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

Commit 01bfe76

Browse files
authored
Add format field to EGL surface backing store (#54499)
Trying to use the `GL_BGRA8_EXT` format for the EGL surface backing store on *desktop* OpenGL platforms would fail at: https://github.com/flutter/engine/blob/bde314b856850155d0678632b62c23c84f49afab/shell/platform/embedder/embedder.cc#L869 This seems to be a known issue and both the Linux and Windows embedders have some logic to pick a different format depending on the OpenGL context information: https://github.com/flutter/engine/blob/088dcfa6cf934088413c5d8af754de1ef7b0d1ca/shell/platform/windows/compositor_opengl.cc#L23-L34 https://github.com/flutter/engine/blob/088dcfa6cf934088413c5d8af754de1ef7b0d1ca/shell/platform/linux/fl_framebuffer.cc#L81-L104 This pull-request gets rid of the hard-coded `GL_BGRA8_EXT` format and makes it configurable by adding a `format` field to the `FlutterOpenGLSurface` struct. _Disclaimer_: This has only been tested on desktop Linux (Wayland) using the `GR_GL_RGBA8` format which seemed to work as expected. This change is related to the recently introduced EGL surface backing store: flutter/flutter#58363 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 9d1566d commit 01bfe76

File tree

5 files changed

+78
-4
lines changed

5 files changed

+78
-4
lines changed

shell/platform/embedder/embedder.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
868868
const FlutterOpenGLSurface* surface) {
869869
#ifdef SHELL_ENABLE_GL
870870
GrGLFramebufferInfo framebuffer_info = {};
871-
framebuffer_info.fFormat = GL_BGRA8_EXT;
871+
framebuffer_info.fFormat = SAFE_ACCESS(surface, format, GL_BGRA8_EXT);
872872
framebuffer_info.fFBOID = 0;
873873

874874
auto backend_render_target =
@@ -881,11 +881,17 @@ static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
881881

882882
SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
883883

884+
std::optional<SkColorType> color_type =
885+
FlutterFormatToSkColorType(surface->format);
886+
if (!color_type) {
887+
return nullptr;
888+
}
889+
884890
auto sk_surface = SkSurfaces::WrapBackendRenderTarget(
885891
context, // context
886892
backend_render_target, // backend render target
887893
kBottomLeft_GrSurfaceOrigin, // surface origin
888-
kN32_SkColorType, // color type
894+
color_type.value(), // color type
889895
SkColorSpace::MakeSRGB(), // color space
890896
&surface_properties, // surface properties
891897
static_cast<SkSurfaces::RenderTargetReleaseProc>(

shell/platform/embedder/embedder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,13 @@ typedef struct {
458458
///
459459
/// @attention required. (non-null)
460460
VoidCallback destruction_callback;
461+
462+
/// The surface format.
463+
///
464+
/// Allowed values:
465+
/// - GL_RGBA8
466+
/// - GL_BGRA8_EXT
467+
uint32_t format;
461468
} FlutterOpenGLSurface;
462469

463470
typedef bool (*BoolCallback)(void* /* user data */);

shell/platform/embedder/tests/embedder_assertions.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ inline bool operator==(const FlutterOpenGLFramebuffer& a,
7070
inline bool operator==(const FlutterOpenGLSurface& a,
7171
const FlutterOpenGLSurface& b) {
7272
return a.make_current_callback == b.make_current_callback &&
73-
a.user_data == b.user_data &&
73+
a.user_data == b.user_data && a.format == b.format &&
7474
a.destruction_callback == b.destruction_callback;
7575
}
7676

@@ -309,7 +309,8 @@ inline std::ostream& operator<<(std::ostream& out,
309309
const FlutterOpenGLSurface& item) {
310310
return out << "(FlutterOpenGLSurface) Make Current Callback: "
311311
<< reinterpret_cast<void*>(item.make_current_callback)
312-
<< " User Data: " << item.user_data << " Destruction Callback: "
312+
<< " User Data: " << item.user_data << "Format: " << item.format
313+
<< " Destruction Callback: "
313314
<< reinterpret_cast<void*>(item.destruction_callback);
314315
}
315316

shell/platform/embedder/tests/embedder_gl_unittests.cc

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4527,6 +4527,65 @@ TEST_F(EmbedderTest, CreateInvalidBackingstoreOpenGLFramebuffer) {
45274527
latch.Wait();
45284528
}
45294529

4530+
TEST_F(EmbedderTest, CreateInvalidBackingstoreOpenGLSurface) {
4531+
auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext);
4532+
EmbedderConfigBuilder builder(context);
4533+
builder.SetOpenGLRendererConfig(SkISize::Make(800, 600));
4534+
builder.SetCompositor();
4535+
builder.SetRenderTargetType(
4536+
EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLSurface);
4537+
builder.SetDartEntrypoint("invalid_backingstore");
4538+
4539+
fml::AutoResetWaitableEvent latch;
4540+
4541+
builder.GetCompositor().create_backing_store_callback =
4542+
[](const FlutterBackingStoreConfig* config, //
4543+
FlutterBackingStore* backing_store_out, //
4544+
void* user_data //
4545+
) {
4546+
backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
4547+
backing_store_out->user_data = user_data;
4548+
backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeSurface;
4549+
backing_store_out->open_gl.surface.user_data = user_data;
4550+
// Deliberately set this to an invalid format
4551+
backing_store_out->open_gl.surface.format = 0;
4552+
backing_store_out->open_gl.surface.make_current_callback = [](void*,
4553+
bool*) {
4554+
ADD_FAILURE() << "make_current_callback method should not be called";
4555+
return true;
4556+
};
4557+
backing_store_out->open_gl.surface.clear_current_callback = [](void*,
4558+
bool*) {
4559+
ADD_FAILURE() << "clear_current_callback method should not be called";
4560+
return true;
4561+
};
4562+
backing_store_out->open_gl.surface.destruction_callback =
4563+
[](void* user_data) {
4564+
FAIL() << "destruction_callback method should not be called";
4565+
};
4566+
4567+
return true;
4568+
};
4569+
4570+
context.AddNativeCallback(
4571+
"SignalNativeTest",
4572+
CREATE_NATIVE_ENTRY(
4573+
[&latch](Dart_NativeArguments args) { latch.Signal(); }));
4574+
4575+
auto engine = builder.LaunchEngine();
4576+
4577+
// Send a window metrics events so frames may be scheduled.
4578+
FlutterWindowMetricsEvent event = {};
4579+
event.struct_size = sizeof(event);
4580+
event.width = 800;
4581+
event.height = 600;
4582+
event.pixel_ratio = 1.0;
4583+
ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event),
4584+
kSuccess);
4585+
ASSERT_TRUE(engine.is_valid());
4586+
latch.Wait();
4587+
}
4588+
45304589
TEST_F(EmbedderTest, ExternalTextureGLRefreshedTooOften) {
45314590
TestGLSurface surface(SkISize::Make(100, 100));
45324591
auto context = surface.GetGrContext();

shell/platform/embedder/tests/embedder_test_backingstore_producer.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ bool EmbedderTestBackingStoreProducer::CreateSurface(
258258
backing_store_out->open_gl.surface.clear_current_callback = clear_current;
259259
backing_store_out->open_gl.surface.destruction_callback =
260260
destruction_callback;
261+
backing_store_out->open_gl.surface.format = 0x93A1 /* GL_BGRA8_EXT */;
261262

262263
return true;
263264
#else

0 commit comments

Comments
 (0)