Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller] force software resize usage for GLES backend. #56511

Merged
merged 11 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions impeller/renderer/backend/gles/capabilities_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ bool CapabilitiesGLES::SupportsSSBO() const {
}

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

Expand Down
7 changes: 5 additions & 2 deletions lib/ui/painting/image_decoder_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ DecompressResult ImageDecoderImpeller::DecompressTexture(
SkISize target_size,
impeller::ISize max_texture_size,
bool supports_wide_gamut,
const std::shared_ptr<const impeller::Capabilities>& capabilities,
const std::shared_ptr<impeller::Allocator>& allocator) {
TRACE_EVENT0("impeller", __FUNCTION__);
if (!descriptor) {
Expand Down Expand Up @@ -238,7 +239,8 @@ DecompressResult ImageDecoderImpeller::DecompressTexture(
: std::optional<SkImageInfo>(image_info.makeDimensions(target_size));

if (source_size.width() > max_texture_size.width ||
source_size.height() > max_texture_size.height) {
source_size.height() > max_texture_size.height ||
!capabilities->SupportsTextureToTextureBlits()) {
//----------------------------------------------------------------------------
/// 2. If the decoded image isn't the requested target size and the src size
/// exceeds the device max texture size, perform a slow CPU reisze.
Expand Down Expand Up @@ -536,7 +538,8 @@ void ImageDecoderImpeller::Decode(fml::RefPtr<ImageDescriptor> descriptor,
// Always decompress on the concurrent runner.
auto bitmap_result = DecompressTexture(
raw_descriptor, target_size, max_size_supported,
supports_wide_gamut, context->GetResourceAllocator());
/*supports_wide_gamut=*/supports_wide_gamut,
context->GetCapabilities(), context->GetResourceAllocator());
if (!bitmap_result.device_buffer) {
result(nullptr, bitmap_result.decode_error);
return;
Expand Down
2 changes: 2 additions & 0 deletions lib/ui/painting/image_decoder_impeller.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "flutter/lib/ui/painting/image_decoder.h"
#include "impeller/core/formats.h"
#include "impeller/geometry/size.h"
#include "impeller/renderer/capabilities.h"
#include "include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkBitmap.h"

Expand Down Expand Up @@ -68,6 +69,7 @@ class ImageDecoderImpeller final : public ImageDecoder {
SkISize target_size,
impeller::ISize max_texture_size,
bool supports_wide_gamut,
const std::shared_ptr<const impeller::Capabilities>& capabilities,
const std::shared_ptr<impeller::Allocator>& allocator);

/// @brief Create a device private texture from the provided host buffer.
Expand Down
24 changes: 19 additions & 5 deletions lib/ui/painting/image_decoder_no_gl_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
// found in the LICENSE file.

#include "flutter/lib/ui/painting/image_decoder_no_gl_unittests.h"
#include <memory>

#include "flutter/fml/endianness.h"
#include "impeller/renderer/capabilities.h"
#include "include/core/SkColorType.h"

namespace flutter {
Expand Down Expand Up @@ -80,6 +82,10 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutDisplayP3) {
#endif
auto data = flutter::testing::OpenFixtureAsSkData("DisplayP3Logo.png");
auto image = SkImages::DeferredFromEncodedData(data);
std::shared_ptr<impeller::Capabilities> capabilities =
impeller::CapabilitiesBuilder()
.SetSupportsTextureToTextureBlits(true)
.Build();
ASSERT_TRUE(image != nullptr);
ASSERT_EQ(SkISize::Make(100, 100), image->dimensions());

Expand All @@ -100,7 +106,7 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutDisplayP3) {
std::optional<DecompressResult> wide_result =
ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(100, 100), {100, 100},
/*supports_wide_gamut=*/true, allocator);
/*supports_wide_gamut=*/true, capabilities, allocator);
ASSERT_TRUE(wide_result.has_value());
ASSERT_EQ(wide_result->image_info.colorType(), kRGBA_F16_SkColorType);
ASSERT_TRUE(wide_result->image_info.colorSpace()->isSRGB());
Expand All @@ -124,7 +130,7 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutDisplayP3) {
std::optional<DecompressResult> narrow_result =
ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(100, 100), {100, 100},
/*supports_wide_gamut=*/false, allocator);
/*supports_wide_gamut=*/false, capabilities, allocator);

ASSERT_TRUE(narrow_result.has_value());
ASSERT_EQ(narrow_result->image_info.colorType(), kRGBA_8888_SkColorType);
Expand All @@ -137,6 +143,10 @@ TEST(ImageDecoderNoGLTest, ImpellerWideGamutIndexedPng) {
#endif
auto data = flutter::testing::OpenFixtureAsSkData("WideGamutIndexed.png");
auto image = SkImages::DeferredFromEncodedData(data);
std::shared_ptr<impeller::Capabilities> capabilities =
impeller::CapabilitiesBuilder()
.SetSupportsTextureToTextureBlits(true)
.Build();
ASSERT_TRUE(image != nullptr);
ASSERT_EQ(SkISize::Make(100, 100), image->dimensions());

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

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

ASSERT_TRUE(narrow_result.has_value());
ASSERT_EQ(narrow_result->image_info.colorType(), kRGBA_8888_SkColorType);
Expand All @@ -193,6 +203,10 @@ TEST(ImageDecoderNoGLTest, ImepllerUnmultipliedAlphaPng) {
#endif
auto data = flutter::testing::OpenFixtureAsSkData("unmultiplied_alpha.png");
auto image = SkImages::DeferredFromEncodedData(data);
std::shared_ptr<impeller::Capabilities> capabilities =
impeller::CapabilitiesBuilder()
.SetSupportsTextureToTextureBlits(true)
.Build();
ASSERT_TRUE(image != nullptr);
ASSERT_EQ(SkISize::Make(11, 11), image->dimensions());

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

const SkPixmap& pixmap = result->sk_bitmap->pixmap();
Expand Down
47 changes: 39 additions & 8 deletions lib/ui/painting/image_decoder_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -441,12 +441,16 @@ TEST_F(ImageDecoderFixtureTest, ImpellerNullColorspace) {
std::move(data), image->imageInfo(), 10 * 4);

#if IMPELLER_SUPPORTS_RENDERING
std::shared_ptr<impeller::Capabilities> capabilities =
impeller::CapabilitiesBuilder()
.SetSupportsTextureToTextureBlits(true)
.Build();
std::shared_ptr<impeller::Allocator> allocator =
std::make_shared<impeller::TestImpellerAllocator>();
std::optional<DecompressResult> decompressed =
ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(100, 100), {100, 100},
/*supports_wide_gamut=*/true, allocator);
/*supports_wide_gamut=*/true, capabilities, allocator);
ASSERT_TRUE(decompressed.has_value());
ASSERT_EQ(decompressed->image_info.colorType(), kRGBA_8888_SkColorType);
ASSERT_EQ(decompressed->image_info.colorSpace(), nullptr);
Expand All @@ -468,12 +472,16 @@ TEST_F(ImageDecoderFixtureTest, ImpellerPixelConversion32F) {
std::move(data), image->imageInfo(), 10 * 16);

#if IMPELLER_SUPPORTS_RENDERING
std::shared_ptr<impeller::Capabilities> capabilities =
impeller::CapabilitiesBuilder()
.SetSupportsTextureToTextureBlits(true)
.Build();
std::shared_ptr<impeller::Allocator> allocator =
std::make_shared<impeller::TestImpellerAllocator>();
std::optional<DecompressResult> decompressed =
ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(100, 100), {100, 100},
/*supports_wide_gamut=*/true, allocator);
/*supports_wide_gamut=*/true, capabilities, allocator);

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

