Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,9 @@ 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);
auto frame = compositor_context.flutter::CompositorContext::AcquireFrame(
Comment thread
gw280 marked this conversation as resolved.
surface_context, canvas, nullptr, root_surface_transformation, false,
nullptr);
canvas->clear(SK_ColorTRANSPARENT);
frame->Raster(*tree, true);
canvas->flush();
Expand Down
65 changes: 65 additions & 0 deletions shell/common/shell_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -952,5 +953,69 @@ TEST_F(ShellTest, IsolateCanAccessPersistentIsolateData) {
DestroyShell(std::move(shell), std::move(task_runners));
}

TEST_F(ShellTest, Screenshot) {
Comment thread
gw280 marked this conversation as resolved.
auto settings = CreateSettingsForFixture();
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);

fml::Status result =
shell->WaitForFirstFrame(fml::TimeDelta::FromMilliseconds(1000));
Comment thread
gw280 marked this conversation as resolved.
Outdated
ASSERT_TRUE(result.ok());

std::shared_ptr<fml::AutoResetWaitableEvent> latch =
Comment thread
gw280 marked this conversation as resolved.
Outdated
std::make_shared<fml::AutoResetWaitableEvent>();

Rasterizer::Screenshot screenshot;
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetGPUTaskRunner(), [&]() {
Comment thread
gw280 marked this conversation as resolved.
Outdated
auto rasterizer = shell->GetRasterizer();
screenshot = rasterizer->ScreenshotLastLayerTree(
Rasterizer::ScreenshotType::CompressedImage, true);
latch->Signal();
});
latch->Wait();

const char* reference_png =
Comment thread
gw280 marked this conversation as resolved.
Outdated
"iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAAAARzQklU"
"CAgICHwIZIgAAADpSURBVHic7dHBCcAwDARBOf337FQQSB6GJcy89Ti0MwAAAEDHenu4Z/"
"bJIX+"
"3Xv76Oj2EbwSJESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgS"
"JESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgS"
"JESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgSJESRGkBhBYgS"
"JESRGkBhBYgSJESRGkBhBYgSJEQQAAADg0Q0wHwKgbFGDCQAAAABJRU5ErkJggg==";
// Use MakeWithoutCopy instead of MakeWithCString because we don't want to
// encode the null sentinel
sk_sp<SkData> reference_data =
SkData::MakeWithoutCopy(reference_png, strlen(reference_png));

ASSERT_TRUE(reference_data->equals(screenshot.data.get()));
Comment thread
gw280 marked this conversation as resolved.
Outdated

DestroyShell(std::move(shell));
}

} // namespace testing
} // namespace flutter