Skip to content

Commit c7894a6

Browse files
authored
Make the context current before accessing GL in MakeSkiaGpuImage (flutter#40208)
Make the context current before accessing GL in MakeSkiaGpuImage
1 parent 7f25023 commit c7894a6

File tree

4 files changed

+83
-7
lines changed

4 files changed

+83
-7
lines changed

shell/common/BUILD.gn

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,5 +328,13 @@ if (enable_unittests) {
328328
deps += [ "//third_party/swiftshader" ]
329329
}
330330
}
331+
332+
if (shell_enable_gl) {
333+
deps += [
334+
"//third_party/angle:libEGL_static",
335+
"//third_party/angle:libGLESv2_static",
336+
"//third_party/swiftshader",
337+
]
338+
}
331339
}
332340
}

shell/common/fixtures/shell_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ void scene_with_red_box() {
354354
PlatformDispatcher.instance.scheduleFrame();
355355
}
356356

357+
@pragma('vm:external-name', 'NativeOnBeforeToImageSync')
358+
external void onBeforeToImageSync();
359+
357360

358361
@pragma('vm:entry-point')
359362
Future<void> toImageSync() async {
@@ -362,6 +365,7 @@ Future<void> toImageSync() async {
362365
canvas.drawPaint(Paint()..color = const Color(0xFFAAAAAA));
363366
final Picture picture = recorder.endRecording();
364367

368+
onBeforeToImageSync();
365369
final Image image = picture.toImageSync(20, 25);
366370
void expect(Object? a, Object? b) {
367371
if (a != b) {

shell/common/rasterizer.cc

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,24 +289,27 @@ std::unique_ptr<Rasterizer::GpuImageResult> Rasterizer::MakeSkiaGpuImage(
289289
TRACE_EVENT0("flutter", "Rasterizer::MakeGpuImage");
290290
FML_DCHECK(display_list);
291291

292-
// TODO(dnfield): the Linux embedding is in a rough state right now and
293-
// I can't seem to get the GPU path working on it.
294-
// https://github.com/flutter/flutter/issues/108835
295-
#if FML_OS_LINUX
296-
return MakeBitmapImage(display_list, image_info);
297-
#endif
298-
299292
std::unique_ptr<SnapshotDelegate::GpuImageResult> result;
300293
delegate_.GetIsGpuDisabledSyncSwitch()->Execute(
301294
fml::SyncSwitch::Handlers()
302295
.SetIfTrue([&result, &image_info, &display_list] {
296+
// TODO(dnfield): This isn't safe if display_list contains any GPU
297+
// resources like an SkImage_gpu.
303298
result = MakeBitmapImage(display_list, image_info);
304299
})
305300
.SetIfFalse([&result, &image_info, &display_list,
306301
surface = surface_.get(),
307302
gpu_image_behavior = gpu_image_behavior_] {
308303
if (!surface ||
309304
gpu_image_behavior == MakeGpuImageBehavior::kBitmap) {
305+
// TODO(dnfield): This isn't safe if display_list contains any GPU
306+
// resources like an SkImage_gpu.
307+
result = MakeBitmapImage(display_list, image_info);
308+
return;
309+
}
310+
311+
auto context_switch = surface->MakeRenderContextCurrent();
312+
if (!context_switch->GetResult()) {
310313
result = MakeBitmapImage(display_list, image_info);
311314
return;
312315
}

shell/common/shell_unittests.cc

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#include <utility>
1212
#include <vector>
1313

14+
#if SHELL_ENABLE_GL
15+
#include <EGL/egl.h>
16+
#endif // SHELL_ENABLE_GL
17+
1418
#include "assets/directory_asset_bundle.h"
1519
#include "common/graphics/persistent_cache.h"
1620
#include "flutter/flow/layers/backdrop_filter_layer.h"
@@ -3890,6 +3894,11 @@ TEST_F(ShellTest, PictureToImageSync) {
38903894
ShellTestPlatformView::BackendType::kGLBackend //
38913895
);
38923896

3897+
AddNativeCallback("NativeOnBeforeToImageSync",
3898+
CREATE_NATIVE_ENTRY([&](auto args) {
3899+
// nop
3900+
}));
3901+
38933902
fml::CountDownLatch latch(2);
38943903
AddNativeCallback("NotifyNative", CREATE_NATIVE_ENTRY([&](auto args) {
38953904
// Teardown and set up rasterizer again.
@@ -3912,6 +3921,58 @@ TEST_F(ShellTest, PictureToImageSync) {
39123921
DestroyShell(std::move(shell));
39133922
}
39143923

3924+
#if SHELL_ENABLE_GL
3925+
// This test uses the GL backend and refers to symbols in egl.h
3926+
TEST_F(ShellTest, PictureToImageSyncWithTrampledContext) {
3927+
// make it easier to trample the GL context by running on a single task
3928+
// runner.
3929+
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
3930+
ThreadHost::Type::Platform);
3931+
auto task_runner = thread_host.platform_thread->GetTaskRunner();
3932+
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
3933+
task_runner);
3934+
3935+
auto settings = CreateSettingsForFixture();
3936+
std::unique_ptr<Shell> shell =
3937+
CreateShell(settings, //
3938+
task_runners, //
3939+
false, //
3940+
nullptr, //
3941+
false, //
3942+
ShellTestPlatformView::BackendType::kGLBackend //
3943+
);
3944+
3945+
AddNativeCallback(
3946+
"NativeOnBeforeToImageSync", CREATE_NATIVE_ENTRY([&](auto args) {
3947+
// Trample the GL context. If the rasterizer fails
3948+
// to make the right one current again, test will
3949+
// fail.
3950+
::eglMakeCurrent(::eglGetCurrentDisplay(), NULL, NULL, NULL);
3951+
}));
3952+
3953+
fml::CountDownLatch latch(2);
3954+
AddNativeCallback("NotifyNative", CREATE_NATIVE_ENTRY([&](auto args) {
3955+
// Teardown and set up rasterizer again.
3956+
PlatformViewNotifyDestroyed(shell.get());
3957+
PlatformViewNotifyCreated(shell.get());
3958+
latch.CountDown();
3959+
}));
3960+
3961+
ASSERT_NE(shell, nullptr);
3962+
ASSERT_TRUE(shell->IsSetup());
3963+
auto configuration = RunConfiguration::InferFromSettings(settings);
3964+
PlatformViewNotifyCreated(shell.get());
3965+
configuration.SetEntrypoint("toImageSync");
3966+
RunEngine(shell.get(), std::move(configuration));
3967+
PumpOneFrame(shell.get());
3968+
3969+
latch.Wait();
3970+
3971+
PlatformViewNotifyDestroyed(shell.get());
3972+
DestroyShell(std::move(shell), task_runners);
3973+
}
3974+
#endif // SHELL_ENABLE_GL
3975+
39153976
TEST_F(ShellTest, PluginUtilitiesCallbackHandleErrorHandling) {
39163977
auto settings = CreateSettingsForFixture();
39173978
std::unique_ptr<Shell> shell =

0 commit comments

Comments
 (0)