From fd2a1d21aef4ff5a1fa9402e374c7a973a6150af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 30 Sep 2024 18:57:46 +0200 Subject: [PATCH] Text: make DistanceFieldGlyphCache processed image upload work on ES2 again. This was apparently also broken since the refactor in 6707534ce65375a3b79598f6d08f125071ee02c9. --- src/Magnum/Text/DistanceFieldGlyphCache.cpp | 17 +++++++++- .../Test/DistanceFieldGlyphCacheGLTest.cpp | 34 ++++++++++++++++--- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/Magnum/Text/DistanceFieldGlyphCache.cpp b/src/Magnum/Text/DistanceFieldGlyphCache.cpp index 845ede34c..2f56f2fc4 100644 --- a/src/Magnum/Text/DistanceFieldGlyphCache.cpp +++ b/src/Magnum/Text/DistanceFieldGlyphCache.cpp @@ -168,7 +168,22 @@ void DistanceFieldGlyphCache::setDistanceFieldImage(const Vector2i& offset, cons #endif void DistanceFieldGlyphCache::doSetProcessedImage(const Vector2i& offset, const ImageView2D& image) { - texture().setSubImage(0, offset, image); + ImageView2D imageToUse = image; + + /* On ES2, R8Unorm maps to Luminance, but here it's actually Red if + EXT_texture_rg is supported. Reinterpret the image format in that + case. If the format is something else (such as RGBA8Unorm), no + reinterpret is done. WebGL doesn't have the EXT_texture_rg extension so + there it isn't done either. */ + #if defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + if(processedFormat() == PixelFormat::R8Unorm) { + /* This is checked inside setProcessedImage() already */ + CORRADE_INTERNAL_ASSERT(image.format() == PixelFormat::R8Unorm); + imageToUse = ImageView2D{image.storage(), GL::PixelFormat::Red, GL::PixelType::UnsignedByte, image.size(), image.data()}; + } + #endif + + texture().setSubImage(0, offset, imageToUse); } #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/Text/Test/DistanceFieldGlyphCacheGLTest.cpp b/src/Magnum/Text/Test/DistanceFieldGlyphCacheGLTest.cpp index 31528c68b..cb4799838 100644 --- a/src/Magnum/Text/Test/DistanceFieldGlyphCacheGLTest.cpp +++ b/src/Magnum/Text/Test/DistanceFieldGlyphCacheGLTest.cpp @@ -30,6 +30,7 @@ #include #include #include /**< @todo remove once Debug is stream-free */ +#include /**< @todo remove once Debug is stream-free */ #include #include "Magnum/Image.h" @@ -231,8 +232,18 @@ void DistanceFieldGlyphCacheGLTest::setImage() { Image3D actual3 = cache.processedImage(); /** @todo ugh have slicing on images directly already */ MutableImageView2D actual{actual3.format(), actual3.size().xy(), actual3.data()}; - #else + #elif !defined(MAGNUM_TARGET_GLES2) Image2D actual = DebugTools::textureSubImage(cache.texture(), 0, {{}, data.size}, cache.processedFormat()); + #else + /* On ES2, R8Unorm maps to Luminance, but here it's actually Red if + EXT_texture_rg is supported */ + Image2D actual = DebugTools::textureSubImage(cache.texture(), 0, {{}, data.size}, + #ifndef MAGNUM_TARGET_WEBGL + cache.processedFormat() == PixelFormat::R8Unorm ? + Image2D{GL::PixelFormat::Red, GL::PixelType::UnsignedByte} : + #endif + Image2D{cache.processedFormat()} + ); #endif MAGNUM_VERIFY_NO_GL_ERROR(); @@ -302,8 +313,20 @@ void DistanceFieldGlyphCacheGLTest::setProcessedImage() { Image3D actual3 = cache.processedImage(); /** @todo ugh have slicing on images directly already */ MutableImageView2D actual{actual3.format(), actual3.size().xy(), actual3.data()}; - #else + #elif !defined(MAGNUM_TARGET_GLES2) Image2D actual = DebugTools::textureSubImage(cache.texture(), 0, {{}, {16, 8}}, cache.processedFormat()); + #else + /* On ES2, R8Unorm maps to Luminance, but here it's actually Red if + EXT_texture_rg is supported. We however need the generic format again + below for comparison, so reinterpret it back. */ + Image2D actualGLFormat = DebugTools::textureSubImage(cache.texture(), 0, {{}, {16, 8}}, + #ifndef MAGNUM_TARGET_WEBGL + cache.processedFormat() == PixelFormat::R8Unorm ? + Image2D{GL::PixelFormat::Red, GL::PixelType::UnsignedByte} : + #endif + Image2D{cache.processedFormat()} + ); + ImageView2D actual{actualGLFormat.storage(), PixelFormat::R8Unorm, actualGLFormat.size(), actualGLFormat.data()}; #endif MAGNUM_VERIFY_NO_GL_ERROR(); @@ -337,9 +360,10 @@ void DistanceFieldGlyphCacheGLTest::setDistanceFieldImageUnsupportedGLFormat() { /* Format that doesn't have a generic equivalent gets passed as-is */ cache.setDistanceFieldImage({}, ImageView2D{GL::PixelFormat::RGBA, GL::PixelType::UnsignedShort5551, {1, 1}, "hello!!"}); CORRADE_IGNORE_DEPRECATED_POP - CORRADE_COMPARE_AS(out.str(), - "Text::AbstractGlyphCache::setProcessedImage(): expected PixelFormat::R8Unorm but got PixelFormat::RGBA32F\n" - "Text::AbstractGlyphCache::setProcessedImage(): expected PixelFormat::R8Unorm but got PixelFormat::ImplementationSpecific(0x1908)\n", + CORRADE_COMPARE_AS(out.str(), Utility::formatString( + "Text::AbstractGlyphCache::setProcessedImage(): expected PixelFormat::{0} but got PixelFormat::RGBA32F\n" + "Text::AbstractGlyphCache::setProcessedImage(): expected PixelFormat::{0} but got PixelFormat::ImplementationSpecific(0x1908)\n", + cache.processedFormat() == PixelFormat::RGBA8Unorm ? "RGBA8Unorm" : "R8Unorm"), TestSuite::Compare::String); } #endif