Add an SkPicture screenshot handler to the service protocol (flutter/engine#4284)

This will replace the one in the diagnostic server
This commit is contained in:
Jason Simmons
2017-10-26 14:35:26 -07:00
committed by GitHub
parent 2d897e227d
commit ea0e620ea1
2 changed files with 75 additions and 0 deletions

View File

@@ -122,6 +122,11 @@ void PlatformViewServiceProtocol::RegisterHook(bool running_precompiled_code) {
// Screenshot.
Dart_RegisterRootServiceRequestCallback(kScreenshotExtensionName, &Screenshot,
nullptr);
// SkPicture Screenshot.
Dart_RegisterRootServiceRequestCallback(kScreenshotSkpExtensionName,
&ScreenshotSkp, nullptr);
// The following set of service protocol extensions require debug build
if (running_precompiled_code) {
return;
@@ -316,6 +321,67 @@ void PlatformViewServiceProtocol::ScreenshotGpuTask(SkBitmap* bitmap) {
canvas->flush();
}
const char* PlatformViewServiceProtocol::kScreenshotSkpExtensionName =
"_flutter.screenshotSkp";
bool PlatformViewServiceProtocol::ScreenshotSkp(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object) {
fxl::AutoResetWaitableEvent latch;
sk_sp<SkPicture> picture;
blink::Threads::Gpu()->PostTask([&latch, &picture]() {
picture = ScreenshotSkpGpuTask();
latch.Signal();
});
latch.Wait();
SkDynamicMemoryWStream stream;
PngPixelSerializer serializer;
picture->serialize(&stream, &serializer);
sk_sp<SkData> skp_data(stream.detachAsData());
size_t b64_size =
SkBase64::Encode(skp_data->data(), skp_data->size(), nullptr);
SkAutoTMalloc<char> b64_data(b64_size);
SkBase64::Encode(skp_data->data(), skp_data->size(), b64_data.get());
std::stringstream response;
response << "{\"type\":\"ScreenshotSkp\","
<< "\"skp\":\"" << std::string{b64_data.get(), b64_size} << "\"}";
*json_object = strdup(response.str().c_str());
return true;
}
sk_sp<SkPicture> PlatformViewServiceProtocol::ScreenshotSkpGpuTask() {
std::vector<fxl::WeakPtr<Rasterizer>> rasterizers;
Shell::Shared().GetRasterizers(&rasterizers);
if (rasterizers.size() != 1)
return nullptr;
Rasterizer* rasterizer = rasterizers[0].get();
if (rasterizer == nullptr)
return nullptr;
flow::LayerTree* layer_tree = rasterizer->GetLastLayerTree();
if (layer_tree == nullptr)
return nullptr;
SkPictureRecorder recorder;
recorder.beginRecording(SkRect::MakeWH(layer_tree->frame_size().width(),
layer_tree->frame_size().height()));
flow::CompositorContext compositor_context(nullptr);
flow::CompositorContext::ScopedFrame frame = compositor_context.AcquireFrame(
nullptr, recorder.getRecordingCanvas(), false);
layer_tree->Raster(frame);
return recorder.finishRecordingAsPicture();
}
const char* PlatformViewServiceProtocol::kFlushUIThreadTasksExtensionName =
"_flutter.flushUIThreadTasks";

View File

@@ -48,6 +48,15 @@ class PlatformViewServiceProtocol {
const char** json_object);
static void ScreenshotGpuTask(SkBitmap* bitmap);
static const char* kScreenshotSkpExtensionName;
static bool ScreenshotSkp(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object);
static sk_sp<SkPicture> ScreenshotSkpGpuTask();
// This API should not be invoked by production code.
// It can potentially starve the service isolate if the main isolate pauses
// at a breakpoint or is in an infinite loop.