[Scummvm-cvs-logs] scummvm master -> 787b27a4b1cde2bd8e750b4eb477189565588e28

dhewg dhewg at wiibrew.org
Sun Mar 13 17:16:12 CET 2011


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
a93229cae5 ANDROID: Don't use compressed textures for the game screen
2721e287e5 ANDROID: Buffer 16bit texture contents
fa51d82639 ANDROID: Prevent unnecessary reallocs
787b27a4b1 ANDROID: Add missing updateScreen() calls


Commit: a93229cae53bd35b320e72bd5fe794e8dd79c318
    https://github.com/scummvm/scummvm/commit/a93229cae53bd35b320e72bd5fe794e8dd79c318
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-03-13T08:50:43-07:00

Commit Message:
ANDROID: Don't use compressed textures for the game screen

Some GLES drivers suck so much that uploading data to the GPU takes
ages. CLUT8 games now use a faked paletted texture, which internally
uses a RGB565 hardware texture (Android's native pixel format).
This seems to be the only way to efficiently implement constant
changing textures with GLES1 - at the cost of extra buffers.
Then again, we can now use glTexSubImage2D to only update the dirty
rects, which wasn't possible before because glCompressedTexSubImage2D
is only usable on GLES2. This commit does exactly that.
Overall, the CPU usage is massively reduced for CLUT8 games.

Changed paths:
    backends/platform/android/android.cpp
    backends/platform/android/gfx.cpp
    backends/platform/android/texture.cpp
    backends/platform/android/texture.h



diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index ca65863..56e56fb 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -330,7 +330,7 @@ void OSystem_Android::initBackend() {
 	initSurface();
 	initViewport();
 
-	_game_texture = new GLESPalette565Texture();
+	_game_texture = new GLESFakePalette565Texture();
 	_overlay_texture = new GLES4444Texture();
 	_mouse_texture_palette = new GLESPalette5551Texture();
 	_mouse_texture = _mouse_texture_palette;
diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp
index 6be7a03..62dbe64 100644
--- a/backends/platform/android/gfx.cpp
+++ b/backends/platform/android/gfx.cpp
@@ -72,9 +72,9 @@ Graphics::PixelFormat OSystem_Android::getScreenFormat() const {
 
 Common::List<Graphics::PixelFormat> OSystem_Android::getSupportedFormats() const {
 	Common::List<Graphics::PixelFormat> res;
-	res.push_back(GLES565Texture::getPixelFormat());
-	res.push_back(GLES5551Texture::getPixelFormat());
-	res.push_back(GLES4444Texture::getPixelFormat());
+	res.push_back(GLES565Texture::pixelFormat());
+	res.push_back(GLES5551Texture::pixelFormat());
+	res.push_back(GLES4444Texture::pixelFormat());
 	res.push_back(Graphics::PixelFormat::createFormatCLUT8());
 
 	return res;
@@ -123,11 +123,11 @@ void OSystem_Android::initTexture(GLESTexture **texture,
 
 		delete *texture;
 
-		if (format_new == GLES565Texture::getPixelFormat())
+		if (format_new == GLES565Texture::pixelFormat())
 			*texture = new GLES565Texture();
-		else if (format_new == GLES5551Texture::getPixelFormat())
+		else if (format_new == GLES5551Texture::pixelFormat())
 			*texture = new GLES5551Texture();
-		else if (format_new == GLES4444Texture::getPixelFormat())
+		else if (format_new == GLES4444Texture::pixelFormat())
 			*texture = new GLES4444Texture();
 		else {
 			// TODO what now?
@@ -135,7 +135,7 @@ void OSystem_Android::initTexture(GLESTexture **texture,
 				LOGE("unsupported pixel format: %s",
 					getPixelFormatName(format_new).c_str());
 
-			*texture = new GLESPalette565Texture;
+			*texture = new GLESFakePalette565Texture;
 		}
 
 		LOGD("new pixel format: %s",
diff --git a/backends/platform/android/texture.cpp b/backends/platform/android/texture.cpp
index dbba275..54479a6 100644
--- a/backends/platform/android/texture.cpp
+++ b/backends/platform/android/texture.cpp
@@ -279,22 +279,26 @@ void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
 	clearDirty();
 }
 
+const Graphics::PixelFormat &GLESTexture::getPixelFormat() const {
+	return _pixelFormat;
+}
+
 GLES4444Texture::GLES4444Texture() :
-	GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, getPixelFormat()) {
+	GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixelFormat()) {
 }
 
 GLES4444Texture::~GLES4444Texture() {
 }
 
 GLES5551Texture::GLES5551Texture() :
-	GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, getPixelFormat()) {
+	GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixelFormat()) {
 }
 
 GLES5551Texture::~GLES5551Texture() {
 }
 
 GLES565Texture::GLES565Texture() :
-	GLESTexture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, getPixelFormat()) {
+	GLESTexture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixelFormat()) {
 }
 
 GLES565Texture::~GLES565Texture() {
@@ -409,5 +413,112 @@ GLESPalette5551Texture::GLESPalette5551Texture() :
 GLESPalette5551Texture::~GLESPalette5551Texture() {
 }
 
+GLESFakePaletteTexture::GLESFakePaletteTexture(GLenum glFormat, GLenum glType,
+									Graphics::PixelFormat pixelFormat) :
+	GLESTexture(glFormat, glType, pixelFormat),
+	_palette(0),
+	_pixels(0),
+	_buf(0)
+{
+	_palettePixelFormat = pixelFormat;
+	_fake_format = Graphics::PixelFormat::createFormatCLUT8();
+
+	_palette = new uint16[256];
+	assert(_palette);
+}
+
+GLESFakePaletteTexture::~GLESFakePaletteTexture() {
+	delete[] _buf;
+	delete[] _pixels;
+	delete[] _palette;
+}
+
+void GLESFakePaletteTexture::allocBuffer(GLuint w, GLuint h) {
+	GLESTexture::allocBuffer(w, h);
+
+	delete[] _buf;
+	delete[] _pixels;
+
+	_pixels = new byte[w * h];
+	assert(_pixels);
+
+	// fixup surface, for the outside this is a CLUT8 surface
+	_surface.pixels = _pixels;
+	_surface.bytesPerPixel = 1;
+	_surface.pitch = w;
+
+	_buf = new uint16[w * h];
+	assert(_buf);
+}
+
+void GLESFakePaletteTexture::fillBuffer(uint32 color) {
+	assert(_surface.pixels);
+	memset(_surface.pixels, color & 0xff, _surface.pitch * _surface.h);
+	setDirty();
+}
+
+void GLESFakePaletteTexture::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;
+
+	do {
+		memcpy(dst, src, w);
+		dst += _surface.pitch;
+		src += pitch_buf;
+	} while (--h);
+}
+
+void GLESFakePaletteTexture::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()) {
+		int16 dwidth = _dirty_rect.width();
+		int16 dheight = _dirty_rect.height();
+
+		byte *src = _pixels + _dirty_rect.top * _surface.pitch +
+					_dirty_rect.left;
+		uint16 *dst = _buf;
+		uint pitch_delta = _surface.pitch - dwidth;
+
+		for (uint16 j = 0; j < dheight; ++j) {
+			for (uint16 i = 0; i < dwidth; ++i)
+				*dst++ = _palette[*src++];
+			src += pitch_delta;
+		}
+
+		GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name));
+
+		GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0,
+								_dirty_rect.left, _dirty_rect.top,
+								dwidth, dheight, _glFormat, _glType, _buf));
+	}
+
+	GLESTexture::drawTexture(x, y, w, h);
+}
+
+const Graphics::PixelFormat &GLESFakePaletteTexture::getPixelFormat() const {
+	return _fake_format;
+}
+
+GLESFakePalette565Texture::GLESFakePalette565Texture() :
+	GLESFakePaletteTexture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+							GLES565Texture::pixelFormat()) {
+}
+
+GLESFakePalette565Texture::~GLESFakePalette565Texture() {
+}
+
 #endif
 
