aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/platform/android/android.cpp2
-rw-r--r--backends/platform/android/android.h6
-rw-r--r--backends/platform/android/gfx.cpp3
-rw-r--r--backends/platform/android/texture.cpp213
-rw-r--r--backends/platform/android/texture.h47
5 files changed, 159 insertions, 112 deletions
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 56e56fb3dd..e2e3174877 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -488,7 +488,7 @@ bool OSystem_Android::pollEvent(Common::Event &event) {
} else {
// Touchscreen events need to be converted
// from device to game coords first.
- const GLESTexture *tex;
+ const GLESBaseTexture *tex;
if (_show_overlay)
tex = _overlay_texture;
else
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index f73131b317..11a24a5f57 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -103,7 +103,7 @@ private:
bool _force_redraw;
// Game layer
- GLESTexture *_game_texture;
+ GLESBaseTexture *_game_texture;
int _shake_offset;
Common::Rect _focus_rect;
@@ -112,7 +112,7 @@ private:
bool _show_overlay;
// Mouse layer
- GLESTexture *_mouse_texture;
+ GLESBaseTexture *_mouse_texture;
GLESPaletteTexture *_mouse_texture_palette;
GLES5551Texture *_mouse_texture_rgb;
Common::Point _mouse_hotspot;
@@ -151,7 +151,7 @@ private:
#ifdef USE_RGB_COLOR
Common::String getPixelFormatName(const Graphics::PixelFormat &format) const;
- void initTexture(GLESTexture **texture, uint width, uint height,
+ void initTexture(GLESBaseTexture **texture, uint width, uint height,
const Graphics::PixelFormat *format);
#endif
diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp
index 62dbe644bf..34981dddb8 100644
--- a/backends/platform/android/gfx.cpp
+++ b/backends/platform/android/gfx.cpp
@@ -97,7 +97,7 @@ Common::String OSystem_Android::getPixelFormatName(const Graphics::PixelFormat &
8 - format.aLoss);
}
-void OSystem_Android::initTexture(GLESTexture **texture,
+void OSystem_Android::initTexture(GLESBaseTexture **texture,
uint width, uint height,
const Graphics::PixelFormat *format) {
assert(texture);
@@ -438,7 +438,6 @@ Graphics::Surface *OSystem_Android::lockScreen() {
GLTHREADCHECK;
- // TODO this doesn't return any pixel data for non CLUT8
Graphics::Surface *surface = _game_texture->surface();
assert(surface->pixels);
diff --git a/backends/platform/android/texture.cpp b/backends/platform/android/texture.cpp
index 54479a6ab4..a20222ec64 100644
--- a/backends/platform/android/texture.cpp
+++ b/backends/platform/android/texture.cpp
@@ -36,9 +36,6 @@
#include "backends/platform/android/texture.h"
#include "backends/platform/android/android.h"
-// Unfortunately, Android devices are too varied to make broad assumptions :/
-#define TEXSUBIMAGE_IS_EXPENSIVE 0
-
// Supported GL extensions
static bool npot_supported = false;
#ifdef GL_OES_draw_texture
@@ -62,7 +59,7 @@ static T nextHigher2(T k) {
return k + 1;
}
-void GLESTexture::initGLExtensions() {
+void GLESBaseTexture::initGLExtensions() {
const char *ext_string =
reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
@@ -82,8 +79,8 @@ void GLESTexture::initGLExtensions() {
}
}
-GLESTexture::GLESTexture(GLenum glFormat, GLenum glType,
- Graphics::PixelFormat pixelFormat) :
+GLESBaseTexture::GLESBaseTexture(GLenum glFormat, GLenum glType,
+ Graphics::PixelFormat pixelFormat) :
_glFormat(glFormat),
_glType(glType),
_texture_name(0),
@@ -98,16 +95,16 @@ GLESTexture::GLESTexture(GLenum glFormat, GLenum glType,
GLCALL(glGenTextures(1, &_texture_name));
}
-GLESTexture::~GLESTexture() {
+GLESBaseTexture::~GLESBaseTexture() {
release();
}
-void GLESTexture::release() {
- debug("Destroying texture %u", _texture_name);
+void GLESBaseTexture::release() {
+ LOGD("Destroying texture %u", _texture_name);
GLCALL(glDeleteTextures(1, &_texture_name));
}
-void GLESTexture::reinit() {
+void GLESBaseTexture::reinit() {
GLCALL(glGenTextures(1, &_texture_name));
if (hasPalette()) {
@@ -124,7 +121,7 @@ void GLESTexture::reinit() {
setDirty();
}
-void GLESTexture::initSize() {
+void GLESBaseTexture::initSize() {
// Allocate room for the texture now, but pixel data gets uploaded
// later (perhaps with multiple TexSubImage2D operations).
GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name));
@@ -138,7 +135,7 @@ void GLESTexture::initSize() {
0, _glFormat, _glType, 0));
}
-void GLESTexture::allocBuffer(GLuint w, GLuint h) {
+void GLESBaseTexture::allocBuffer(GLuint w, GLuint h) {
_surface.w = w;
_surface.h = h;
_surface.bytesPerPixel = _pixelFormat.bytesPerPixel;
@@ -155,85 +152,10 @@ void GLESTexture::allocBuffer(GLuint w, GLuint h) {
_texture_height = nextHigher2(_surface.h);
}
- _surface.pitch = _texture_width * _pixelFormat.bytesPerPixel;
-
initSize();
}
-void GLESTexture::updateBuffer(GLuint x, GLuint y, GLuint w, GLuint h,
- const void *buf, int pitch_buf) {
- ENTER("%u, %u, %u, %u, %p, %d", x, y, w, h, buf, pitch_buf);
-
- GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name));
- GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
-
- setDirtyRect(Common::Rect(x, y, x + w, y + h));
-
- if (static_cast<int>(w) * _pixelFormat.bytesPerPixel == pitch_buf) {
- GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h,
- _glFormat, _glType, buf));
- } else {
- // GLES removed the ability to specify pitch, so we
- // have to do this ourselves.
-#if TEXSUBIMAGE_IS_EXPENSIVE
- byte *tmp = new byte[w * h * _pixelFormat.bytesPerPixel];
- assert(tmp);
-
- const byte *src = static_cast<const byte *>(buf);
- byte *dst = tmp;
- GLuint count = h;
-
- do {
- memcpy(dst, src, w * _pixelFormat.bytesPerPixel);
- dst += w * _pixelFormat.bytesPerPixel;
- src += pitch_buf;
- } while (--count);
-
- GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h,
- _glFormat, _glType, tmp));
-
- delete[] tmp;
-#else
- // This version avoids the intermediate copy at the expense of
- // repeat glTexSubImage2D calls. On some devices this is worse.
- const byte *src = static_cast<const byte *>(buf);
- do {
- GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,
- w, 1, _glFormat, _glType, src));
- ++y;
- src += pitch_buf;
- } while (--h);
-#endif
- }
-}
-
-void GLESTexture::fillBuffer(uint32 color) {
- uint rowbytes = _surface.w * _pixelFormat.bytesPerPixel;
-
- byte *tmp = new byte[rowbytes];
- assert(tmp);
-
- if (_pixelFormat.bytesPerPixel == 1 ||
- ((color & 0xff) == ((color >> 8) & 0xff))) {
- memset(tmp, color & 0xff, rowbytes);
- } else {
- uint16 *p = (uint16 *)tmp;
- Common::set_to(p, p + _surface.w, (uint16)color);
- }
-
- GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name));
- GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
-
- for (GLuint y = 0; y < _surface.h; ++y)
- GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, _surface.w, 1,
- _glFormat, _glType, tmp));
-
- delete[] tmp;
-
- setDirty();
-}
-
-void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
+void GLESBaseTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name));
#ifdef GL_OES_draw_texture
@@ -279,10 +201,110 @@ void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
clearDirty();
}
-const Graphics::PixelFormat &GLESTexture::getPixelFormat() const {
+const Graphics::PixelFormat &GLESBaseTexture::getPixelFormat() const {
return _pixelFormat;
}
+GLESTexture::GLESTexture(GLenum glFormat, GLenum glType,
+ Graphics::PixelFormat pixelFormat) :
+ GLESBaseTexture(glFormat, glType, pixelFormat),
+ _pixels(0),
+ _buf(0) {
+}
+
+GLESTexture::~GLESTexture() {
+ delete[] _buf;
+ delete[] _pixels;
+}
+
+void GLESTexture::allocBuffer(GLuint w, GLuint h) {
+ GLESBaseTexture::allocBuffer(w, h);
+
+ delete[] _buf;
+ delete[] _pixels;
+
+ _pixels = new byte[w * h * _surface.bytesPerPixel];
+ assert(_pixels);
+
+ _surface.pixels = _pixels;
+ _surface.pitch = w * _pixelFormat.bytesPerPixel;
+
+ _buf = new byte[w * h * _surface.bytesPerPixel];
+ assert(_buf);
+}
+
+void GLESTexture::updateBuffer(GLuint x, GLuint y, GLuint w, GLuint h,
+ const void *buf, int pitch_buf) {
+ setDirtyRect(Common::Rect(x, y, x + w, y + h));
+
+ const byte *src = (const byte *)buf;
+ byte *dst = _pixels + y * _surface.pitch + x * _surface.bytesPerPixel;
+
+ do {
+ memcpy(dst, src, w * _surface.bytesPerPixel);
+ dst += _surface.pitch;
+ src += pitch_buf;
+ } while (--h);
+}
+
+void GLESTexture::fillBuffer(uint32 color) {
+ assert(_surface.pixels);
+
+ if (_pixelFormat.bytesPerPixel == 1 ||
+ ((color & 0xff) == ((color >> 8) & 0xff)))
+ memset(_pixels, color & 0xff, _surface.pitch * _surface.h);
+ else
+ Common::set_to(_pixels, _pixels + _surface.pitch * _surface.h,
+ (uint16)color);
+
+ setDirty();
+}
+
+void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
+ if (_all_dirty) {
+ _dirty_rect.top = 0;
+ _dirty_rect.left = 0;
+ _dirty_rect.bottom = _surface.h;
+ _dirty_rect.right = _surface.w;
+
+ _all_dirty = false;
+ }
+
+ if (!_dirty_rect.isEmpty()) {
+ byte *_tex;
+
+ int16 dwidth = _dirty_rect.width();
+ int16 dheight = _dirty_rect.height();
+
+ if (dwidth == _surface.w) {
+ _tex = _pixels + _dirty_rect.top * _surface.pitch;
+ } else {
+ _tex = _buf;
+
+ byte *src = _pixels + _dirty_rect.top * _surface.pitch +
+ _dirty_rect.left * _surface.bytesPerPixel;
+ byte *dst = _buf;
+
+ uint16 l = dwidth * _surface.bytesPerPixel;
+
+ for (uint16 i = 0; i < dheight; ++i) {
+ memcpy(dst, src, l);
+ src += _surface.pitch;
+ dst += l;
+ }
+ }
+
+ GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name));
+ GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
+
+ GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0,
+ _dirty_rect.left, _dirty_rect.top,
+ dwidth, dheight, _glFormat, _glType, _tex));
+ }
+
+ GLESBaseTexture::drawTexture(x, y, w, h);
+}
+
GLES4444Texture::GLES4444Texture() :
GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixelFormat()) {
}
@@ -306,7 +328,7 @@ GLES565Texture::~GLES565Texture() {
GLESPaletteTexture::GLESPaletteTexture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat palettePixelFormat) :
- GLESTexture(glFormat, glType,
+ GLESBaseTexture(glFormat, glType,
Graphics::PixelFormat::createFormatCLUT8()),
_texture(0)
{
@@ -319,7 +341,7 @@ GLESPaletteTexture::~GLESPaletteTexture() {
}
void GLESPaletteTexture::allocBuffer(GLuint w, GLuint h) {
- GLESTexture::allocBuffer(w, h);
+ GLESBaseTexture::allocBuffer(w, h);
// Texture gets uploaded later (from drawTexture())
@@ -335,6 +357,7 @@ void GLESPaletteTexture::allocBuffer(GLuint w, GLuint h) {
_texture = new_buffer;
_surface.pixels = _texture + _paletteSize;
+ _surface.pitch = _texture_width;
}
void GLESPaletteTexture::fillBuffer(uint32 color) {
@@ -370,7 +393,7 @@ void GLESPaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w,
0, texture_size, _texture));
}
- GLESTexture::drawTexture(x, y, w, h);
+ GLESBaseTexture::drawTexture(x, y, w, h);
}
GLESPalette888Texture::GLESPalette888Texture() :
@@ -415,7 +438,7 @@ GLESPalette5551Texture::~GLESPalette5551Texture() {
GLESFakePaletteTexture::GLESFakePaletteTexture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat pixelFormat) :
- GLESTexture(glFormat, glType, pixelFormat),
+ GLESBaseTexture(glFormat, glType, pixelFormat),
_palette(0),
_pixels(0),
_buf(0)
@@ -434,7 +457,7 @@ GLESFakePaletteTexture::~GLESFakePaletteTexture() {
}
void GLESFakePaletteTexture::allocBuffer(GLuint w, GLuint h) {
- GLESTexture::allocBuffer(w, h);
+ GLESBaseTexture::allocBuffer(w, h);
delete[] _buf;
delete[] _pixels;
@@ -505,7 +528,7 @@ void GLESFakePaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w,
dwidth, dheight, _glFormat, _glType, _buf));
}
- GLESTexture::drawTexture(x, y, w, h);
+ GLESBaseTexture::drawTexture(x, y, w, h);
}
const Graphics::PixelFormat &GLESFakePaletteTexture::getPixelFormat() const {
diff --git a/backends/platform/android/texture.h b/backends/platform/android/texture.h
index 15ad2e78b6..e8f20132f8 100644
--- a/backends/platform/android/texture.h
+++ b/backends/platform/android/texture.h
@@ -36,26 +36,26 @@
#include "common/rect.h"
#include "common/array.h"
-class GLESTexture {
+class GLESBaseTexture {
public:
static void initGLExtensions();
protected:
- GLESTexture(GLenum glFormat, GLenum glType,
- Graphics::PixelFormat pixelFormat);
+ GLESBaseTexture(GLenum glFormat, GLenum glType,
+ Graphics::PixelFormat pixelFormat);
public:
- virtual ~GLESTexture();
+ virtual ~GLESBaseTexture();
void release();
void reinit();
void initSize();
- virtual void allocBuffer(GLuint width, GLuint height);
+ virtual void allocBuffer(GLuint w, GLuint h);
virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
- const void *buf, int pitch_buf);
- virtual void fillBuffer(uint32 color);
+ const void *buf, int pitch_buf) = 0;
+ virtual void fillBuffer(uint32 color) = 0;
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
@@ -144,6 +144,31 @@ protected:
Graphics::PixelFormat _palettePixelFormat;
};
+class GLESTexture : public GLESBaseTexture {
+protected:
+ GLESTexture(GLenum glFormat, GLenum glType,
+ Graphics::PixelFormat pixelFormat);
+
+public:
+ virtual ~GLESTexture();
+
+ virtual void allocBuffer(GLuint w, GLuint h);
+
+ virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
+ const void *buf, int pitch_buf);
+ virtual void fillBuffer(uint32 color);
+
+ virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
+
+ inline void drawTexture() {
+ drawTexture(0, 0, _surface.w, _surface.h);
+ }
+
+protected:
+ byte *_pixels;
+ byte *_buf;
+};
+
// RGBA4444 texture
class GLES4444Texture : public GLESTexture {
public:
@@ -177,7 +202,7 @@ public:
}
};
-class GLESPaletteTexture : public GLESTexture {
+class GLESPaletteTexture : public GLESBaseTexture {
protected:
GLESPaletteTexture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat palettePixelFormat);
@@ -185,7 +210,7 @@ protected:
public:
virtual ~GLESPaletteTexture();
- virtual void allocBuffer(GLuint width, GLuint height);
+ virtual void allocBuffer(GLuint w, GLuint h);
virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
const void *buf, int pitch_buf);
virtual void fillBuffer(uint32 color);
@@ -245,7 +270,7 @@ public:
virtual ~GLESPalette5551Texture();
};
-class GLESFakePaletteTexture : public GLESTexture {
+class GLESFakePaletteTexture : public GLESBaseTexture {
protected:
GLESFakePaletteTexture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat pixelFormat);
@@ -253,7 +278,7 @@ protected:
public:
virtual ~GLESFakePaletteTexture();
- virtual void allocBuffer(GLuint width, GLuint height);
+ virtual void allocBuffer(GLuint w, GLuint h);
virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
const void *buf, int pitch_buf);
virtual void fillBuffer(uint32 color);