[Scummvm-git-logs] scummvm master -> 6aea08860fa09bd8c9972a32bcd4bd9ca1698ce9
aquadran
noreply at scummvm.org
Wed Dec 15 23:09:29 UTC 2021
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:
8094b77d21 ANDROID: Simplify 3D backend
35fff1ab79 ANDROID: Add cursor scaling to 3D backend
24565a5bd8 ANDROID: Rework 3D GLES textures
6aea08860f ANDROID: Chooose the best surface formats offered by the system
Commit: 8094b77d214569076fb76152a48aa96a5c9a59a4
https://github.com/scummvm/scummvm/commit/8094b77d214569076fb76152a48aa96a5c9a59a4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2021-12-16T00:09:25+01:00
Commit Message:
ANDROID: Simplify 3D backend
Changed paths:
backends/graphics3d/android/android-graphics3d.cpp
backends/graphics3d/android/android-graphics3d.h
diff --git a/backends/graphics3d/android/android-graphics3d.cpp b/backends/graphics3d/android/android-graphics3d.cpp
index e6e6025725..2e31f2f58f 100644
--- a/backends/graphics3d/android/android-graphics3d.cpp
+++ b/backends/graphics3d/android/android-graphics3d.cpp
@@ -72,8 +72,7 @@ AndroidGraphics3dManager::AndroidGraphics3dManager() :
_mouse_texture_rgb(0),
_mouse_hotspot(),
_mouse_keycolor(0),
- _show_mouse(false),
- _use_mouse_palette(false) {
+ _show_mouse(false) {
_game_texture = new GLESFakePalette565Texture();
_overlay_texture = new GLES5551Texture();
_overlay_background = new GLES5551Texture();
@@ -388,12 +387,6 @@ bool AndroidGraphics3dManager::hasFeature(OSystem::Feature f) const {
void AndroidGraphics3dManager::setFeatureState(OSystem::Feature f, bool enable) {
switch (f) {
- case OSystem::kFeatureCursorPalette:
- _use_mouse_palette = enable;
- if (!enable) {
- disableCursorPalette();
- }
- break;
case OSystem::kFeatureFullscreenMode:
_fullscreen = enable;
updateScreenRect();
@@ -410,7 +403,7 @@ void AndroidGraphics3dManager::setFeatureState(OSystem::Feature f, bool enable)
bool AndroidGraphics3dManager::getFeatureState(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureCursorPalette:
- return _use_mouse_palette;
+ return true;
case OSystem::kFeatureFullscreenMode:
return _fullscreen;
case OSystem::kFeatureAspectRatioCorrection:
@@ -539,81 +532,36 @@ int16 AndroidGraphics3dManager::getWidth() const {
}
void AndroidGraphics3dManager::setPalette(const byte *colors, uint start, uint num) {
- ENTER("%p, %u, %u", colors, start, num);
-
-#ifdef USE_RGB_COLOR
- assert(_game_texture->hasPalette());
-#endif
-
- GLTHREADCHECK;
-
- if (!_use_mouse_palette) {
- setCursorPaletteInternal(colors, start, num);
- }
-
- const Graphics::PixelFormat &pf = _game_texture->getPalettePixelFormat();
- // _game_texture is a GLESFakePalette565Texture so it's 16bits colors
- assert(pf.bpp() == sizeof(uint16) * 8);
- byte *p = _game_texture->palette() + start * sizeof(uint16);
-
- for (uint i = 0; i < num; ++i, colors += 3, p += sizeof(uint16)) {
- WRITE_UINT16(p, pf.RGBToColor(colors[0], colors[1], colors[2]));
- }
+ // We should never end up here in 3D
+ assert(false);
}
void AndroidGraphics3dManager::grabPalette(byte *colors, uint start, uint num) const {
- ENTER("%p, %u, %u", colors, start, num);
-
-#ifdef USE_RGB_COLOR
- assert(_game_texture->hasPalette());
-#endif
-
- GLTHREADCHECK;
-
- const Graphics::PixelFormat &pf = _game_texture->getPalettePixelFormat();
- // _game_texture is a GLESFakePalette565Texture so it's 16bits colors
- assert(pf.bpp() == sizeof(uint16) * 8);
- const byte *p = _game_texture->palette_const() + start * sizeof(uint16);
-
- for (uint i = 0; i < num; ++i, colors += 3, p += sizeof(uint16)) {
- pf.colorToRGB(READ_UINT16(p), colors[0], colors[1], colors[2]);
- }
+ // We should never end up here in 3D
+ assert(false);
}
Graphics::Surface *AndroidGraphics3dManager::lockScreen() {
- ENTER();
-
- GLTHREADCHECK;
-
- Graphics::Surface *surface = _game_texture->surface();
- assert(surface->getPixels());
+ // We should never end up here in 3D
+ assert(false);
- return surface;
+ return nullptr;
}
void AndroidGraphics3dManager::unlockScreen() {
- ENTER();
-
- GLTHREADCHECK;
-
- assert(_game_texture->dirty());
+ // We should never end up here in 3D
+ assert(false);
}
void AndroidGraphics3dManager::fillScreen(uint32 col) {
- ENTER("%u", col);
-
- GLTHREADCHECK;
-
- _game_texture->fillBuffer(col);
+ // We should never end up here in 3D
+ assert(false);
}
void AndroidGraphics3dManager::copyRectToScreen(const void *buf, int pitch,
int x, int y, int w, int h) {
- ENTER("%p, %d, %d, %d, %d, %d", buf, pitch, x, y, w, h);
-
- GLTHREADCHECK;
-
- _game_texture->updateBuffer(x, y, w, h, buf, pitch);
+ // We should never end up here in 3D
+ assert(false);
}
void AndroidGraphics3dManager::initSize(uint width, uint height,
@@ -817,34 +765,6 @@ void AndroidGraphics3dManager::setCursorPalette(const byte *colors,
}
setCursorPaletteInternal(colors, start, num);
- _use_mouse_palette = true;
-}
-
-void AndroidGraphics3dManager::disableCursorPalette() {
- // when disabling the cursor palette, and we're running a clut8 game,
- // it expects the game palette to be used for the cursor
- if (_game_texture->hasPalette()) {
- // _game_texture and _mouse_texture_palette are GLESFakePalette565Texture so it's 16bits colors
- const Graphics::PixelFormat &pf_src =
- _game_texture->getPalettePixelFormat();
- const Graphics::PixelFormat &pf_dst =
- _mouse_texture_palette->getPalettePixelFormat();
- assert(pf_src.bpp() == sizeof(uint16) * 8);
- assert(pf_dst.bpp() == sizeof(uint16) * 8);
-
- const byte *src = _game_texture->palette_const();
- byte *dst = _mouse_texture_palette->palette();
-
- uint8 r, g, b;
-
- for (uint i = 0; i < 256; ++i, src += sizeof(uint16), dst += sizeof(uint16)) {
- pf_src.colorToRGB(READ_UINT16(src), r, g, b);
- WRITE_UINT16(dst, pf_dst.RGBToColor(r, g, b));
- }
-
- byte *p = _mouse_texture_palette->palette() + _mouse_keycolor * sizeof(uint16);
- WRITE_UINT16(p, READ_UINT16(p) & ~1);
- }
}
bool AndroidGraphics3dManager::lockMouse(bool lock) {
@@ -866,10 +786,8 @@ Graphics::PixelFormat AndroidGraphics3dManager::getScreenFormat() const {
Common::List<Graphics::PixelFormat> AndroidGraphics3dManager::getSupportedFormats() const {
Common::List<Graphics::PixelFormat> res;
- res.push_back(GLES565Texture::pixelFormat());
- res.push_back(GLES5551Texture::pixelFormat());
- res.push_back(GLES4444Texture::pixelFormat());
- res.push_back(Graphics::PixelFormat::createFormatCLUT8());
+
+ // empty list
return res;
}
@@ -990,14 +908,17 @@ AndroidCommonGraphics::State AndroidGraphics3dManager::getState() const {
state.fullscreen = getFeatureState(OSystem::kFeatureFullscreenMode);
state.cursorPalette = getFeatureState(OSystem::kFeatureCursorPalette);
#ifdef USE_RGB_COLOR
- state.pixelFormat = getScreenFormat();
+ state.pixelFormat = _2d_pixel_format;
#endif
return state;
}
bool AndroidGraphics3dManager::setState(const AndroidCommonGraphics::State &state) {
- // In 3d we don't have a pixel format so we ignore it
+ // In 3d we don't have a pixel format so we ignore it but store it for when leaving 3d mode
initSize(state.screenWidth, state.screenHeight, nullptr);
+#ifdef USE_RGB_COLOR
+ _2d_pixel_format = state.pixelFormat;
+#endif
setFeatureState(OSystem::kFeatureAspectRatioCorrection, state.aspectRatio);
setFeatureState(OSystem::kFeatureFullscreenMode, state.fullscreen);
setFeatureState(OSystem::kFeatureCursorPalette, state.cursorPalette);
diff --git a/backends/graphics3d/android/android-graphics3d.h b/backends/graphics3d/android/android-graphics3d.h
index bdd1e0363f..b459f5a85f 100644
--- a/backends/graphics3d/android/android-graphics3d.h
+++ b/backends/graphics3d/android/android-graphics3d.h
@@ -132,7 +132,6 @@ protected:
private:
void setCursorPaletteInternal(const byte *colors, uint start, uint num);
- void disableCursorPalette();
void initOverlay();
enum FixupType {
@@ -154,6 +153,11 @@ private:
GLESBaseTexture *_game_texture;
OpenGL::FrameBuffer *_frame_buffer;
+#ifdef USE_RGB_COLOR
+ // Backup of the previous pixel format to pass it back when we leave 3d
+ Graphics::PixelFormat _2d_pixel_format;
+#endif
+
/**
* The position of the mouse cursor, in window coordinates.
*/
@@ -172,7 +176,6 @@ private:
uint32 _mouse_keycolor;
int _mouse_targetscale;
bool _show_mouse;
- bool _use_mouse_palette;
};
#endif
Commit: 35fff1ab79248a0f88c6b30da65564a76ac16cb4
https://github.com/scummvm/scummvm/commit/35fff1ab79248a0f88c6b30da65564a76ac16cb4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2021-12-16T00:09:25+01:00
Commit Message:
ANDROID: Add cursor scaling to 3D backend
Changed paths:
backends/graphics3d/android/android-graphics3d.cpp
backends/graphics3d/android/android-graphics3d.h
diff --git a/backends/graphics3d/android/android-graphics3d.cpp b/backends/graphics3d/android/android-graphics3d.cpp
index 2e31f2f58f..59eca9f035 100644
--- a/backends/graphics3d/android/android-graphics3d.cpp
+++ b/backends/graphics3d/android/android-graphics3d.cpp
@@ -72,6 +72,7 @@ AndroidGraphics3dManager::AndroidGraphics3dManager() :
_mouse_texture_rgb(0),
_mouse_hotspot(),
_mouse_keycolor(0),
+ _mouse_dont_scale(false),
_show_mouse(false) {
_game_texture = new GLESFakePalette565Texture();
_overlay_texture = new GLES5551Texture();
@@ -281,23 +282,15 @@ void AndroidGraphics3dManager::updateScreen() {
dynamic_cast<OSystem_Android *>(g_system)->getTouchControls().draw();
}
- int cs = _mouse_targetscale;
-
if (_show_overlay) {
- // ugly, but the modern theme sets a wacko factor, only god knows why
- cs = 1;
-
if (_overlay_background && _overlay_background->getTextureName() != 0) {
GLCALL(_overlay_background->drawTextureRect());
}
GLCALL(_overlay_texture->drawTextureRect());
- }
- if (_show_mouse && !_mouse_texture->isEmpty()) {
- const Common::Point &mouse = g_system->getEventManager()->getMousePos();
- if (_show_overlay) {
- _mouse_texture->drawTexture(mouse.x * cs, mouse.y * cs,
- _mouse_texture->width(), _mouse_texture->height());
+ if (_show_mouse && !_mouse_texture->isEmpty()) {
+ _mouse_texture->drawTexture(_cursorX - _mouse_hotspot_scaled.x, _cursorY - _mouse_hotspot_scaled.y,
+ _mouse_width_scaled, _mouse_width_scaled);
}
}
@@ -589,14 +582,14 @@ void AndroidGraphics3dManager::initSize(uint width, uint height,
_game_texture->texWidth(), _game_texture->texHeight());
_frame_buffer->attach();
- updateScreenRect();
-
// Don't know mouse size yet - it gets reallocated in
// setMouseCursor. We need the palette allocated before
// setMouseCursor however, so just take a guess at the desired
// size (it's small).
_mouse_texture_palette->allocBuffer(20, 20);
+ updateScreenRect();
+
clearScreen(kClear);
_game_texture->setGameTexture();
@@ -630,6 +623,30 @@ void AndroidGraphics3dManager::warpMouse(int x, int y) {
dynamic_cast<OSystem_Android *>(g_system)->pushEvent(e);
}
+void AndroidGraphics3dManager::updateCursorScaling() {
+ // By default we use the unscaled versions.
+ _mouse_hotspot_scaled = _mouse_hotspot;
+ _mouse_width_scaled = _mouse_texture->width();
+ _mouse_height_scaled = _mouse_texture->height();
+
+ // In case scaling is actually enabled we will scale the cursor according
+ // to the game screen.
+ uint16 w = _game_texture->width();
+ uint16 h = _game_texture->height();
+
+ if (!_mouse_dont_scale && w && h) {
+ const frac_t screen_scale_factor_x = intToFrac(_game_texture->getDrawRect().width()) / w;
+ const frac_t screen_scale_factor_y = intToFrac(_game_texture->getDrawRect().height()) / h;
+
+ _mouse_hotspot_scaled = Common::Point(
+ fracToInt(_mouse_hotspot_scaled.x * screen_scale_factor_x),
+ fracToInt(_mouse_hotspot_scaled.y * screen_scale_factor_y));
+
+ _mouse_width_scaled = fracToInt(_mouse_width_scaled * screen_scale_factor_x);
+ _mouse_height_scaled = fracToInt(_mouse_height_scaled * screen_scale_factor_y);
+ }
+}
+
void AndroidGraphics3dManager::setMouseCursor(const void *buf, uint w, uint h,
int hotspotX, int hotspotY,
uint32 keycolor, bool dontScale,
@@ -729,8 +746,8 @@ void AndroidGraphics3dManager::setMouseCursor(const void *buf, uint w, uint h,
}
_mouse_hotspot = Common::Point(hotspotX, hotspotY);
- // TODO: Adapt to the new "do not scale" cursor logic.
- _mouse_targetscale = 1;
+ _mouse_dont_scale = dontScale;
+ updateCursorScaling();
}
void AndroidGraphics3dManager::setCursorPaletteInternal(const byte *colors,
@@ -830,6 +847,8 @@ void AndroidGraphics3dManager::updateScreenRect() {
}
_game_texture->setDrawRect(rect);
+
+ updateCursorScaling();
}
const GLESBaseTexture *AndroidGraphics3dManager::getActiveTexture() const {
diff --git a/backends/graphics3d/android/android-graphics3d.h b/backends/graphics3d/android/android-graphics3d.h
index b459f5a85f..8a0e59c658 100644
--- a/backends/graphics3d/android/android-graphics3d.h
+++ b/backends/graphics3d/android/android-graphics3d.h
@@ -119,6 +119,7 @@ public:
protected:
void updateScreenRect();
+ void updateCursorScaling();
const GLESBaseTexture *getActiveTexture() const;
void clipMouse(Common::Point &p) const;
@@ -174,7 +175,9 @@ private:
GLES5551Texture *_mouse_texture_rgb;
Common::Point _mouse_hotspot;
uint32 _mouse_keycolor;
- int _mouse_targetscale;
+ Common::Point _mouse_hotspot_scaled;
+ int _mouse_width_scaled, _mouse_height_scaled;
+ bool _mouse_dont_scale;
bool _show_mouse;
};
Commit: 24565a5bd8cdc9ed1f2b74d2798d8bb89d802fb4
https://github.com/scummvm/scummvm/commit/24565a5bd8cdc9ed1f2b74d2798d8bb89d802fb4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2021-12-16T00:09:25+01:00
Commit Message:
ANDROID: Rework 3D GLES textures
The abstraction added will allow the backend to allow surface
customization
Changed paths:
backends/graphics3d/android/android-graphics3d.cpp
backends/graphics3d/android/android-graphics3d.h
backends/graphics3d/android/texture.cpp
backends/graphics3d/android/texture.h
diff --git a/backends/graphics3d/android/android-graphics3d.cpp b/backends/graphics3d/android/android-graphics3d.cpp
index 59eca9f035..3fc2633b4b 100644
--- a/backends/graphics3d/android/android-graphics3d.cpp
+++ b/backends/graphics3d/android/android-graphics3d.cpp
@@ -71,7 +71,6 @@ AndroidGraphics3dManager::AndroidGraphics3dManager() :
_mouse_texture_palette(0),
_mouse_texture_rgb(0),
_mouse_hotspot(),
- _mouse_keycolor(0),
_mouse_dont_scale(false),
_show_mouse(false) {
_game_texture = new GLESFakePalette565Texture();
@@ -434,9 +433,7 @@ void AndroidGraphics3dManager::showOverlay() {
_overlay_background->allocBuffer(_overlay_texture->width(), _overlay_texture->height());
_overlay_background->setDrawRect(0, 0,
JNI::egl_surface_width, JNI::egl_surface_height);
- Graphics::Surface *background = _overlay_background->surface();
- GLCALL(glReadPixels(0, 0, background->w, background->h, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,
- background->getPixels()));
+ _overlay_background->readPixels();
// Restore game viewport
GLCALL(glViewport(savedViewport[0], savedViewport[1], savedViewport[2], savedViewport[3]));
@@ -683,17 +680,7 @@ void AndroidGraphics3dManager::setMouseCursor(const void *buf, uint w, uint h,
if (_mouse_texture == _mouse_texture_palette) {
assert(keycolor < 256);
-
- const Graphics::PixelFormat &pf = _mouse_texture_palette->getPalettePixelFormat();
- // _mouse_texture_palette is a GLESFakePalette565Texture so it's 16bits colors
- assert(pf.bpp() == sizeof(uint16) * 8);
- byte *p = _mouse_texture_palette->palette() + _mouse_keycolor * sizeof(uint16);
- WRITE_UINT16(p, READ_UINT16(p) | 1);
-
- _mouse_keycolor = keycolor;
-
- p = _mouse_texture_palette->palette() + _mouse_keycolor * sizeof(uint16);
- WRITE_UINT16(p, READ_UINT16(p) & ~1);
+ _mouse_texture->setKeycolor(keycolor);
}
if (w == 0 || h == 0) {
@@ -747,23 +734,8 @@ void AndroidGraphics3dManager::setMouseCursor(const void *buf, uint w, uint h,
_mouse_hotspot = Common::Point(hotspotX, hotspotY);
_mouse_dont_scale = dontScale;
- updateCursorScaling();
-}
-void AndroidGraphics3dManager::setCursorPaletteInternal(const byte *colors,
- uint start, uint num) {
- // _mouse_texture_palette is a GLESFakePalette565Texture so it's 16bits colors
- const Graphics::PixelFormat &pf =
- _mouse_texture_palette->getPalettePixelFormat();
- assert(pf.bpp() == sizeof(uint16) * 8);
- byte *p = _mouse_texture_palette->palette() + start * sizeof(uint16);
-
- for (uint i = 0; i < num; ++i, colors += 3, p += sizeof(uint16)) {
- WRITE_UINT16(p, pf.RGBToColor(colors[0], colors[1], colors[2]));
- }
-
- p = _mouse_texture_palette->palette() + _mouse_keycolor * sizeof(uint16);
- WRITE_UINT16(p, READ_UINT16(p) & ~1);
+ updateCursorScaling();
}
void AndroidGraphics3dManager::setCursorPalette(const byte *colors,
@@ -781,7 +753,7 @@ void AndroidGraphics3dManager::setCursorPalette(const byte *colors,
_mouse_texture_rgb = 0;
}
- setCursorPaletteInternal(colors, start, num);
+ _mouse_texture->setPalette(colors, start, num);
}
bool AndroidGraphics3dManager::lockMouse(bool lock) {
diff --git a/backends/graphics3d/android/android-graphics3d.h b/backends/graphics3d/android/android-graphics3d.h
index 8a0e59c658..759115f6ca 100644
--- a/backends/graphics3d/android/android-graphics3d.h
+++ b/backends/graphics3d/android/android-graphics3d.h
@@ -132,7 +132,6 @@ protected:
void *getProcAddress(const char *name) const;
private:
- void setCursorPaletteInternal(const byte *colors, uint start, uint num);
void initOverlay();
enum FixupType {
@@ -174,7 +173,6 @@ private:
GLESBaseTexture *_mouse_texture_palette;
GLES5551Texture *_mouse_texture_rgb;
Common::Point _mouse_hotspot;
- uint32 _mouse_keycolor;
Common::Point _mouse_hotspot_scaled;
int _mouse_width_scaled, _mouse_height_scaled;
bool _mouse_dont_scale;
diff --git a/backends/graphics3d/android/texture.cpp b/backends/graphics3d/android/texture.cpp
index 1d84a9b1d0..4924e7ebe8 100644
--- a/backends/graphics3d/android/texture.cpp
+++ b/backends/graphics3d/android/texture.cpp
@@ -181,6 +181,28 @@ void GLESBaseTexture::allocBuffer(GLuint w, GLuint h) {
void GLESBaseTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h,
const Common::Rect &clip) {
+ 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()) {
+ void *tex = prepareTextureBuffer(_dirty_rect);
+
+ 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,
+ _dirty_rect.width(), _dirty_rect.height(),
+ _glFormat, _glType, tex));
+ }
+
+
// LOGD("*** Texture %p: Drawing %dx%d rect to (%d,%d)", this, w, h, x, y);
assert(_box_shader);
@@ -277,98 +299,44 @@ void GLESTexture::fillBuffer(uint32 color) {
setDirty();
}
-void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h,
- const Common::Rect &clip) {
- 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;
+void *GLESTexture::prepareTextureBuffer(const Common::Rect &rect) {
+ if (rect.width() == _surface.w) {
+ return _pixels + rect.top * _surface.pitch;
+ } else {
+ byte *tex = _buf;
- byte *src = _pixels + _dirty_rect.top * _surface.pitch +
- _dirty_rect.left * _surface.format.bytesPerPixel;
- byte *dst = _buf;
+ byte *src = _pixels + rect.top * _surface.pitch +
+ rect.left * _surface.format.bytesPerPixel;
+ byte *dst = _buf;
- uint16 l = dwidth * _surface.format.bytesPerPixel;
+ uint16 l = rect.width() * _surface.format.bytesPerPixel;
- for (uint16 i = 0; i < dheight; ++i) {
- memcpy(dst, src, l);
- src += _surface.pitch;
- dst += l;
- }
+ for (uint16 i = rect.height(); i > 0; --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));
+ return tex;
}
-
- GLESBaseTexture::drawTexture(x, y, w, h, clip);
}
-GLES4444Texture::GLES4444Texture() :
- GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixelFormat()) {
-}
-
-GLES4444Texture::~GLES4444Texture() {
-}
-
-GLES8888Texture::GLES8888Texture() :
- GLESTexture(GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat()) {
-}
-
-GLES8888Texture::~GLES8888Texture() {
-}
-
-GLES5551Texture::GLES5551Texture() :
- GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixelFormat()) {
-}
-
-GLES5551Texture::~GLES5551Texture() {
-}
-
-GLES565Texture::GLES565Texture() :
- GLESTexture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixelFormat()) {
-}
-
-GLES565Texture::~GLES565Texture() {
+void GLESTexture::readPixels() {
+ GLCALL(glReadPixels(0, 0, _surface.w, _surface.h, _glFormat, _glType,
+ _pixels));
+ setDirty();
}
GLESFakePaletteTexture::GLESFakePaletteTexture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat pixelFormat) :
GLESBaseTexture(glFormat, glType, pixelFormat),
- _palette(nullptr),
- _pixels(nullptr),
- _buf(nullptr) {
+ _pixels(nullptr) {
_palettePixelFormat = pixelFormat;
_fake_format = Graphics::PixelFormat::createFormatCLUT8();
-
- _palette = new uint16[256];
-
- memset(_palette, 0, 256 * 2);
}
GLESFakePaletteTexture::~GLESFakePaletteTexture() {
- delete[] _buf;
delete[] _pixels;
- delete[] _palette;
}
void GLESFakePaletteTexture::allocBuffer(GLuint w, GLuint h) {
@@ -385,8 +353,8 @@ void GLESFakePaletteTexture::allocBuffer(GLuint w, GLuint h) {
return;
}
- delete[] _buf;
delete[] _pixels;
+ _pixels = nullptr;
_pixels = new byte[w * h];
@@ -394,8 +362,6 @@ void GLESFakePaletteTexture::allocBuffer(GLuint w, GLuint h) {
_surface.setPixels(_pixels);
fillBuffer(0);
-
- _buf = new uint16[w * h];
}
void GLESFakePaletteTexture::fillBuffer(uint32 color) {
@@ -418,59 +384,209 @@ void GLESFakePaletteTexture::updateBuffer(GLuint x, GLuint y,
} while (--h);
}
-void GLESFakePaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h,
- const Common::Rect &clip) {
- if (_all_dirty) {
- _dirty_rect.top = 0;
- _dirty_rect.left = 0;
- _dirty_rect.bottom = _surface.h;
- _dirty_rect.right = _surface.w;
+GLESFakePalette16Texture::GLESFakePalette16Texture(GLenum glFormat, GLenum glType,
+ Graphics::PixelFormat pixelFormat) :
+ GLESFakePaletteTexture(glFormat, glType, pixelFormat),
+ _palette(nullptr),
+ _buf(nullptr) {
+ _palette = new uint16[256];
+ memset(_palette, 0, sizeof(*_palette) * 256);
+}
- _all_dirty = false;
- }
+GLESFakePalette16Texture::~GLESFakePalette16Texture() {
+ delete[] _buf;
+ delete[] _palette;
+}
- 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;
- }
+void GLESFakePalette16Texture::allocBuffer(GLuint w, GLuint h) {
+ delete[] _buf;
+ _buf = nullptr;
- GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name));
+ GLESFakePaletteTexture::allocBuffer(w, h);
- GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0,
- _dirty_rect.left, _dirty_rect.top,
- dwidth, dheight, _glFormat, _glType, _buf));
+ _buf = new uint16[w * h];
+}
+
+void *GLESFakePalette16Texture::prepareTextureBuffer(const Common::Rect &rect) {
+ int16 w = rect.width();
+
+ byte *src = _pixels + rect.top * _surface.pitch +
+ rect.left;
+ uint16 *dst = _buf;
+ uint pitch_delta = _surface.pitch - w;
+
+ for (uint16 j = rect.height(); j > 0; --j) {
+ for (uint16 i = 0; i < w; ++i) {
+ *dst++ = _palette[*src++];
+ }
+ src += pitch_delta;
}
- GLESBaseTexture::drawTexture(x, y, w, h, clip);
+ return _buf;
}
-const Graphics::PixelFormat &GLESFakePaletteTexture::getPixelFormat() const {
- return _fake_format;
+void GLESFakePalette16Texture::setPalette(const byte *colors, uint start, uint num) {
+ uint16 *p = _palette + start;
+
+ for (uint i = 0; i < num; ++i, colors += 3, ++p) {
+ *p = _palettePixelFormat.RGBToColor(colors[0], colors[1], colors[2]);
+ }
}
-GLESFakePalette565Texture::GLESFakePalette565Texture() :
- GLESFakePaletteTexture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
- GLES565Texture::pixelFormat()) {
+void GLESFakePalette16Texture::grabPalette(byte *colors, uint start, uint num) const {
+ const uint16 *p = _palette + start;
+
+ for (uint i = 0; i < num; ++i, colors += 3, ++p) {
+ _palettePixelFormat.colorToRGB(*p, colors[0], colors[1], colors[2]);
+ }
}
-GLESFakePalette565Texture::~GLESFakePalette565Texture() {
+GLESFakePalette565Texture::GLESFakePalette565Texture() :
+ GLESFakePalette16Texture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+ GLES565Texture::pixelFormat()) {
}
GLESFakePalette5551Texture::GLESFakePalette5551Texture() :
- GLESFakePaletteTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,
- GLES5551Texture::pixelFormat()) {
+ GLESFakePalette16Texture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,
+ GLES5551Texture::pixelFormat()),
+ _keycolor(0) {
+}
+
+void GLESFakePalette5551Texture::setKeycolor(byte color) {
+ uint16 *p = _palette + _keycolor;
+ *p |= 1;
+
+ _keycolor = color;
+
+ p = _palette + _keycolor;
+ *p &= ~1;
+}
+
+GLESFakePalette888Texture::GLESFakePalette888Texture() :
+ GLESFakePaletteTexture(GL_RGB, GL_UNSIGNED_BYTE,
+ GLES888Texture::pixelFormat()),
+ _palette(nullptr),
+ _buf(nullptr) {
+ _palette = new byte[256 * 3];
+ memset(_palette, 0, 256 * 3);
+}
+
+GLESFakePalette888Texture::~GLESFakePalette888Texture() {
+ delete[] _buf;
+ delete[] _palette;
+}
+
+void GLESFakePalette888Texture::allocBuffer(GLuint w, GLuint h) {
+ delete[] _buf;
+ _buf = nullptr;
+
+ GLESFakePaletteTexture::allocBuffer(w, h);
+
+ _buf = new byte[w * h * 3];
+}
+
+void *GLESFakePalette888Texture::prepareTextureBuffer(const Common::Rect &rect) {
+ int16 w = rect.width();
+
+ byte *src = _pixels + rect.top * _surface.pitch +
+ rect.left;
+ byte *dst = _buf;
+ uint pitch_delta = _surface.pitch - w;
+
+ for (uint16 j = rect.height(); j > 0; --j) {
+ for (uint16 i = 0; i < w; ++i) {
+ byte c = *src++;
+ byte *p = _palette + c * 3;
+ *dst++ = *p++;
+ *dst++ = *p++;
+ *dst++ = *p++;
+ }
+ src += pitch_delta;
+ }
+
+ return _buf;
+}
+
+void GLESFakePalette888Texture::setPalette(const byte *colors, uint start, uint num) {
+ memcpy(_palette + start * 3, colors, num * 3);
+}
+
+void GLESFakePalette888Texture::grabPalette(byte *colors, uint start, uint num) const {
+ memcpy(colors, _palette + start * 3, num * 3);
+}
+
+GLESFakePalette8888Texture::GLESFakePalette8888Texture() :
+ GLESFakePaletteTexture(GL_RGBA, GL_UNSIGNED_BYTE,
+ GLES8888Texture::pixelFormat()),
+ _palette(nullptr),
+ _buf(nullptr),
+ _keycolor(0) {
+ _palette = new uint32[256];
+ memset(_palette, 0, sizeof(*_palette) * 256);
+}
+
+GLESFakePalette8888Texture::~GLESFakePalette8888Texture() {
+ delete[] _buf;
+ delete[] _palette;
+}
+
+void GLESFakePalette8888Texture::allocBuffer(GLuint w, GLuint h) {
+ delete[] _buf;
+ _buf = nullptr;
+
+ GLESFakePaletteTexture::allocBuffer(w, h);
+
+ _buf = new uint32[w * h];
+}
+
+void *GLESFakePalette8888Texture::prepareTextureBuffer(const Common::Rect &rect) {
+ int16 w = rect.width();
+
+ byte *src = _pixels + rect.top * _surface.pitch +
+ rect.left;
+ uint32 *dst = _buf;
+ uint pitch_delta = _surface.pitch - w;
+
+ for (uint16 j = rect.height(); j > 0; --j) {
+ for (uint16 i = 0; i < w; ++i) {
+ *dst++ = _palette[*src++];
+ }
+ src += pitch_delta;
+ }
+
+ return _buf;
}
-GLESFakePalette5551Texture::~GLESFakePalette5551Texture() {
+void GLESFakePalette8888Texture::setPalette(const byte *colors, uint start, uint num) {
+ // We use _palette as a uint32 to ensure proper alignment but we store bytes in a endian independent fashion
+ // because GL_UNSIGNED_BYTE is endian neutral
+ byte *p = (byte *)(_palette + start);
+
+ for (uint i = 0; i < num; ++i, colors += 3, p += 4) {
+ p[0] = colors[0];
+ p[1] = colors[1];
+ p[2] = colors[2];
+ p[3] = 255;
+ }
+}
+
+void GLESFakePalette8888Texture::setKeycolor(byte color) {
+ // _palette is endian neutral even though it's an uint32
+ byte *p = (byte *)(_palette + _keycolor);
+ p[3] = 255;
+
+ _keycolor = color;
+
+ p = (byte *)(_palette + _keycolor);
+ p[3] = 0;
+}
+
+void GLESFakePalette8888Texture::grabPalette(byte *colors, uint start, uint num) const {
+ const byte *p = (byte *)(_palette + start);
+
+ for (uint i = 0; i < num; ++i, colors += 3, p += 4) {
+ colors[0] = p[0];
+ colors[1] = p[1];
+ colors[2] = p[2];
+ }
}
diff --git a/backends/graphics3d/android/texture.h b/backends/graphics3d/android/texture.h
index 468a891579..c416f0d279 100644
--- a/backends/graphics3d/android/texture.h
+++ b/backends/graphics3d/android/texture.h
@@ -60,11 +60,12 @@ public:
const void *buf, int pitch_buf) = 0;
virtual void fillBuffer(uint32 color) = 0;
- virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
+ void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
}
- virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
+ void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
+ virtual void *prepareTextureBuffer(const Common::Rect &rect) = 0;
inline void setDrawRect(const Common::Rect &rect) {
_draw_rect = rect;
@@ -124,13 +125,9 @@ public:
return &_surface;
}
- virtual const byte *palette_const() const {
- return 0;
- };
-
- virtual byte *palette() {
- return 0;
- };
+ virtual void setPalette(const byte *colors, uint start, uint num) = 0;
+ virtual void setKeycolor(byte color) = 0;
+ virtual void grabPalette(byte *colors, uint start, uint num) const = 0;
inline bool hasPalette() const {
return _palettePixelFormat.bytesPerPixel > 0;
@@ -216,31 +213,24 @@ public:
const void *buf, int pitch_buf);
virtual void fillBuffer(uint32 color);
- virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
- drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
- }
- virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
+ virtual void *prepareTextureBuffer(const Common::Rect &rect) override;
+
+ virtual void setPalette(const byte *colors, uint start, uint num) override {}
+ virtual void setKeycolor(byte color) override {};
+ virtual void grabPalette(byte *colors, uint start, uint num) const override {}
+
+ void readPixels();
protected:
byte *_pixels;
byte *_buf;
};
-class GLES8888Texture : public GLESTexture {
-public:
- GLES8888Texture();
- virtual ~GLES8888Texture();
-
- static Graphics::PixelFormat pixelFormat() {
- return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
- }
-};
-
// RGBA4444 texture
class GLES4444Texture : public GLESTexture {
public:
- GLES4444Texture();
- virtual ~GLES4444Texture();
+ GLES4444Texture() : GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixelFormat()) {}
+ virtual ~GLES4444Texture() {}
static Graphics::PixelFormat pixelFormat() {
return Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0);
@@ -250,8 +240,8 @@ public:
// RGBA5551 texture
class GLES5551Texture : public GLESTexture {
public:
- GLES5551Texture();
- virtual ~GLES5551Texture();
+ GLES5551Texture() : GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixelFormat()) {}
+ virtual ~GLES5551Texture() {}
static inline Graphics::PixelFormat pixelFormat() {
return Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0);
@@ -261,14 +251,42 @@ public:
// RGB565 texture
class GLES565Texture : public GLESTexture {
public:
- GLES565Texture();
- virtual ~GLES565Texture();
+ GLES565Texture() : GLESTexture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixelFormat()) {}
+ virtual ~GLES565Texture() {}
static inline Graphics::PixelFormat pixelFormat() {
return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
}
};
+class GLES888Texture : public GLESTexture {
+public:
+ GLES888Texture() : GLESTexture(GL_RGB, GL_UNSIGNED_BYTE, pixelFormat()) {}
+ virtual ~GLES888Texture() {}
+
+ static Graphics::PixelFormat pixelFormat() {
+#ifdef SCUMM_BIG_ENDIAN
+ return Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0);
+#else
+ return Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
+#endif
+ }
+};
+
+class GLES8888Texture : public GLESTexture {
+public:
+ GLES8888Texture() : GLESTexture(GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat()) {}
+ virtual ~GLES8888Texture() {}
+
+ static Graphics::PixelFormat pixelFormat() {
+#ifdef SCUMM_BIG_ENDIAN
+ return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+ return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+ }
+};
+
class GLESFakePaletteTexture : public GLESBaseTexture {
protected:
GLESFakePaletteTexture(GLenum glFormat, GLenum glType,
@@ -277,44 +295,90 @@ protected:
public:
virtual ~GLESFakePaletteTexture();
- virtual void allocBuffer(GLuint w, GLuint h);
+ virtual void allocBuffer(GLuint w, GLuint h) override;
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) override;
+ virtual void fillBuffer(uint32 color) override;
- virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
- drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
+ virtual const Graphics::PixelFormat &getPixelFormat() const override {
+ return _fake_format;
}
- virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
- virtual const byte *palette_const() const {
- return (byte *)_palette;
- };
+protected:
+ Graphics::PixelFormat _fake_format;
+ byte *_pixels;
+};
- virtual byte *palette() {
- setDirty();
- return (byte *)_palette;
- };
+class GLESFakePalette16Texture : public GLESFakePaletteTexture {
+protected:
+ GLESFakePalette16Texture(GLenum glFormat, GLenum glType,
+ Graphics::PixelFormat pixelFormat);
+public:
+ virtual ~GLESFakePalette16Texture();
- virtual const Graphics::PixelFormat &getPixelFormat() const;
+ virtual void allocBuffer(GLuint w, GLuint h) override;
+ virtual void *prepareTextureBuffer(const Common::Rect &rect) override;
+
+ virtual void setPalette(const byte *colors, uint start, uint num) override;
+ virtual void grabPalette(byte *colors, uint start, uint num) const override;
protected:
- Graphics::PixelFormat _fake_format;
uint16 *_palette;
- byte *_pixels;
uint16 *_buf;
};
-class GLESFakePalette565Texture : public GLESFakePaletteTexture {
+class GLESFakePalette565Texture : public GLESFakePalette16Texture {
public:
GLESFakePalette565Texture();
- virtual ~GLESFakePalette565Texture();
+ virtual ~GLESFakePalette565Texture() {}
+
+ virtual void setKeycolor(byte color) override {};
};
-class GLESFakePalette5551Texture : public GLESFakePaletteTexture {
+class GLESFakePalette5551Texture : public GLESFakePalette16Texture {
public:
GLESFakePalette5551Texture();
- virtual ~GLESFakePalette5551Texture();
+ virtual ~GLESFakePalette5551Texture() {}
+
+ virtual void setKeycolor(byte color) override;
+
+protected:
+ byte _keycolor;
+};
+
+class GLESFakePalette888Texture : public GLESFakePaletteTexture {
+public:
+ GLESFakePalette888Texture();
+ virtual ~GLESFakePalette888Texture();
+
+ virtual void allocBuffer(GLuint w, GLuint h) override;
+ virtual void *prepareTextureBuffer(const Common::Rect &rect) override;
+
+ virtual void setPalette(const byte *colors, uint start, uint num) override;
+ virtual void setKeycolor(byte color) override {};
+ virtual void grabPalette(byte *colors, uint start, uint num) const override;
+
+protected:
+ byte *_palette;
+ byte *_buf;
+};
+
+class GLESFakePalette8888Texture : public GLESFakePaletteTexture {
+public:
+ GLESFakePalette8888Texture();
+ virtual ~GLESFakePalette8888Texture();
+
+ virtual void allocBuffer(GLuint w, GLuint h) override;
+ virtual void *prepareTextureBuffer(const Common::Rect &rect) override;
+
+ virtual void setPalette(const byte *colors, uint start, uint num) override;
+ virtual void setKeycolor(byte color) override;
+ virtual void grabPalette(byte *colors, uint start, uint num) const override;
+
+protected:
+ uint32 *_palette;
+ uint32 *_buf;
+ byte _keycolor;
};
#endif
Commit: 6aea08860fa09bd8c9972a32bcd4bd9ca1698ce9
https://github.com/scummvm/scummvm/commit/6aea08860fa09bd8c9972a32bcd4bd9ca1698ce9
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2021-12-16T00:09:25+01:00
Commit Message:
ANDROID: Chooose the best surface formats offered by the system
Changed paths:
backends/graphics/android/android-graphics.cpp
backends/graphics3d/android/android-graphics3d.cpp
backends/graphics3d/android/android-graphics3d.h
backends/platform/android/jni-android.cpp
backends/platform/android/jni-android.h
backends/platform/android/org/scummvm/scummvm/ScummVM.java
backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
diff --git a/backends/graphics/android/android-graphics.cpp b/backends/graphics/android/android-graphics.cpp
index 4ca106c084..6cf4f1b783 100644
--- a/backends/graphics/android/android-graphics.cpp
+++ b/backends/graphics/android/android-graphics.cpp
@@ -67,9 +67,17 @@ void AndroidGraphicsManager::initSurface() {
// Notify the OpenGL code about our context.
setContextType(OpenGL::kContextGLES2);
- // We default to RGB565 and RGBA5551 which is closest to the actual output
- // mode we setup.
- notifyContextCreate(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
+ if (JNI::egl_bits_per_pixel == 16) {
+ // We default to RGB565 and RGBA5551 which is closest to what we setup in Java side
+ notifyContextCreate(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
+ } else {
+ // If not 16, this must be 24 or 32 bpp so make use of them
+#ifdef SCUMM_BIG_ENDIAN
+ notifyContextCreate(Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0), Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+#else
+ notifyContextCreate(Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0), Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+#endif
+ }
handleResize(JNI::egl_surface_width, JNI::egl_surface_height);
}
diff --git a/backends/graphics3d/android/android-graphics3d.cpp b/backends/graphics3d/android/android-graphics3d.cpp
index 3fc2633b4b..4798503c10 100644
--- a/backends/graphics3d/android/android-graphics3d.cpp
+++ b/backends/graphics3d/android/android-graphics3d.cpp
@@ -73,10 +73,20 @@ AndroidGraphics3dManager::AndroidGraphics3dManager() :
_mouse_hotspot(),
_mouse_dont_scale(false),
_show_mouse(false) {
- _game_texture = new GLESFakePalette565Texture();
- _overlay_texture = new GLES5551Texture();
- _overlay_background = new GLES5551Texture();
- _mouse_texture_palette = new GLESFakePalette5551Texture();
+
+ if (JNI::egl_bits_per_pixel == 16) {
+ // We default to RGB565 and RGBA5551 which is closest to what we setup in Java side
+ _game_texture = new GLES565Texture();
+ _overlay_texture = new GLES5551Texture();
+ _overlay_background = new GLES565Texture();
+ _mouse_texture_palette = new GLESFakePalette5551Texture();
+ } else {
+ // If not 16, this must be 24 or 32 bpp so make use of them
+ _game_texture = new GLES888Texture();
+ _overlay_texture = new GLES8888Texture();
+ _overlay_background = new GLES888Texture();
+ _mouse_texture_palette = new GLESFakePalette8888Texture();
+ }
_mouse_texture = _mouse_texture_palette;
initSurface();
@@ -374,6 +384,9 @@ bool AndroidGraphics3dManager::hasFeature(OSystem::Feature f) const {
f == OSystem::kFeatureAspectRatioCorrection) {
return true;
}
+ if (f == OSystem::kFeatureOverlaySupportsAlpha) {
+ return _overlay_texture->getPixelFormat().aBits() > 3;
+ }
return false;
}
@@ -483,13 +496,12 @@ void AndroidGraphics3dManager::grabOverlay(Graphics::Surface &surface) const {
assert(surface.w >= overlaySurface->w);
assert(surface.h >= overlaySurface->h);
- assert(surface.format.bytesPerPixel == sizeof(uint16));
- assert(overlaySurface->format.bytesPerPixel == sizeof(uint16));
+ assert(surface.format.bytesPerPixel == overlaySurface->format.bytesPerPixel);
const byte *src = (const byte *)overlaySurface->getPixels();
byte *dst = (byte *)surface.getPixels();
Graphics::copyBlit(dst, src, surface.pitch, overlaySurface->pitch,
- overlaySurface->w, overlaySurface->h, sizeof(uint16));
+ overlaySurface->w, overlaySurface->h, overlaySurface->format.bytesPerPixel);
}
void AndroidGraphics3dManager::copyRectToOverlay(const void *buf, int pitch,
@@ -659,7 +671,11 @@ void AndroidGraphics3dManager::setMouseCursor(const void *buf, uint w, uint h,
LOGD("switching to rgb mouse cursor");
assert(!_mouse_texture_rgb);
- _mouse_texture_rgb = new GLES5551Texture();
+ if (JNI::egl_bits_per_pixel == 16) {
+ _mouse_texture_rgb = new GLES5551Texture();
+ } else {
+ _mouse_texture_rgb = new GLES8888Texture();
+ }
_mouse_texture_rgb->setLinearFilter(_graphicsMode == 1);
}
@@ -691,6 +707,7 @@ void AndroidGraphics3dManager::setMouseCursor(const void *buf, uint w, uint h,
_mouse_texture->updateBuffer(0, 0, w, h, buf, w);
} else {
uint16 pitch = _mouse_texture->pitch();
+ uint16 bpp = _mouse_texture->getPixelFormat().bytesPerPixel;
byte *tmp = new byte[pitch * h];
@@ -709,19 +726,19 @@ void AndroidGraphics3dManager::setMouseCursor(const void *buf, uint w, uint h,
if (format->bytesPerPixel == 2) {
const uint16 *s = (const uint16 *)buf;
- uint16 *d = (uint16 *)tmp;
+ byte *d = tmp;
for (uint16 y = 0; y < h; ++y, d += pitch / 2 - w)
for (uint16 x = 0; x < w; ++x, d++)
if (*s++ == (keycolor & 0xffff)) {
- *d = 0;
+ memset(d, 0, bpp);
}
} else if (format->bytesPerPixel == 4) {
const uint32 *s = (const uint32 *)buf;
- uint16 *d = (uint16 *)tmp;
+ byte *d = tmp;
for (uint16 y = 0; y < h; ++y, d += pitch / 2 - w)
for (uint16 x = 0; x < w; ++x, d++)
- if (*s++ == (keycolor & 0xffff)) {
- *d = 0;
+ if (*s++ == (keycolor & 0xffffffff)) {
+ memset(d, 0, bpp);
}
} else {
error("AndroidGraphics3dManager::setMouseCursor: invalid bytesPerPixel %d", format->bytesPerPixel);
diff --git a/backends/graphics3d/android/android-graphics3d.h b/backends/graphics3d/android/android-graphics3d.h
index 759115f6ca..99aea2e2f2 100644
--- a/backends/graphics3d/android/android-graphics3d.h
+++ b/backends/graphics3d/android/android-graphics3d.h
@@ -150,7 +150,7 @@ private:
bool _force_redraw;
// Game layer
- GLESBaseTexture *_game_texture;
+ GLESTexture *_game_texture;
OpenGL::FrameBuffer *_frame_buffer;
#ifdef USE_RGB_COLOR
@@ -164,14 +164,14 @@ private:
int _cursorX, _cursorY;
// Overlay layer
- GLES5551Texture *_overlay_background;
- GLES5551Texture *_overlay_texture;
+ GLESTexture *_overlay_background;
+ GLESTexture *_overlay_texture;
bool _show_overlay;
// Mouse layer
GLESBaseTexture *_mouse_texture;
- GLESBaseTexture *_mouse_texture_palette;
- GLES5551Texture *_mouse_texture_rgb;
+ GLESFakePaletteTexture *_mouse_texture_palette;
+ GLESTexture *_mouse_texture_rgb;
Common::Point _mouse_hotspot;
Common::Point _mouse_hotspot_scaled;
int _mouse_width_scaled, _mouse_height_scaled;
diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp
index fa846cc0d2..fd19aef238 100644
--- a/backends/platform/android/jni-android.cpp
+++ b/backends/platform/android/jni-android.cpp
@@ -72,6 +72,7 @@ sem_t JNI::pause_sem = { 0 };
int JNI::surface_changeid = 0;
int JNI::egl_surface_width = 0;
int JNI::egl_surface_height = 0;
+int JNI::egl_bits_per_pixel = 0;
bool JNI::_ready_for_events = 0;
jmethodID JNI::_MID_getDPI = 0;
@@ -113,7 +114,7 @@ const JNINativeMethod JNI::_natives[] = {
(void *)JNI::create },
{ "destroy", "()V",
(void *)JNI::destroy },
- { "setSurface", "(II)V",
+ { "setSurface", "(III)V",
(void *)JNI::setSurface },
{ "main", "([Ljava/lang/String;)I",
(void *)JNI::main },
@@ -647,9 +648,10 @@ void JNI::destroy(JNIEnv *env, jobject self) {
JNI::getEnv()->DeleteGlobalRef(_jobj);
}
-void JNI::setSurface(JNIEnv *env, jobject self, jint width, jint height) {
+void JNI::setSurface(JNIEnv *env, jobject self, jint width, jint height, jint bpp) {
egl_surface_width = width;
egl_surface_height = height;
+ egl_bits_per_pixel = bpp;
surface_changeid++;
}
diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h
index 547af26cdc..b118ab7f03 100644
--- a/backends/platform/android/jni-android.h
+++ b/backends/platform/android/jni-android.h
@@ -48,6 +48,7 @@ public:
static int surface_changeid;
static int egl_surface_width;
static int egl_surface_height;
+ static int egl_bits_per_pixel;
static jint onLoad(JavaVM *vm);
@@ -146,7 +147,7 @@ private:
jint audio_buffer_size);
static void destroy(JNIEnv *env, jobject self);
- static void setSurface(JNIEnv *env, jobject self, jint width, jint height);
+ static void setSurface(JNIEnv *env, jobject self, jint width, jint height, jint bpp);
static jint main(JNIEnv *env, jobject self, jobjectArray args);
static void pushEvent(JNIEnv *env, jobject self, int type, int arg1,
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index 5d6d0a5a35..d3d04fdced 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -2,6 +2,7 @@ package org.scummvm.scummvm;
import androidx.annotation.NonNull;
import android.content.res.AssetManager;
+import android.graphics.PixelFormat;
import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
@@ -33,6 +34,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
private EGLSurface _egl_surface = EGL10.EGL_NO_SURFACE;
private SurfaceHolder _surface_holder;
+ private int bitsPerPixel;
private AudioTrack _audio_track;
private int _sample_rate = 0;
private int _buffer_size = 0;
@@ -46,7 +48,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
int sample_rate,
int buffer_size);
private native void destroy();
- private native void setSurface(int width, int height);
+ private native void setSurface(int width, int height, int bpp);
private native int main(String[] args);
// pause the engine and all native threads
@@ -109,13 +111,17 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
return;
}
- Log.d(LOG_TAG, String.format(Locale.ROOT, "surfaceChanged: %dx%d (%d)",
- width, height, format));
+ PixelFormat pixelFormat = new PixelFormat();
+ PixelFormat.getPixelFormatInfo(format, pixelFormat);
+ bitsPerPixel = pixelFormat.bitsPerPixel;
+
+ Log.d(LOG_TAG, String.format(Locale.ROOT, "surfaceChanged: %dx%d (%d: %dbpp)",
+ width, height, format, bitsPerPixel));
// store values for the native code
// make sure to do it before notifying the lock
// as it leads to a race condition otherwise
- setSurface(width, height);
+ setSurface(width, height, bitsPerPixel);
synchronized(_sem_surface) {
_surface_holder = holder;
@@ -133,7 +139,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
}
// clear values for the native code
- setSurface(0, 0);
+ setSurface(0, 0, 0);
}
final public void setArgs(String[] args) {
@@ -142,14 +148,14 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
final public void run() {
try {
- initAudio();
- initEGL();
-
// wait for the surfaceChanged callback
synchronized(_sem_surface) {
while (_surface_holder == null)
_sem_surface.wait();
}
+
+ initAudio();
+ initEGL();
} catch (Exception e) {
deinitEGL();
deinitAudio();
@@ -477,15 +483,24 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
for (EGLConfig config : configs) {
if (config != null) {
+ boolean good = true;
+
EglAttribs attr = new EglAttribs(config);
// must have
if ((attr.get(EGL10.EGL_SURFACE_TYPE) & EGL10.EGL_WINDOW_BIT) == 0)
- continue;
+ good = false;
+
+ if (attr.get(EGL10.EGL_BUFFER_SIZE) < bitsPerPixel)
+ good = false;
int score = attr.weight();
- Log.d(LOG_TAG, String.format(Locale.ROOT, "%s (%d)", attr.toString(), score));
+ Log.d(LOG_TAG, String.format(Locale.ROOT, "%s (%d, %s)", attr.toString(), score, good ? "OK" : "NOK"));
+
+ if (!good) {
+ continue;
+ }
if (score > bestScore) {
res = config;
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 9902dd5059..9b2ad2711d 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -1007,7 +1007,14 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
// so app's internal space (which would be deleted on uninstall) was set as WORLD_READABLE which is no longer supported in newer versions of Android API
// In newer APIs we can set that path as Context.MODE_PRIVATE which is the default - but this makes the files inaccessible to other apps
- _scummvm = new MyScummVM(_main_surface.getHolder(), new MyScummVMDestroyedCallback() {
+ SurfaceHolder main_surface_holder = _main_surface.getHolder();
+
+ // By default Android selects RGB_565 for backward compatibility, use the best one by querying the display
+ // It's deprecated on API level >= 17 and will always return RGBA_8888
+ // but on older versions it could return RGB_565 which could be more efficient for the GPU
+ main_surface_holder.setFormat(getDisplayPixelFormat());
+
+ _scummvm = new MyScummVM(main_surface_holder, new MyScummVMDestroyedCallback() {
@Override
public void handle(int exitResult) {
Log.d(ScummVM.LOG_TAG, "Via callback: ScummVM native terminated with code: " + exitResult);
@@ -1385,6 +1392,13 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
hideSystemUI();
}
+ @SuppressWarnings("deprecation")
+ private int getDisplayPixelFormat() {
+ // Since API level 17 this always returns PixelFormat.RGBA_8888
+ // so if we target more recent API levels, we could remove this function
+ return getWindowManager().getDefaultDisplay().getPixelFormat();
+ }
+
// Auxiliary function to overwrite a file (used for overwriting the scummvm.ini file with an existing other one)
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private static void copyFileUsingStream(File source, File dest) throws IOException {
More information about the Scummvm-git-logs
mailing list