diff --git a/backends/platform/android/texture.h b/backends/platform/android/texture.h
index 02cb0c7..15ad2e7 100644
--- a/backends/platform/android/texture.h
+++ b/backends/platform/android/texture.h
@@ -100,9 +100,7 @@ public:
 		return _all_dirty || !_dirty_rect.isEmpty();
 	}
 
-	inline const Graphics::PixelFormat &getPixelFormat() const {
-		return _pixelFormat;
-	}
+	virtual const Graphics::PixelFormat &getPixelFormat() const;
 
 	inline const Graphics::PixelFormat &getPalettePixelFormat() const {
 		return _palettePixelFormat;
@@ -152,7 +150,7 @@ public:
 	GLES4444Texture();
 	virtual ~GLES4444Texture();
 
-	static inline Graphics::PixelFormat getPixelFormat() {
+	static Graphics::PixelFormat pixelFormat() {
 		return Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0);
 	}
 };
@@ -163,7 +161,7 @@ public:
 	GLES5551Texture();
 	virtual ~GLES5551Texture();
 
-	static inline Graphics::PixelFormat getPixelFormat() {
+	static inline Graphics::PixelFormat pixelFormat() {
 		return Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0);
 	}
 };
@@ -174,7 +172,7 @@ public:
 	GLES565Texture();
 	virtual ~GLES565Texture();
 
-	static inline Graphics::PixelFormat getPixelFormat() {
+	static inline Graphics::PixelFormat pixelFormat() {
 		return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
 	}
 };
@@ -247,6 +245,49 @@ public:
 	virtual ~GLESPalette5551Texture();
 };
 
