Skip to content

Commit 9442880

Browse files
author
Jonah Williams
authored
[Impeller] force software resize usage for GLES backend. (flutter/engine#56511)
Should fix some of the wonderous bugs by avoiding the usage of gl blitframebuffer altogether. Fixes flutter#158391
1 parent 6c4ea42 commit 9442880

File tree

5 files changed

+68
-15
lines changed

5 files changed

+68
-15
lines changed

engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ bool CapabilitiesGLES::SupportsSSBO() const {
158158
}
159159

160160
bool CapabilitiesGLES::SupportsTextureToTextureBlits() const {
161+
// TODO(158523): Switch this to true for improved performance
162+
// on GLES 3.0+ devices. Note that this wasn't enabled because
163+
// there were some rendering issues on some devices.
161164
return false;
162165
}
163166

engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ DecompressResult ImageDecoderImpeller::DecompressTexture(
114114
SkISize target_size,
115115
impeller::ISize max_texture_size,
116116
bool supports_wide_gamut,
117+
const std::shared_ptr<const impeller::Capabilities>& capabilities,
117118
const std::shared_ptr<impeller::Allocator>& allocator) {
118119
TRACE_EVENT0("impeller", __FUNCTION__);
119120
if (!descriptor) {
@@ -238,7 +239,8 @@ DecompressResult ImageDecoderImpeller::DecompressTexture(
238239
: std::optional<SkImageInfo>(image_info.makeDimensions(target_size));
239240

240241
if (source_size.width() > max_texture_size.width ||
241-
source_size.height() > max_texture_size.height) {
242+
source_size.height() > max_texture_size.height ||
243+
!capabilities->SupportsTextureToTextureBlits()) {
242244
//----------------------------------------------------------------------------
243245
/// 2. If the decoded image isn't the requested target size and the src size
244246
/// exceeds the device max texture size, perform a slow CPU reisze.
@@ -536,7 +538,8 @@ void ImageDecoderImpeller::Decode(fml::RefPtr<ImageDescriptor> descriptor,
536538
// Always decompress on the concurrent runner.
537539
auto bitmap_result = DecompressTexture(
538540
raw_descriptor, target_size, max_size_supported,
539-
supports_wide_gamut, context->GetResourceAllocator());
541+
/*supports_wide_gamut=*/supports_wide_gamut,
542+
context->GetCapabilities(), context->GetResourceAllocator());
540543
if (!bitmap_result.device_buffer) {
541544
result(nullptr, bitmap_result.decode_error);
542545
return;

engine/src/flutter/lib/ui/painting/image_decoder_impeller.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "flutter/lib/ui/painting/image_decoder.h"
1212
#include "impeller/core/formats.h"
1313
#include "impeller/geometry/size.h"
14+
#include "impeller/renderer/capabilities.h"
1415
#include "include/core/SkImageInfo.h"
1516
#include "third_party/skia/include/core/SkBitmap.h"
1617

@@ -68,6 +69,7 @@ class ImageDecoderImpeller final : public ImageDecoder {
6869
SkISize target_size,
6970
impeller::ISize max_texture_size,
7071
bool supports_wide_gamut,
72+
const std::shared_ptr<const impeller::Capabilities>& capabilities,
7173
const std::shared_ptr<impeller::Allocator>& allocator);
7274

7375
/// @brief Create a device private texture from the provided host buffer.

engine/src/flutter/lib/ui/painting/image_decoder_no_gl_unittests.cc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
// found in the LICENSE file.
44

55
#include "flutter/lib/ui/painting/image_decoder_no_gl_unittests.h"
6+
#include <memory>
67

78
#include "flutter/fml/endianness.h"
9+
#include "impeller/renderer/capabilities.h"
810
#include "include/core/SkColorType.h"
911

1012
namespace flutter {
@@ -80,6 +82,10 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutDisplayP3) {
8082
#endif
8183
auto data = flutter::testing::OpenFixtureAsSkData("DisplayP3Logo.png");
8284
auto image = SkImages::DeferredFromEncodedData(data);
85+
std::shared_ptr<impeller::Capabilities> capabilities =
86+
impeller::CapabilitiesBuilder()
87+
.SetSupportsTextureToTextureBlits(true)
88+
.Build();
8389
ASSERT_TRUE(image != nullptr);
8490
ASSERT_EQ(SkISize::Make(100, 100), image->dimensions());
8591

@@ -100,7 +106,7 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutDisplayP3) {
100106
std::optional<DecompressResult> wide_result =
101107
ImageDecoderImpeller::DecompressTexture(
102108
descriptor.get(), SkISize::Make(100, 100), {100, 100},
103-
/*supports_wide_gamut=*/true, allocator);
109+
/*supports_wide_gamut=*/true, capabilities, allocator);
104110
ASSERT_TRUE(wide_result.has_value());
105111
ASSERT_EQ(wide_result->image_info.colorType(), kRGBA_F16_SkColorType);
106112
ASSERT_TRUE(wide_result->image_info.colorSpace()->isSRGB());
@@ -124,7 +130,7 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutDisplayP3) {
124130
std::optional<DecompressResult> narrow_result =
125131
ImageDecoderImpeller::DecompressTexture(
126132
descriptor.get(), SkISize::Make(100, 100), {100, 100},
127-
/*supports_wide_gamut=*/false, allocator);
133+
/*supports_wide_gamut=*/false, capabilities, allocator);
128134

129135
ASSERT_TRUE(narrow_result.has_value());
130136
ASSERT_EQ(narrow_result->image_info.colorType(), kRGBA_8888_SkColorType);
@@ -137,6 +143,10 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutIndexedPng) {
137143
#endif
138144
auto data = flutter::testing::OpenFixtureAsSkData("WideGamutIndexed.png");
139145
auto image = SkImages::DeferredFromEncodedData(data);
146+
std::shared_ptr<impeller::Capabilities> capabilities =
147+
impeller::CapabilitiesBuilder()
148+
.SetSupportsTextureToTextureBlits(true)
149+
.Build();
140150
ASSERT_TRUE(image != nullptr);
141151
ASSERT_EQ(SkISize::Make(100, 100), image->dimensions());
142152

@@ -157,7 +167,7 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutIndexedPng) {
157167
std::optional<DecompressResult> wide_result =
158168
ImageDecoderImpeller::DecompressTexture(
159169
descriptor.get(), SkISize::Make(100, 100), {100, 100},
160-
/*supports_wide_gamut=*/true, allocator);
170+
/*supports_wide_gamut=*/true, capabilities, allocator);
161171
ASSERT_EQ(wide_result->image_info.colorType(), kBGR_101010x_XR_SkColorType);
162172
ASSERT_TRUE(wide_result->image_info.colorSpace()->isSRGB());
163173

@@ -180,7 +190,7 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutIndexedPng) {
180190
std::optional<DecompressResult> narrow_result =
181191
ImageDecoderImpeller::DecompressTexture(
182192
descriptor.get(), SkISize::Make(100, 100), {100, 100},
183-
/*supports_wide_gamut=*/false, allocator);
193+
/*supports_wide_gamut=*/false, capabilities, allocator);
184194

185195
ASSERT_TRUE(narrow_result.has_value());
186196
ASSERT_EQ(narrow_result->image_info.colorType(), kRGBA_8888_SkColorType);
@@ -193,6 +203,10 @@ TEST(ImageDecoderNoGLTest, ImepllerUnmultipliedAlphaPng) {
193203
#endif
194204
auto data = flutter::testing::OpenFixtureAsSkData("unmultiplied_alpha.png");
195205
auto image = SkImages::DeferredFromEncodedData(data);
206+
std::shared_ptr<impeller::Capabilities> capabilities =
207+
impeller::CapabilitiesBuilder()
208+
.SetSupportsTextureToTextureBlits(true)
209+
.Build();
196210
ASSERT_TRUE(image != nullptr);
197211
ASSERT_EQ(SkISize::Make(11, 11), image->dimensions());
198212

@@ -210,7 +224,7 @@ TEST(ImageDecoderNoGLTest, ImepllerUnmultipliedAlphaPng) {
210224
std::optional<DecompressResult> result =
211225
ImageDecoderImpeller::DecompressTexture(
212226
descriptor.get(), SkISize::Make(11, 11), {11, 11},
213-
/*supports_wide_gamut=*/true, allocator);
227+
/*supports_wide_gamut=*/true, capabilities, allocator);
214228
ASSERT_EQ(result->image_info.colorType(), kRGBA_8888_SkColorType);
215229

216230
const SkPixmap& pixmap = result->sk_bitmap->pixmap();

engine/src/flutter/lib/ui/painting/image_decoder_unittests.cc

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -441,12 +441,16 @@ TEST_F(ImageDecoderFixtureTest, ImpellerNullColorspace) {
441441
std::move(data), image->imageInfo(), 10 * 4);
442442

443443
#if IMPELLER_SUPPORTS_RENDERING
444+
std::shared_ptr<impeller::Capabilities> capabilities =
445+
impeller::CapabilitiesBuilder()
446+
.SetSupportsTextureToTextureBlits(true)
447+
.Build();
444448
std::shared_ptr<impeller::Allocator> allocator =
445449
std::make_shared<impeller::TestImpellerAllocator>();
446450
std::optional<DecompressResult> decompressed =
447451
ImageDecoderImpeller::DecompressTexture(
448452
descriptor.get(), SkISize::Make(100, 100), {100, 100},
449-
/*supports_wide_gamut=*/true, allocator);
453+
/*supports_wide_gamut=*/true, capabilities, allocator);
450454
ASSERT_TRUE(decompressed.has_value());
451455
ASSERT_EQ(decompressed->image_info.colorType(), kRGBA_8888_SkColorType);
452456
ASSERT_EQ(decompressed->image_info.colorSpace(), nullptr);
@@ -468,12 +472,16 @@ TEST_F(ImageDecoderFixtureTest, ImpellerPixelConversion32F) {
468472
std::move(data), image->imageInfo(), 10 * 16);
469473

470474
#if IMPELLER_SUPPORTS_RENDERING
475+
std::shared_ptr<impeller::Capabilities> capabilities =
476+
impeller::CapabilitiesBuilder()
477+
.SetSupportsTextureToTextureBlits(true)
478+
.Build();
471479
std::shared_ptr<impeller::Allocator> allocator =
472480
std::make_shared<impeller::TestImpellerAllocator>();
473481
std::optional<DecompressResult> decompressed =
474482
ImageDecoderImpeller::DecompressTexture(
475483
descriptor.get(), SkISize::Make(100, 100), {100, 100},
476-
/*supports_wide_gamut=*/true, allocator);
484+
/*supports_wide_gamut=*/true, capabilities, allocator);
477485

478486
ASSERT_TRUE(decompressed.has_value());
479487
ASSERT_EQ(decompressed->image_info.colorType(), kRGBA_F16_SkColorType);
@@ -496,12 +504,16 @@ TEST_F(ImageDecoderFixtureTest, ImpellerWideGamutDisplayP3Opaque) {
496504
std::move(generator));
497505

498506
#if IMPELLER_SUPPORTS_RENDERING
507+
std::shared_ptr<impeller::Capabilities> capabilities =
508+
impeller::CapabilitiesBuilder()
509+
.SetSupportsTextureToTextureBlits(true)
510+
.Build();
499511
std::shared_ptr<impeller::Allocator> allocator =
500512
std::make_shared<impeller::TestImpellerAllocator>();
501513
std::optional<DecompressResult> wide_result =
502514
ImageDecoderImpeller::DecompressTexture(
503515
descriptor.get(), SkISize::Make(100, 100), {100, 100},
504-
/*supports_wide_gamut=*/true, allocator);
516+
/*supports_wide_gamut=*/true, capabilities, allocator);
505517

506518
ASSERT_TRUE(wide_result.has_value());
507519
ASSERT_EQ(wide_result->image_info.colorType(), kBGR_101010x_XR_SkColorType);
@@ -526,7 +538,7 @@ TEST_F(ImageDecoderFixtureTest, ImpellerWideGamutDisplayP3Opaque) {
526538
std::optional<DecompressResult> narrow_result =
527539
ImageDecoderImpeller::DecompressTexture(
528540
descriptor.get(), SkISize::Make(100, 100), {100, 100},
529-
/*supports_wide_gamut=*/false, allocator);
541+
/*supports_wide_gamut=*/false, capabilities, allocator);
530542

531543
ASSERT_TRUE(narrow_result.has_value());
532544
ASSERT_EQ(narrow_result->image_info.colorType(), kRGBA_8888_SkColorType);
@@ -548,12 +560,16 @@ TEST_F(ImageDecoderFixtureTest, ImpellerNonWideGamut) {
548560
std::move(generator));
549561

550562
#if IMPELLER_SUPPORTS_RENDERING
563+
std::shared_ptr<impeller::Capabilities> capabilities =
564+
impeller::CapabilitiesBuilder()
565+
.SetSupportsTextureToTextureBlits(true)
566+
.Build();
551567
std::shared_ptr<impeller::Allocator> allocator =
552568
std::make_shared<impeller::TestImpellerAllocator>();
553569
std::optional<DecompressResult> result =
554570
ImageDecoderImpeller::DecompressTexture(
555571
descriptor.get(), SkISize::Make(600, 200), {600, 200},
556-
/*supports_wide_gamut=*/true, allocator);
572+
/*supports_wide_gamut=*/true, capabilities, allocator);
557573

