Skip to content

Commit

Permalink
Make the GL context current in EmbedderSurfaceGLImpeller before creat…
Browse files Browse the repository at this point in the history
…ing the GPU surface (flutter#50807)

The GPUSurfaceGLImpeller ctor creates an AiksContext/ContentContext, which loads the shader pipelines.  If the current thread does not have a GL context and can not execute ReactorGLES operations, then the pipeline futures will not complete.  This can cause the raster thread to hang if the reactor has not run and the futures are still incomplete when a rendering task later needs to obtain the pipeline.
  • Loading branch information
jason-simmons authored Feb 21, 2024
1 parent bd60b55 commit f7ac96d
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 3 deletions.
2 changes: 1 addition & 1 deletion shell/platform/embedder/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ test_fixtures("fixtures") {
"fixtures/dpr_noxform.png",
"fixtures/dpr_xform.png",
"fixtures/gradient.png",
"fixtures/impeller_gl_gradient.png",
"fixtures/impeller_gl_test.png",
"fixtures/vk_dpr_noxform.png",
"fixtures/vk_gradient.png",
"fixtures/gradient_metal.png",
Expand Down
5 changes: 5 additions & 0 deletions shell/platform/embedder/embedder_surface_gl_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ EmbedderSurfaceGLImpeller::GLContextFramebufferInfo() const {

// |EmbedderSurface|
std::unique_ptr<Surface> EmbedderSurfaceGLImpeller::CreateGPUSurface() {
// Ensure that the GL context is current before creating the GPU surface.
// GPUSurfaceGLImpeller initialization will set up shader pipelines, and the
// current thread needs to be able to execute reactor operations.
GLContextMakeCurrent();

return std::make_unique<GPUSurfaceGLImpeller>(
this, // GPU surface GL delegate
impeller_context_, // Impeller context
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions shell/platform/embedder/fixtures/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1364,3 +1364,21 @@ void render_gradient_retained() {
};
PlatformDispatcher.instance.scheduleFrame();
}

@pragma('vm:entry-point')
void render_impeller_gl_test() {
PlatformDispatcher.instance.onBeginFrame = (Duration duration) {
final SceneBuilder builder = SceneBuilder();
builder.pushOffset(0.0, 0.0);
final Paint paint = Paint();
paint.color = Color.fromARGB(255, 0, 0, 255);
final PictureRecorder baseRecorder = PictureRecorder();
final Canvas canvas = Canvas(baseRecorder);
canvas.drawPaint(Paint()..color = Color.fromARGB(255, 255, 0, 0));
canvas.drawRect(Rect.fromLTRB(20.0, 20.0, 200.0, 150.0), paint);
builder.addPicture(Offset.zero, baseRecorder.endRecording());
builder.pop();
PlatformDispatcher.instance.views.first.render(builder.build());
};
PlatformDispatcher.instance.scheduleFrame();
}
4 changes: 2 additions & 2 deletions shell/platform/embedder/tests/embedder_gl_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4711,7 +4711,7 @@ TEST_F(EmbedderTest, CanRenderWithImpellerOpenGL) {
});

builder.AddCommandLineArgument("--enable-impeller");
builder.SetDartEntrypoint("render_gradient");
builder.SetDartEntrypoint("render_impeller_gl_test");
builder.SetOpenGLRendererConfig(SkISize::Make(800, 600));
builder.SetCompositor();
builder.SetRenderTargetType(
Expand All @@ -4733,7 +4733,7 @@ TEST_F(EmbedderTest, CanRenderWithImpellerOpenGL) {

ASSERT_TRUE(ImageMatchesFixture(
FixtureNameForBackend(EmbedderTestContextType::kOpenGLContext,
"impeller_gl_gradient.png"),
"impeller_gl_test.png"),
rendered_scene));

// The scene will be rendered by the compositor, and the surface present
Expand Down

0 comments on commit f7ac96d

Please sign in to comment.