+class GLESFakePaletteTexture : public GLESTexture {
+protected:
+	GLESFakePaletteTexture(GLenum glFormat, GLenum glType,
+							Graphics::PixelFormat pixelFormat);
+
+public:
+	virtual ~GLESFakePaletteTexture();
+
+	virtual void allocBuffer(GLuint width, GLuint height);
+	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);
+	}
+
+	virtual const byte *palette_const() const {
+		return (byte *)_palette;
+	};
+
+	virtual byte *palette() {
+		setDirty();
+		return (byte *)_palette;
+	};
+
+	virtual const Graphics::PixelFormat &getPixelFormat() const;
+
+protected:
+	Graphics::PixelFormat _fake_format;
+	uint16 *_palette;
+	byte *_pixels;
+	uint16 *_buf;
+};
+
+class GLESFakePalette565Texture : public GLESFakePaletteTexture {
+public:
+	GLESFakePalette565Texture();
+	virtual ~GLESFakePalette565Texture();
+};
+
 #endif
 #endif
 


Commit: 2721e287e5bcd1f4d524f869c26156e27f5ba187
    https://github.com/scummvm/scummvm/commit/2721e287e5bcd1f4d524f869c26156e27f5ba187
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-03-13T08:50:47-07:00

Commit Message:
ANDROID: Buffer 16bit texture contents

Same issue as in the last commit: glTexSubImage2D is slow, so cache
all copyRect*() calls in a buffer, and update the dirty rect once
when drawing. Reduces CPU usage on 16bit games significantly.
Also, lockScreen() returns now pixel data for non-CLUT8 games instead
of asserting.

Changed paths:
    backends/platform/android/android.cpp
    backends/platform/android/android.h
    backends/platform/android/gfx.cpp
    backends/platform/android/texture.cpp
    backends/platform/android/texture.h



diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 56e56fb..e2e3174 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 f73131b..11a24a5 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 62dbe64..34981dd 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 54479a6..a20222e 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 15ad2e7..e8f2013 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);


Commit: fa51d82639a500939907fdc9d18497914c60fe2c
    https://github.com/scummvm/scummvm/commit/fa51d82639a500939907fdc9d18497914c60fe2c
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-03-13T08:50:48-07:00

Commit Message:
ANDROID: Prevent unnecessary reallocs

Changed paths:
    backends/platform/android/texture.cpp



diff --git a/backends/platform/android/texture.cpp b/backends/platform/android/texture.cpp
index a20222e..c309bd5 100644
--- a/backends/platform/android/texture.cpp
+++ b/backends/platform/android/texture.cpp
@@ -218,8 +218,14 @@ GLESTexture::~GLESTexture() {
 }
 
 void GLESTexture::allocBuffer(GLuint w, GLuint h) {
+	GLuint oldw = _surface.w;
+	GLuint oldh = _surface.h;
+
 	GLESBaseTexture::allocBuffer(w, h);
 
+	if (_surface.w == oldw && _surface.h == oldh)
+		return;
+
 	delete[] _buf;
 	delete[] _pixels;
 
@@ -341,9 +347,13 @@ GLESPaletteTexture::~GLESPaletteTexture() {
 }
 
 void GLESPaletteTexture::allocBuffer(GLuint w, GLuint h) {
+	GLuint oldw = _surface.w;
+	GLuint oldh = _surface.h;
+
 	GLESBaseTexture::allocBuffer(w, h);
 
-	// Texture gets uploaded later (from drawTexture())
+	if (_surface.w == oldw && _surface.h == oldh)
+		return;
 
 	byte *new_buffer = new byte[_paletteSize +
 						_texture_width * _texture_height];
@@ -457,8 +467,14 @@ GLESFakePaletteTexture::~GLESFakePaletteTexture() {
 }
 
 void GLESFakePaletteTexture::allocBuffer(GLuint w, GLuint h) {
+	GLuint oldw = _surface.w;
+	GLuint oldh = _surface.h;
+
 	GLESBaseTexture::allocBuffer(w, h);
 
+	if (_surface.w == oldw && _surface.h == oldh)
+		return;
+
 	delete[] _buf;
 	delete[] _pixels;
 


Commit: 787b27a4b1cde2bd8e750b4eb477189565588e28
    https://github.com/scummvm/scummvm/commit/787b27a4b1cde2bd8e750b4eb477189565588e28
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-03-13T08:50:48-07:00

Commit Message:
ANDROID: Add missing updateScreen() calls

Changed paths:
    backends/platform/android/android.cpp



diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index e2e3174..4391cf5 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -423,6 +423,7 @@ bool OSystem_Android::pollEvent(Common::Event &event) {
 					_force_redraw = true;
 					updateScreen();
 					_force_redraw = true;
+					updateScreen();
 
 					event.type = Common::EVENT_SCREEN_CHANGED;
 
@@ -431,6 +432,7 @@ bool OSystem_Android::pollEvent(Common::Event &event) {
 					// new surface
 					initSurface();
 					_force_redraw = true;
+					updateScreen();
 
 					event.type = Common::EVENT_SCREEN_CHANGED;
 






More information about the Scummvm-git-logs mailing list