558574
ASSERT_TRUE(result.has_value());
559575
ASSERT_EQ(result->image_info.colorType(), kRGBA_8888_SkColorType);
@@ -802,31 +818,46 @@ TEST(ImageDecoderTest, VerifySimpleDecoding) {
802818
EXPECT_EQ(compressed_image->alphaType(), kOpaque_SkAlphaType);
803819

804820
#if IMPELLER_SUPPORTS_RENDERING
821+
std::shared_ptr<impeller::Capabilities> capabilities =
822+
impeller::CapabilitiesBuilder()
823+
.SetSupportsTextureToTextureBlits(true)
824+
.Build();
825+
std::shared_ptr<impeller::Capabilities> capabilities_no_blit =
826+
impeller::CapabilitiesBuilder()
827+
.SetSupportsTextureToTextureBlits(false)
828+
.Build();
805829
// Bitmap sizes reflect the original image size as resizing is done on the
806830
// GPU if the src size is smaller than the max texture size.
807831
std::shared_ptr<impeller::Allocator> allocator =
808832
std::make_shared<impeller::TestImpellerAllocator>();
809833
auto result_1 = ImageDecoderImpeller::DecompressTexture(
810834
descriptor.get(), SkISize::Make(6, 2), {1000, 1000},
811-
/*supports_wide_gamut=*/false, allocator);
835+
/*supports_wide_gamut=*/false, capabilities, allocator);
812836
EXPECT_EQ(result_1.sk_bitmap->width(), 75);
813837
EXPECT_EQ(result_1.sk_bitmap->height(), 25);
814838

