mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Make rasterizer screenshot work with gl_context_switch (flutter/engine#18850)
This commit is contained in:
parent
389517d57e
commit
c80477385d
@ -468,7 +468,7 @@ static sk_sp<SkSurface> CreateSnapshotSurface(GrContext* surface_context,
|
||||
return SkSurface::MakeRaster(image_info);
|
||||
}
|
||||
|
||||
static sk_sp<SkData> ScreenshotLayerTreeAsImage(
|
||||
sk_sp<SkData> Rasterizer::ScreenshotLayerTreeAsImage(
|
||||
flutter::LayerTree* tree,
|
||||
flutter::CompositorContext& compositor_context,
|
||||
GrContext* surface_context,
|
||||
@ -502,6 +502,15 @@ static sk_sp<SkData> ScreenshotLayerTreeAsImage(
|
||||
frame->Raster(*tree, true);
|
||||
canvas->flush();
|
||||
|
||||
// snapshot_surface->makeImageSnapshot needs the GL context to be set if the
|
||||
// render context is GL. frame->Raster() pops the gl context in platforms that
|
||||
// gl context switching are used. (For example, older iOS that uses GL) We
|
||||
// reset the GL context using the context switch.
|
||||
auto context_switch = surface_->MakeRenderContextCurrent();
|
||||
if (!context_switch->GetResult()) {
|
||||
FML_LOG(ERROR) << "Screenshot: unable to make image screenshot";
|
||||
return nullptr;
|
||||
}
|
||||
// Prepare an image from the surface, this image may potentially be on th GPU.
|
||||
auto potentially_gpu_snapshot = snapshot_surface->makeImageSnapshot();
|
||||
if (!potentially_gpu_snapshot) {
|
||||
@ -528,7 +537,6 @@ static sk_sp<SkData> ScreenshotLayerTreeAsImage(
|
||||
FML_LOG(ERROR) << "Screenshot: unable to obtain bitmap pixels";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SkData::MakeWithCopy(pixmap.addr32(), pixmap.computeByteSize());
|
||||
}
|
||||
|
||||
|
||||
@ -448,6 +448,12 @@ class Rasterizer final : public SnapshotDelegate {
|
||||
// |SnapshotDelegate|
|
||||
sk_sp<SkImage> ConvertToRasterImage(sk_sp<SkImage> image) override;
|
||||
|
||||
sk_sp<SkData> ScreenshotLayerTreeAsImage(
|
||||
flutter::LayerTree* tree,
|
||||
flutter::CompositorContext& compositor_context,
|
||||
GrContext* surface_context,
|
||||
bool compressed);
|
||||
|
||||
sk_sp<SkImage> DoMakeRasterSnapshot(
|
||||
SkISize size,
|
||||
std::function<void(SkCanvas*)> draw_callback);
|
||||
|
||||
@ -1222,5 +1222,68 @@ TEST_F(ShellTest, OnServiceProtocolGetSkSLsWorks) {
|
||||
fml::RemoveFilesInDirectory(temp_dir.fd());
|
||||
}
|
||||
|
||||
TEST_F(ShellTest, RasterizerScreenshot) {
|
||||
Settings settings = CreateSettingsForFixture();
|
||||
auto configuration = RunConfiguration::InferFromSettings(settings);
|
||||
auto task_runner = CreateNewThread();
|
||||
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
|
||||
task_runner);
|
||||
std::unique_ptr<Shell> shell =
|
||||
CreateShell(std::move(settings), std::move(task_runners));
|
||||
|
||||
ASSERT_TRUE(ValidateShell(shell.get()));
|
||||
PlatformViewNotifyCreated(shell.get());
|
||||
|
||||
RunEngine(shell.get(), std::move(configuration));
|
||||
|
||||
auto latch = std::make_shared<fml::AutoResetWaitableEvent>();
|
||||
|
||||
PumpOneFrame(shell.get());
|
||||
|
||||
fml::TaskRunner::RunNowOrPostTask(
|
||||
shell->GetTaskRunners().GetRasterTaskRunner(), [&shell, &latch]() {
|
||||
Rasterizer::Screenshot screenshot =
|
||||
shell->GetRasterizer()->ScreenshotLastLayerTree(
|
||||
Rasterizer::ScreenshotType::CompressedImage, true);
|
||||
EXPECT_NE(screenshot.data, nullptr);
|
||||
|
||||
latch->Signal();
|
||||
});
|
||||
latch->Wait();
|
||||
DestroyShell(std::move(shell), std::move(task_runners));
|
||||
}
|
||||
|
||||
TEST_F(ShellTest, RasterizerMakeRasterSnapshot) {
|
||||
Settings settings = CreateSettingsForFixture();
|
||||
auto configuration = RunConfiguration::InferFromSettings(settings);
|
||||
auto task_runner = CreateNewThread();
|
||||
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
|
||||
task_runner);
|
||||
std::unique_ptr<Shell> shell =
|
||||
CreateShell(std::move(settings), std::move(task_runners));
|
||||
|
||||
ASSERT_TRUE(ValidateShell(shell.get()));
|
||||
PlatformViewNotifyCreated(shell.get());
|
||||
|
||||
RunEngine(shell.get(), std::move(configuration));
|
||||
|
||||
auto latch = std::make_shared<fml::AutoResetWaitableEvent>();
|
||||
|
||||
PumpOneFrame(shell.get());
|
||||
|
||||
fml::TaskRunner::RunNowOrPostTask(
|
||||
shell->GetTaskRunners().GetRasterTaskRunner(), [&shell, &latch]() {
|
||||
SnapshotDelegate* delegate =
|
||||
reinterpret_cast<Rasterizer*>(shell->GetRasterizer().get());
|
||||
sk_sp<SkImage> image = delegate->MakeRasterSnapshot(
|
||||
SkPicture::MakePlaceholder({0, 0, 50, 50}), SkISize::Make(50, 50));
|
||||
EXPECT_NE(image, nullptr);
|
||||
|
||||
latch->Signal();
|
||||
});
|
||||
latch->Wait();
|
||||
DestroyShell(std::move(shell), std::move(task_runners));
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user