Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
snapshot_controller_skia.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/shell/common/snapshot_controller_skia.h"
6
8#include "flutter/flow/surface.h"
9#include "flutter/fml/trace_event.h"
10#include "flutter/shell/common/snapshot_controller.h"
14
15namespace flutter {
16
17namespace {
18sk_sp<SkImage> DrawSnapshot(
20 const std::function<void(SkCanvas*)>& draw_callback) {
21 if (surface == nullptr || surface->getCanvas() == nullptr) {
22 return nullptr;
23 }
24
25 draw_callback(surface->getCanvas());
26 auto dContext = GrAsDirectContext(surface->recordingContext());
27 if (dContext) {
28 dContext->flushAndSubmit();
29 }
30
31 sk_sp<SkImage> device_snapshot;
32 {
33 TRACE_EVENT0("flutter", "MakeDeviceSnapshot");
34 device_snapshot = surface->makeImageSnapshot();
35 }
36
37 if (device_snapshot == nullptr) {
38 return nullptr;
39 }
40
41 {
42 TRACE_EVENT0("flutter", "DeviceHostTransfer");
43 if (auto raster_image = device_snapshot->makeRasterImage()) {
44 return raster_image;
45 }
46 }
47
48 return nullptr;
49}
50} // namespace
51
52sk_sp<DlImage> SnapshotControllerSkia::DoMakeRasterSnapshot(
54 std::function<void(SkCanvas*)> draw_callback) {
55 TRACE_EVENT0("flutter", __FUNCTION__);
58 size.width(), size.height(), SkColorSpace::MakeSRGB());
59
60 std::unique_ptr<Surface> pbuffer_surface;
61 Surface* snapshot_surface = nullptr;
62 auto& delegate = GetDelegate();
63 if (delegate.GetSurface() && delegate.GetSurface()->GetContext()) {
64 snapshot_surface = delegate.GetSurface().get();
65 } else if (delegate.GetSnapshotSurfaceProducer()) {
66 pbuffer_surface =
67 delegate.GetSnapshotSurfaceProducer()->CreateSnapshotSurface();
68 if (pbuffer_surface && pbuffer_surface->GetContext()) {
69 snapshot_surface = pbuffer_surface.get();
70 }
71 }
72
73 if (!snapshot_surface) {
74 // Raster surface is fine if there is no on screen surface. This might
75 // happen in case of software rendering.
76 sk_sp<SkSurface> sk_surface = SkSurfaces::Raster(image_info);
77 result = DrawSnapshot(sk_surface, draw_callback);
78 } else {
79 delegate.GetIsGpuDisabledSyncSwitch()->Execute(
81 .SetIfTrue([&] {
83 result = DrawSnapshot(surface, draw_callback);
84 })
85 .SetIfFalse([&] {
86 FML_DCHECK(snapshot_surface);
87 auto context_switch =
88 snapshot_surface->MakeRenderContextCurrent();
89 if (!context_switch->GetResult()) {
90 return;
91 }
92
93 GrRecordingContext* context = snapshot_surface->GetContext();
94 auto max_size = context->maxRenderTargetSize();
95 double scale_factor = std::min(
96 1.0, static_cast<double>(max_size) /
97 static_cast<double>(std::max(image_info.width(),
98 image_info.height())));
99
100 // Scale down the render target size to the max supported by the
101 // GPU if necessary. Exceeding the max would otherwise cause a
102 // null result.
103 if (scale_factor < 1.0) {
104 image_info = image_info.makeWH(
105 static_cast<double>(image_info.width()) * scale_factor,
106 static_cast<double>(image_info.height()) * scale_factor);
107 }
108
109 // When there is an on screen surface, we need a render target
110 // SkSurface because we want to access texture backed images.
111 sk_sp<SkSurface> sk_surface =
112 SkSurfaces::RenderTarget(context, // context
113 skgpu::Budgeted::kNo, // budgeted
114 image_info // image info
115 );
116 if (!sk_surface) {
118 << "DoMakeRasterSnapshot can not create GPU render target";
119 return;
120 }
121
122 sk_surface->getCanvas()->scale(scale_factor, scale_factor);
123 result = DrawSnapshot(sk_surface, draw_callback);
124 }));
125 }
126
127 // It is up to the caller to create a DlImageGPU version of this image
128 // if the result will interact with the UI thread.
129 return DlImage::Make(result);
130}
131
133 sk_sp<DisplayList> display_list,
134 SkISize size) {
135 return DoMakeRasterSnapshot(size, [display_list](SkCanvas* canvas) {
136 DlSkCanvasAdapter(canvas).DrawDisplayList(display_list);
137 });
138}
139
142 // If the rasterizer does not have a surface with a GrContext, then it will
143 // be unable to render a cross-context SkImage. The caller will need to
144 // create the raster image on the IO thread.
145 if (GetDelegate().GetSurface() == nullptr ||
146 GetDelegate().GetSurface()->GetContext() == nullptr) {
147 return nullptr;
148 }
149
150 if (image == nullptr) {
151 return nullptr;
152 }
153
154 SkISize image_size = image->dimensions();
155
156 auto result = DoMakeRasterSnapshot(
157 image_size, [image = std::move(image)](SkCanvas* canvas) {
158 canvas->drawImage(image, 0, 0);
159 });
160 return result->skia_image();
161}
162
164 const std::shared_ptr<impeller::RuntimeStage>& runtime_stage) {}
165
166} // namespace flutter
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
SK_API int maxRenderTargetSize() const
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
static sk_sp< SkColorSpace > MakeSRGB()
SkISize dimensions() const
Definition SkImage.h:297
static sk_sp< DlImage > Make(const SkImage *image)
Definition dl_image.cc:11
Backend implementation of |DlCanvas| for |SkCanvas|.
void DrawDisplayList(const sk_sp< DisplayList > display_list, SkScalar opacity=SK_Scalar1) override
void CacheRuntimeStage(const std::shared_ptr< impeller::RuntimeStage > &runtime_stage) override
virtual sk_sp< SkImage > ConvertToRasterImage(sk_sp< SkImage > image) override
sk_sp< DlImage > MakeRasterSnapshot(sk_sp< DisplayList > display_list, SkISize size) override
VkSurfaceKHR surface
Definition main.cc:49
sk_sp< SkImage > image
Definition examples.cpp:29
GAsyncResult * result
#define FML_LOG(severity)
Definition logging.h:82
#define FML_DCHECK(condition)
Definition logging.h:103
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
SkImageInfo makeWH(int newWidth, int newHeight) const
static SkImageInfo MakeN32Premul(int width, int height)
int width() const
int height() const
Represents the 2 code paths available when calling |SyncSwitchExecute|.
Definition sync_switch.h:35
#define ERROR(message)
#define TRACE_EVENT0(category_group, name)