<!-- start_original_pr_link --> Reverts: flutter/flutter#165601 <!-- end_original_pr_link --> <!-- start_initiating_author --> Initiated by: jonahwilliams <!-- end_initiating_author --> <!-- start_revert_reason --> Reason for reverting: descriptor mismatch not caught in testing. Maybe missing feature? <!-- end_revert_reason --> <!-- start_original_pr_author --> Original PR Author: jonahwilliams <!-- end_original_pr_author --> <!-- start_reviewers --> Reviewed By: {gaaclarke} <!-- end_reviewers --> <!-- start_revert_body --> This change reverts the following previous change: If the onscreen surface is opaque, resolve to an alpha-less wide gamut format. This reduces the bits per color from 40 to 32, which allows us to fit in a 32 bit texture size, down from 64. This should reduce memory usage by nearly 50 MB for typical applications. <!-- end_revert_body --> Co-authored-by: auto-submit[bot] <flutter-engprod-team@google.com>
This commit is contained in:
@@ -1723,20 +1723,12 @@ bool Canvas::SupportsBlitToOnscreen() const {
|
||||
}
|
||||
|
||||
bool Canvas::BlitToOnscreen(bool is_onscreen) {
|
||||
std::shared_ptr<CommandBuffer> command_buffer =
|
||||
renderer_.GetContext()->CreateCommandBuffer();
|
||||
auto command_buffer = renderer_.GetContext()->CreateCommandBuffer();
|
||||
command_buffer->SetLabel("EntityPass Root Command Buffer");
|
||||
RenderTarget offscreen_target = render_passes_.back()
|
||||
.inline_pass_context->GetPassTarget()
|
||||
.GetRenderTarget();
|
||||
// If the src and destination format differ (due to wide gamut, alpha-less
|
||||
// format, et cetera), then a draw must always be performed instead of a blit.
|
||||
if (SupportsBlitToOnscreen() &&
|
||||
offscreen_target.GetRenderTargetTexture()
|
||||
->GetTextureDescriptor()
|
||||
.format == render_target_.GetRenderTargetTexture()
|
||||
->GetTextureDescriptor()
|
||||
.format) {
|
||||
auto offscreen_target = render_passes_.back()
|
||||
.inline_pass_context->GetPassTarget()
|
||||
.GetRenderTarget();
|
||||
if (SupportsBlitToOnscreen()) {
|
||||
auto blit_pass = command_buffer->CreateBlitPass();
|
||||
blit_pass->AddCopy(offscreen_target.GetRenderTargetTexture(),
|
||||
render_target_.GetRenderTargetTexture());
|
||||
|
||||
@@ -24,12 +24,11 @@ namespace testing {
|
||||
std::unique_ptr<Canvas> CreateTestCanvas(
|
||||
ContentContext& context,
|
||||
std::optional<Rect> cull_rect = std::nullopt,
|
||||
bool requires_readback = false,
|
||||
std::optional<PixelFormat> format = std::nullopt) {
|
||||
bool requires_readback = false) {
|
||||
TextureDescriptor onscreen_desc;
|
||||
onscreen_desc.size = {100, 100};
|
||||
onscreen_desc.format =
|
||||
format.value_or(context.GetDeviceCapabilities().GetDefaultColorFormat());
|
||||
context.GetDeviceCapabilities().GetDefaultColorFormat();
|
||||
onscreen_desc.usage = TextureUsage::kRenderTarget;
|
||||
onscreen_desc.storage_mode = StorageMode::kDevicePrivate;
|
||||
onscreen_desc.sample_count = SampleCount::kCount1;
|
||||
@@ -386,18 +385,5 @@ TEST_P(AiksTest, SupportsBlitToOnscreen) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AiksTest, SupportsBlitToOnscreenWithDifferentFormat) {
|
||||
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
|
||||
GTEST_SKIP() << "Not valid on GLES";
|
||||
}
|
||||
// Create an onscreen format which is different than the offscreen format,
|
||||
// then make the canvas perform a restore to verify a blit is not used.
|
||||
ContentContext context(GetContext(), nullptr);
|
||||
auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
|
||||
/*requires_readback=*/true,
|
||||
/*format=*/PixelFormat::kB8G8R8A8UNormIntSRGB);
|
||||
canvas->EndReplay();
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
||||
|
||||
@@ -52,11 +52,7 @@ std::shared_ptr<Texture> SwapchainTransientsMTL::GetMSAATexture() {
|
||||
TextureDescriptor desc;
|
||||
desc.size = size_;
|
||||
desc.sample_count = SampleCount::kCount4;
|
||||
if (format_ == PixelFormat::kB10G10R10XR) {
|
||||
desc.format = PixelFormat::kB10G10R10A10XR;
|
||||
} else {
|
||||
desc.format = format_;
|
||||
}
|
||||
desc.format = format_;
|
||||
desc.storage_mode = StorageMode::kDeviceTransient;
|
||||
desc.usage = TextureUsage::kRenderTarget;
|
||||
desc.type = TextureType::kTexture2DMultisample;
|
||||
|
||||
@@ -73,14 +73,6 @@ TEST_P(SwapchainTransientsMTLTest, CanAllocateSwapchainTextures) {
|
||||
// Texture cache is invalidated when pixel format changes.
|
||||
transients->SetSizeAndFormat({2, 2}, PixelFormat::kB10G10R10A10XR);
|
||||
EXPECT_NE(resolve, transients->GetResolveTexture());
|
||||
|
||||
// Transients converts alpha-less format to have alpha for MSAA.
|
||||
transients->SetSizeAndFormat({2, 2}, PixelFormat::kB10G10R10XR);
|
||||
|
||||
EXPECT_EQ(transients->GetMSAATexture()->GetTextureDescriptor().format,
|
||||
PixelFormat::kB10G10R10A10XR);
|
||||
EXPECT_EQ(transients->GetResolveTexture()->GetTextureDescriptor().format,
|
||||
PixelFormat::kB10G10R10XR);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@@ -275,9 +275,6 @@ extern CFTimeInterval display_link_target;
|
||||
} else if (self.pixelFormat == MTLPixelFormatBGRA10_XR) {
|
||||
pixelFormat = kCVPixelFormatType_40ARGBLEWideGamut;
|
||||
bytesPerElement = 8;
|
||||
} else if (self.pixelFormat == MTLPixelFormatBGR10_XR) {
|
||||
pixelFormat = kCVPixelFormatType_30RGBLEPackedWideGamut;
|
||||
bytesPerElement = 4;
|
||||
} else {
|
||||
FML_LOG(ERROR) << "Unsupported pixel format: " << self.pixelFormat;
|
||||
return nil;
|
||||
|
||||
@@ -51,12 +51,9 @@ FLUTTER_ASSERT_ARC
|
||||
CAMetalLayer* layer = (CAMetalLayer*)self.layer;
|
||||
#pragma clang diagnostic pop
|
||||
layer.pixelFormat = pixelFormat;
|
||||
if (pixelFormat == MTLPixelFormatRGBA16Float || pixelFormat == MTLPixelFormatBGRA10_XR ||
|
||||
pixelFormat == MTLPixelFormatBGR10_XR) {
|
||||
if (pixelFormat == MTLPixelFormatRGBA16Float || pixelFormat == MTLPixelFormatBGRA10_XR) {
|
||||
self->_colorSpaceRef = fml::CFRef(CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB));
|
||||
layer.colorspace = self->_colorSpaceRef;
|
||||
// Overlay layers always need an alpha channel.
|
||||
layer.pixelFormat = MTLPixelFormatBGRA10_XR;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
|
||||
@@ -78,6 +78,16 @@ FLUTTER_ASSERT_ARC
|
||||
return self;
|
||||
}
|
||||
|
||||
static void PrintWideGamutWarningOnce() {
|
||||
static BOOL did_print = NO;
|
||||
if (did_print) {
|
||||
return;
|
||||
}
|
||||
FML_DLOG(WARNING) << "Rendering wide gamut colors is turned on but isn't "
|
||||
"supported, downgrading the color gamut to sRGB.";
|
||||
did_print = YES;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
if ([self.layer isKindOfClass:[CAMetalLayer class]]) {
|
||||
// It is a known Apple bug that CAMetalLayer incorrectly reports its supported
|
||||
@@ -86,7 +96,6 @@ FLUTTER_ASSERT_ARC
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
||||
CAMetalLayer* layer = (CAMetalLayer*)self.layer;
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
CGFloat screenScale = self.screen.scale;
|
||||
layer.allowsGroupOpacity = YES;
|
||||
layer.contentsScale = screenScale;
|
||||
@@ -95,13 +104,9 @@ FLUTTER_ASSERT_ARC
|
||||
if (_isWideGamutEnabled && self.isWideGamutSupported) {
|
||||
fml::CFRef<CGColorSpaceRef> srgb(CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB));
|
||||
layer.colorspace = srgb;
|
||||
// If the flutter layer is opaque, then use an alpha-less format for the onscreen
|
||||
// texture. This will reduce wide gamut memory usage by 50%, and Impeller will
|
||||
// still correctly use alpha for MSAA textures and any offscreen save layer usage.
|
||||
// For non-wide gamut formats there is no point in removing the alpha channel as
|
||||
// the textures must align to 32 bits (32 -> 24 = 32) whereas wide gamut is (40 -> 32 = 32)
|
||||
// instead of 64.
|
||||
layer.pixelFormat = layer.opaque ? MTLPixelFormatBGR10_XR : MTLPixelFormatBGRA10_XR;
|
||||
layer.pixelFormat = MTLPixelFormatBGRA10_XR;
|
||||
} else if (_isWideGamutEnabled && !self.isWideGamutSupported) {
|
||||
PrintWideGamutWarningOnce();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_metal_impeller.h"
|
||||
|
||||
#include "flutter/impeller/core/formats.h"
|
||||
#include "flutter/impeller/renderer/backend/metal/formats_mtl.h"
|
||||
#include "flutter/impeller/renderer/context.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_metal_impeller.h"
|
||||
@@ -44,12 +43,8 @@ void IOSSurfaceMetalImpeller::UpdateStorageSizeIfNecessary() {
|
||||
|
||||
// |IOSSurface|
|
||||
std::unique_ptr<Surface> IOSSurfaceMetalImpeller::CreateGPUSurface() {
|
||||
// Convert alpha-less onscreen format to alpha including format.
|
||||
impeller::PixelFormat pixel_format = impeller::FromMTLPixelFormat(layer_.pixelFormat);
|
||||
if (pixel_format == impeller::PixelFormat::kB10G10R10XR) {
|
||||
pixel_format = impeller::PixelFormat::kB10G10R10A10XR;
|
||||
}
|
||||
impeller_context_->UpdateOffscreenLayerPixelFormat(pixel_format);
|
||||
impeller_context_->UpdateOffscreenLayerPixelFormat(
|
||||
impeller::FromMTLPixelFormat(layer_.pixelFormat));
|
||||
return std::make_unique<GPUSurfaceMetalImpeller>(this, //
|
||||
aiks_context_ //
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user