未验证 提交 53759037 编写于 作者: G George Wright 提交者: GitHub

Ensure we use the base CompositorContext's AcquireFrame method when screenshotting (#13934)

This ensures we rasterize into the canvas passed in as subclasses may reimplement AcquireFrame in different ways that don't utilize the canvas object passed in (such as Fuchsia's flutter_runner::CompositorContext).
上级 115f57ee
......@@ -503,6 +503,7 @@ FILE: ../../../flutter/shell/common/canvas_spy_unittests.cc
FILE: ../../../flutter/shell/common/engine.cc
FILE: ../../../flutter/shell/common/engine.h
FILE: ../../../flutter/shell/common/fixtures/shell_test.dart
FILE: ../../../flutter/shell/common/fixtures/shelltest_screenshot.png
FILE: ../../../flutter/shell/common/input_events_unittests.cc
FILE: ../../../flutter/shell/common/isolate_configuration.cc
FILE: ../../../flutter/shell/common/isolate_configuration.h
......
......@@ -153,6 +153,8 @@ if (current_toolchain == host_toolchain) {
test_fixtures("shell_unittests_fixtures") {
dart_main = "fixtures/shell_test.dart"
fixtures = [ "fixtures/shelltest_screenshot.png" ]
}
shell_host_executable("shell_unittests") {
......
......@@ -399,9 +399,14 @@ static sk_sp<SkData> ScreenshotLayerTreeAsImage(
SkMatrix root_surface_transformation;
root_surface_transformation.reset();
auto frame = compositor_context.AcquireFrame(surface_context, canvas, nullptr,
root_surface_transformation,
false, nullptr);
// We want to ensure we call the base method for
// CompositorContext::AcquireFrame instead of the platform-specific method.
// Specifically, Fuchsia's CompositorContext handles the rendering surface
// itself which means that we will still continue to render to the onscreen
// surface if we don't call the base method.
auto frame = compositor_context.flutter::CompositorContext::AcquireFrame(
surface_context, canvas, nullptr, root_surface_transformation, false,
nullptr);
canvas->clear(SK_ColorTRANSPARENT);
frame->Raster(*tree, true);
canvas->flush();
......
......@@ -10,6 +10,7 @@
#include <memory>
#include "flutter/flow/layers/layer_tree.h"
#include "flutter/flow/layers/picture_layer.h"
#include "flutter/flow/layers/transform_layer.h"
#include "flutter/fml/command_line.h"
#include "flutter/fml/make_copyable.h"
......@@ -952,5 +953,66 @@ TEST_F(ShellTest, IsolateCanAccessPersistentIsolateData) {
DestroyShell(std::move(shell), std::move(task_runners));
}
TEST_F(ShellTest, Screenshot) {
auto settings = CreateSettingsForFixture();
fml::AutoResetWaitableEvent firstFrameLatch;
settings.frame_rasterized_callback =
[&firstFrameLatch](const FrameTiming& t) { firstFrameLatch.Signal(); };
std::unique_ptr<Shell> shell = CreateShell(settings);
// Create the surface needed by rasterizer
PlatformViewNotifyCreated(shell.get());
auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("emptyMain");
RunEngine(shell.get(), std::move(configuration));
LayerTreeBuilder builder = [&](std::shared_ptr<ContainerLayer> root) {
SkPictureRecorder recorder;
SkCanvas* recording_canvas =
recorder.beginRecording(SkRect::MakeXYWH(0, 0, 80, 80));
recording_canvas->drawRect(SkRect::MakeXYWH(0, 0, 80, 80),
SkPaint(SkColor4f::FromColor(SK_ColorRED)));
auto sk_picture = recorder.finishRecordingAsPicture();
fml::RefPtr<SkiaUnrefQueue> queue = fml::MakeRefCounted<SkiaUnrefQueue>(
this->GetCurrentTaskRunner(), fml::TimeDelta::FromSeconds(0));
auto picture_layer = std::make_shared<PictureLayer>(
SkPoint::Make(10, 10),
flutter::SkiaGPUObject<SkPicture>({sk_picture, queue}), false, false);
root->Add(picture_layer);
};
PumpOneFrame(shell.get(), 100, 100, builder);
firstFrameLatch.Wait();
std::promise<Rasterizer::Screenshot> screenshot_promise;
auto screenshot_future = screenshot_promise.get_future();
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetGPUTaskRunner(),
[&screenshot_promise, &shell]() {
auto rasterizer = shell->GetRasterizer();
screenshot_promise.set_value(rasterizer->ScreenshotLastLayerTree(
Rasterizer::ScreenshotType::CompressedImage, false));
});
auto fixtures_dir =
fml::OpenDirectory(GetFixturesPath(), false, fml::FilePermission::kRead);
auto reference_png = fml::FileMapping::CreateReadOnly(
fixtures_dir, "shelltest_screenshot.png");
// Use MakeWithoutCopy instead of MakeWithCString because we don't want to
// encode the null sentinel
sk_sp<SkData> reference_data = SkData::MakeWithoutCopy(
reference_png->GetMapping(), reference_png->GetSize());
ASSERT_TRUE(reference_data->equals(screenshot_future.get().data.get()));
DestroyShell(std::move(shell));
}
} // namespace testing
} // namespace flutter
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册