815839
// Bitmap sizes reflect the scaled size if the source size is larger than
816840
// max texture size even if destination size isn't max texture size.
817841
auto result_2 = ImageDecoderImpeller::DecompressTexture(
818842
descriptor.get(), SkISize::Make(6, 2), {10, 10},
819-
/*supports_wide_gamut=*/false, allocator);
843+
/*supports_wide_gamut=*/false, capabilities, allocator);
820844
EXPECT_EQ(result_2.sk_bitmap->width(), 6);
821845
EXPECT_EQ(result_2.sk_bitmap->height(), 2);
822846

823847
// If the destination size is larger than the max texture size the image
824848
// is scaled down.
825849
auto result_3 = ImageDecoderImpeller::DecompressTexture(
826850
descriptor.get(), SkISize::Make(60, 20), {10, 10},
827-
/*supports_wide_gamut=*/false, allocator);
851+
/*supports_wide_gamut=*/false, capabilities, allocator);
828852
EXPECT_EQ(result_3.sk_bitmap->width(), 10);
829853
EXPECT_EQ(result_3.sk_bitmap->height(), 10);
854+
855+
// CPU resize is forced.
856+
auto result_4 = ImageDecoderImpeller::DecompressTexture(
857+
descriptor.get(), SkISize::Make(6, 2), {1000, 1000},
858+
/*supports_wide_gamut=*/false, capabilities_no_blit, allocator);
859+
EXPECT_EQ(result_4.sk_bitmap->width(), 6);
860+
EXPECT_EQ(result_4.sk_bitmap->height(), 2);
830861
#endif // IMPELLER_SUPPORTS_RENDERING
831862
}
832863

0 commit comments

Comments
 (0)