#if IMPELLER_SUPPORTS_RENDERING
std::shared_ptr<impeller::Capabilities> capabilities =
impeller::CapabilitiesBuilder()
.SetSupportsTextureToTextureBlits(true)
.Build();
std::shared_ptr<impeller::Allocator> allocator =
std::make_shared<impeller::TestImpellerAllocator>();
std::optional<DecompressResult> wide_result =
ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(100, 100), {100, 100},
/*supports_wide_gamut=*/true, allocator);
/*supports_wide_gamut=*/true, capabilities, allocator);

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

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

#if IMPELLER_SUPPORTS_RENDERING
std::shared_ptr<impeller::Capabilities> capabilities =
impeller::CapabilitiesBuilder()
.SetSupportsTextureToTextureBlits(true)
.Build();
std::shared_ptr<impeller::Allocator> allocator =
std::make_shared<impeller::TestImpellerAllocator>();
std::optional<DecompressResult> result =
ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(600, 200), {600, 200},
/*supports_wide_gamut=*/true, allocator);
/*supports_wide_gamut=*/true, capabilities, allocator);

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

#if IMPELLER_SUPPORTS_RENDERING
std::shared_ptr<impeller::Capabilities> capabilities =
impeller::CapabilitiesBuilder()
.SetSupportsTextureToTextureBlits(true)
.Build();
std::shared_ptr<impeller::Capabilities> capabilities_no_blit =
impeller::CapabilitiesBuilder()
.SetSupportsTextureToTextureBlits(false)
.Build();
// Bitmap sizes reflect the original image size as resizing is done on the
// GPU if the src size is smaller than the max texture size.
std::shared_ptr<impeller::Allocator> allocator =
std::make_shared<impeller::TestImpellerAllocator>();
auto result_1 = ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(6, 2), {1000, 1000},
/*supports_wide_gamut=*/false, allocator);
/*supports_wide_gamut=*/false, capabilities, allocator);
EXPECT_EQ(result_1.sk_bitmap->width(), 75);
EXPECT_EQ(result_1.sk_bitmap->height(), 25);

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

// If the destination size is larger than the max texture size the image
// is scaled down.
auto result_3 = ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(60, 20), {10, 10},
/*supports_wide_gamut=*/false, allocator);
/*supports_wide_gamut=*/false, capabilities, allocator);
EXPECT_EQ(result_3.sk_bitmap->width(), 10);
EXPECT_EQ(result_3.sk_bitmap->height(), 10);

// CPU resize is forced.
auto result_4 = ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(6, 2), {1000, 1000},
/*supports_wide_gamut=*/false, capabilities_no_blit, allocator);
EXPECT_EQ(result_4.sk_bitmap->width(), 6);
EXPECT_EQ(result_4.sk_bitmap->height(), 2);
#endif // IMPELLER_SUPPORTS_RENDERING
}

Expand Down