diff --git a/es-core/src/components/ImageComponent.cpp b/es-core/src/components/ImageComponent.cpp index 1f80e2f25..1b34f37c7 100644 --- a/es-core/src/components/ImageComponent.cpp +++ b/es-core/src/components/ImageComponent.cpp @@ -462,6 +462,15 @@ void ImageComponent::render(const glm::mat4& parentTrans) } mVertices->shaderFlags = mVertices->shaderFlags | Renderer::ShaderFlags::PREMULTIPLIED; + +#if defined(USE_OPENGLES) + // This is required as not all mobile GPUs support mipmapping when using the BGRA + // pixel format. + if (mMipmapping) + mVertices->shaderFlags = + mVertices->shaderFlags | Renderer::ShaderFlags::CONVERT_PIXEL_FORMAT; +#endif + mRenderer->drawTriangleStrips(&mVertices[0], 4); } else { diff --git a/es-core/src/renderers/Renderer.h b/es-core/src/renderers/Renderer.h index feb958962..173aa73e6 100644 --- a/es-core/src/renderers/Renderer.h +++ b/es-core/src/renderers/Renderer.h @@ -55,7 +55,8 @@ public: CLIPPING = 0x00000008, ROTATED = 0x00000010, // Screen rotated 90 or 270 degrees. ROUNDED_CORNERS = 0x00000020, - ROUNDED_CORNERS_NO_AA = 0x00000040 + ROUNDED_CORNERS_NO_AA = 0x00000040, + CONVERT_PIXEL_FORMAT = 0x00000080 }; // clang-format on diff --git a/es-core/src/renderers/RendererOpenGL.cpp b/es-core/src/renderers/RendererOpenGL.cpp index 8f62b705b..222343102 100644 --- a/es-core/src/renderers/RendererOpenGL.cpp +++ b/es-core/src/renderers/RendererOpenGL.cpp @@ -439,8 +439,16 @@ unsigned int RendererOpenGL::createTexture(const unsigned int texUnit, static_cast(GL_NEAREST))); #if defined(USE_OPENGLES) - GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType, - GL_UNSIGNED_BYTE, data)); + if (mipmapping) { + // This is required as not all mobile GPUs support mipmapping when using the BGRA + // pixel format. + GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, data)); + } + else { + GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType, + GL_UNSIGNED_BYTE, data)); + } #else GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, textureType, GL_UNSIGNED_BYTE, data)); @@ -644,6 +652,13 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders, vertices->blurStrength = parameters.blurStrength; vertices->shaderFlags = ShaderFlags::POST_PROCESSING | ShaderFlags::PREMULTIPLIED; +#if defined(USE_OPENGLES) + // This is required as not all mobile GPUs support the glReadPixels() function when using + // the BGRA pixel format. + if (textureRGBA) + vertices->shaderFlags |= ShaderFlags::CONVERT_PIXEL_FORMAT; +#endif + if (screenRotation == 90 || screenRotation == 270) vertices->shaderFlags |= ShaderFlags::ROTATED; @@ -774,10 +789,10 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders, #if defined(USE_OPENGLES) if (screenRotation == 0 || screenRotation == 180) GL_CHECK_ERROR( - glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, textureRGBA)); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, textureRGBA)); else GL_CHECK_ERROR( - glReadPixels(0, 0, height, width, GL_BGRA_EXT, GL_UNSIGNED_BYTE, textureRGBA)); + glReadPixels(0, 0, height, width, GL_RGBA, GL_UNSIGNED_BYTE, textureRGBA)); #else if (screenRotation == 0 || screenRotation == 180) GL_CHECK_ERROR( diff --git a/resources/shaders/glsl/blur_horizontal.glsl b/resources/shaders/glsl/blur_horizontal.glsl index e35b8cb04..75b208ff2 100644 --- a/resources/shaders/glsl/blur_horizontal.glsl +++ b/resources/shaders/glsl/blur_horizontal.glsl @@ -41,6 +41,7 @@ out vec4 FragColor; // 0x00000010 - Screen rotated 90 or 270 degrees // 0x00000020 - Rounded corners // 0x00000040 - Rounded corners with no anti-aliasing +// 0x00000080 - Convert pixel format void main() { diff --git a/resources/shaders/glsl/blur_vertical.glsl b/resources/shaders/glsl/blur_vertical.glsl index e23d5e8e1..2f4d00825 100644 --- a/resources/shaders/glsl/blur_vertical.glsl +++ b/resources/shaders/glsl/blur_vertical.glsl @@ -41,6 +41,7 @@ out vec4 FragColor; // 0x00000010 - Screen rotated 90 or 270 degrees // 0x00000020 - Rounded corners // 0x00000040 - Rounded corners with no anti-aliasing +// 0x00000080 - Convert pixel format void main() { diff --git a/resources/shaders/glsl/core.glsl b/resources/shaders/glsl/core.glsl index 12587cfcf..0c56f2991 100644 --- a/resources/shaders/glsl/core.glsl +++ b/resources/shaders/glsl/core.glsl @@ -59,6 +59,7 @@ out vec4 FragColor; // 0x00000010 - Screen rotated 90 or 270 degrees // 0x00000020 - Rounded corners // 0x00000040 - Rounded corners with no anti-aliasing +// 0x00000080 - Convert pixel format void main() { @@ -74,7 +75,14 @@ void main() discard; } - vec4 sampledColor = texture(textureSampler0, texCoord); + vec4 sampledColor; + + // Pixel format conversion is sometimes required as not all mobile GPUs support all + // OpenGL operations in BGRA format. + if (0x0u != (shaderFlags & 0x80u)) + sampledColor.bgra = texture(textureSampler0, texCoord); + else + sampledColor = texture(textureSampler0, texCoord); // Rounded corners. if (0x0u != (shaderFlags & 0x20u) || 0x0u != (shaderFlags & 0x40u)) { diff --git a/resources/shaders/glsl/scanlines.glsl b/resources/shaders/glsl/scanlines.glsl index a69725e75..ae5cef003 100644 --- a/resources/shaders/glsl/scanlines.glsl +++ b/resources/shaders/glsl/scanlines.glsl @@ -102,6 +102,7 @@ uniform float OutputGamma; // 0x00000010 - Screen rotated 90 or 270 degrees // 0x00000020 - Rounded corners // 0x00000040 - Rounded corners with no anti-aliasing +// 0x00000080 - Convert pixel format void main() {