Flutter Engine
The Flutter Engine
GrDeferredDisplayListRecorder.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
14#include "include/gpu/GrTypes.h"
29
30#include <functional>
31#include <utility>
32
34
36 : fCharacterization(c) {
37 if (fCharacterization.isValid()) {
39 }
40}
41
43 if (fContext) {
44 auto proxyProvider = fContext->priv().proxyProvider();
45
46 // This allows the uniquely keyed proxies to keep their keys but removes their back
47 // pointer to the about-to-be-deleted proxy provider. The proxies will use their
48 // unique key to reattach to cached versions of themselves or to appropriately tag new
49 // resources (if a cached version was not found). This system operates independent of
50 // the replaying context's proxy provider (i.e., these uniquely keyed proxies will not
51 // appear in the replaying proxy providers uniquely keyed proxy map). This should be fine
52 // since no one else should be trying to reconnect to the orphaned proxies and orphaned
53 // proxies from different DDLs that share the same key should simply reconnect to the
54 // same cached resource.
55 proxyProvider->orphanAllUniqueKeys();
56 }
57}
58
59bool GrDeferredDisplayListRecorder::init() {
61 SkASSERT(!fTargetProxy);
62 SkASSERT(!fLazyProxyData);
63 SkASSERT(!fSurface);
64
65 if (!fCharacterization.isValid()) {
66 return false;
67 }
68
70 new GrDeferredDisplayList::LazyProxyData);
71
72 auto proxyProvider = fContext->priv().proxyProvider();
73 const GrCaps* caps = fContext->priv().caps();
74
75 bool usesGLFBO0 = fCharacterization.usesGLFBO0();
76 if (usesGLFBO0) {
77 if (GrBackendApi::kOpenGL != fContext->backend() ||
78 fCharacterization.isTextureable()) {
79 return false;
80 }
81 }
82
83 bool vkRTSupportsInputAttachment = fCharacterization.vkRTSupportsInputAttachment();
84 if (vkRTSupportsInputAttachment && GrBackendApi::kVulkan != fContext->backend()) {
85 return false;
86 }
87
88 if (fCharacterization.vulkanSecondaryCBCompatible()) {
89 // Because of the restrictive API allowed for a GrVkSecondaryCBDrawContext, we know ahead
90 // of time that we don't be able to support certain parameter combinations. Specifically we
91 // fail on usesGLFBO0 since we can't mix GL and Vulkan. We can't have a texturable object.
92 // We can't use it as in input attachment since we don't control the render pass this will
93 // be played into and thus can't force it to have an input attachment and the correct
94 // dependencies. And finally the GrVkSecondaryCBDrawContext always assumes a top left
95 // origin.
96 if (usesGLFBO0 ||
97 vkRTSupportsInputAttachment ||
98 fCharacterization.isTextureable() ||
99 fCharacterization.origin() == kBottomLeft_GrSurfaceOrigin) {
100 return false;
101 }
102 }
103
104 GrColorType grColorType = SkColorTypeToGrColorType(fCharacterization.colorType());
105
106 // What we're doing here is we're creating a lazy proxy to back the SkSurface. The lazy
107 // proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the
108 // DDL is being replayed into.
109
111 if (usesGLFBO0) {
113 } else if (fCharacterization.sampleCount() > 1 && !caps->msaaResolvesAutomatically() &&
114 fCharacterization.isTextureable()) {
116 }
117
118 if (vkRTSupportsInputAttachment) {
120 }
121
122 // FIXME: Why do we use skgpu::Mipmapped::kNo instead of
123 // GrSurfaceCharacterization::fIsMipMapped?
124 static constexpr GrProxyProvider::TextureInfo kTextureInfo{skgpu::Mipmapped::kNo,
126 const GrProxyProvider::TextureInfo* optionalTextureInfo = nullptr;
127 if (fCharacterization.isTextureable()) {
128 optionalTextureInfo = &kTextureInfo;
129 }
130
131 fTargetProxy = proxyProvider->createLazyRenderTargetProxy(
132 [lazyProxyData = fLazyProxyData](GrResourceProvider* resourceProvider,
134 // The proxy backing the destination surface had better have been instantiated
135 // prior to this one (i.e., the proxy backing the DDL's surface).
136 // Fulfill this lazy proxy with the destination surface's GrRenderTarget.
137 SkASSERT(lazyProxyData->fReplayDest->peekSurface());
138 auto surface = sk_ref_sp<GrSurface>(lazyProxyData->fReplayDest->peekSurface());
140 },
141 fCharacterization.backendFormat(),
142 fCharacterization.dimensions(),
143 fCharacterization.sampleCount(),
144 surfaceFlags,
145 optionalTextureInfo,
149 fCharacterization.isProtected(),
150 fCharacterization.vulkanSecondaryCBCompatible(),
152
153 if (!fTargetProxy) {
154 return false;
155 }
156 fTargetProxy->priv().setIsDDLTarget();
157
158 auto device = fContext->priv().createDevice(grColorType,
159 fTargetProxy,
160 fCharacterization.refColorSpace(),
161 fCharacterization.origin(),
162 fCharacterization.surfaceProps(),
164 if (!device) {
165 return false;
166 }
167
168 fSurface = sk_make_sp<SkSurface_Ganesh>(std::move(device));
169 return SkToBool(fSurface.get());
170}
171
173 if (!fContext) {
174 return nullptr;
175 }
176
177 if (!fSurface && !this->init()) {
178 return nullptr;
179 }
180
181 return fSurface->getCanvas();
182}
183
185 if (!fContext || !fTargetProxy) {
186 return nullptr;
187 }
188
189 if (fSurface) {
190 SkCanvas* canvas = fSurface->getCanvas();
191
192 canvas->restoreToCount(0);
193 }
194
195 auto ddl = sk_sp<GrDeferredDisplayList>(new GrDeferredDisplayList(fCharacterization,
196 std::move(fTargetProxy),
197 std::move(fLazyProxyData)));
198
199 fContext->priv().moveRenderTasksToDDL(ddl.get());
200
201 // We want a new lazy proxy target for each recorded DDL so force the (lazy proxy-backed)
202 // SkSurface to be regenerated for each DDL.
203 fSurface = nullptr;
204 return ddl;
205}
GrColorType
Definition: GrTypesPriv.h:540
GrInternalSurfaceFlags
Definition: GrTypesPriv.h:436
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
Definition: GrTypesPriv.h:629
@ kBottomLeft_GrSurfaceOrigin
Definition: GrTypes.h:149
#define SkASSERT(cond)
Definition: SkAssert.h:116
const Context & fContext
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
Definition: GrCaps.h:57
bool msaaResolvesAutomatically() const
Definition: GrCaps.h:100
GrDeferredDisplayListRecorder(const GrSurfaceCharacterization &)
sk_sp< GrDeferredDisplayList > detach()
static sk_sp< GrRecordingContext > MakeDDL(sk_sp< GrContextThreadSafeProxy >)
const GrCaps * caps() const
sk_sp< GrContextThreadSafeProxy > refContextInfo() const
sk_sp< SkColorSpace > refColorSpace() const
GrSurfaceProxyPriv priv()
void restoreToCount(int saveCount)
Definition: SkCanvas.cpp:478
SkCanvas * getCanvas()
Definition: SkSurface.cpp:82
T * get() const
Definition: SkRefCnt.h:303
VkDevice device
Definition: main.cc:53
VkSurfaceKHR surface
Definition: main.cc:49
static bool init()