blob: 8063349511d34e804ac384918be7fb2ab881f052 [file] [log] [blame]
Robert Phillipsad8a43f2017-08-30 12:06:35 -04001/*
2 * Copyright 2017 Google Inc.
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
8#include "SkDeferredDisplayListRecorder.h"
Brian Salomoncdd8a0a2019-01-10 12:09:52 -05009#include "SkMessageBus.h"
Robert Phillipsad8a43f2017-08-30 12:06:35 -040010#include "SkDeferredDisplayList.h"
Robert Phillipse42edcc2017-12-13 11:50:22 -050011#include "SkSurface.h"
12#include "SkSurfaceCharacterization.h"
Robert Phillipsad8a43f2017-08-30 12:06:35 -040013
Robert Phillips6ceaafa2018-03-15 16:53:06 -040014#if !SK_SUPPORT_GPU
15SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(const SkSurfaceCharacterization&) {}
16
17SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() {}
18
19bool SkDeferredDisplayListRecorder::init() { return false; }
20
21SkCanvas* SkDeferredDisplayListRecorder::getCanvas() { return nullptr; }
22
23std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() { return nullptr; }
24
25sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture(
26 const GrBackendFormat& backendFormat,
27 int width,
28 int height,
29 GrMipMapped mipMapped,
30 GrSurfaceOrigin origin,
31 SkColorType colorType,
32 SkAlphaType alphaType,
33 sk_sp<SkColorSpace> colorSpace,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -050034 PromiseImageTextureFulfillProc textureFulfillProc,
35 PromiseImageTextureReleaseProc textureReleaseProc,
36 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon7d88f312019-02-28 10:03:03 -050037 PromiseImageTextureContext textureContext) {
Brian Salomoncdd8a0a2019-01-10 12:09:52 -050038 return nullptr;
39}
40
Robert Phillipse8e2bb12018-09-27 14:26:47 -040041sk_sp<SkImage> SkDeferredDisplayListRecorder::makeYUVAPromiseTexture(
Brian Salomoncdd8a0a2019-01-10 12:09:52 -050042 SkYUVColorSpace yuvColorSpace,
43 const GrBackendFormat yuvaFormats[],
44 const SkISize yuvaSizes[],
45 const SkYUVAIndex yuvaIndices[4],
46 int imageWidth,
47 int imageHeight,
48 GrSurfaceOrigin imageOrigin,
49 sk_sp<SkColorSpace> imageColorSpace,
50 PromiseImageTextureFulfillProc textureFulfillProc,
51 PromiseImageTextureReleaseProc textureReleaseProc,
52 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon7d88f312019-02-28 10:03:03 -050053 PromiseImageTextureContext textureContexts[]) {
Brian Salomoncdd8a0a2019-01-10 12:09:52 -050054 return nullptr;
55}
56
Robert Phillips6ceaafa2018-03-15 16:53:06 -040057#else
58
59#include "GrContextPriv.h"
60#include "GrProxyProvider.h"
Robert Phillips79730ac2018-09-25 10:40:04 -040061#include "GrRenderTargetContext.h"
Robert Phillips6ceaafa2018-03-15 16:53:06 -040062#include "GrTexture.h"
Robert Phillips6ceaafa2018-03-15 16:53:06 -040063#include "SkGr.h"
64#include "SkImage_Gpu.h"
Jim Van Verth21bd60d2018-10-12 15:00:20 -040065#include "SkImage_GpuYUVA.h"
Brian Salomoncdd8a0a2019-01-10 12:09:52 -050066#include "SkMakeUnique.h"
67#include "SkPromiseImageTexture.h"
Robert Phillips6ceaafa2018-03-15 16:53:06 -040068#include "SkSurface_Gpu.h"
Jim Van Verthe24b5872018-10-29 16:26:02 -040069#include "SkYUVASizeInfo.h"
Robert Phillips6ceaafa2018-03-15 16:53:06 -040070
71SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(const SkSurfaceCharacterization& c)
72 : fCharacterization(c) {
73 if (fCharacterization.isValid()) {
74 fContext = GrContextPriv::MakeDDL(fCharacterization.refContextInfo());
75 }
Robert Phillipsad8a43f2017-08-30 12:06:35 -040076}
77
Robert Phillips62000362018-02-01 09:10:04 -050078SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -040079 if (fContext) {
Robert Phillips9da87e02019-02-04 13:26:26 -050080 auto proxyProvider = fContext->priv().proxyProvider();
Robert Phillips62000362018-02-01 09:10:04 -050081
Robert Phillips0790f8a2018-09-18 13:11:03 -040082 // This allows the uniquely keyed proxies to keep their keys but removes their back
83 // pointer to the about-to-be-deleted proxy provider. The proxies will use their
84 // unique key to reattach to cached versions of themselves or to appropriately tag new
85 // resources (if a cached version was not found). This system operates independent of
86 // the replaying context's proxy provider (i.e., these uniquely keyed proxies will not
87 // appear in the replaying proxy providers uniquely keyed proxy map). This should be fine
88 // since no one else should be trying to reconnect to the orphaned proxies and orphaned
89 // proxies from different DDLs that share the same key should simply reconnect to the
90 // same cached resource.
91 proxyProvider->orphanAllUniqueKeys();
Robert Phillips6ceaafa2018-03-15 16:53:06 -040092 }
Robert Phillips62000362018-02-01 09:10:04 -050093}
94
95
Robert Phillipse42edcc2017-12-13 11:50:22 -050096bool SkDeferredDisplayListRecorder::init() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -040097 SkASSERT(fContext);
98 SkASSERT(!fLazyProxyData);
Robert Phillipse42edcc2017-12-13 11:50:22 -050099 SkASSERT(!fSurface);
100
Robert Phillipsfc711a22018-02-13 17:03:00 -0500101 if (!fCharacterization.isValid()) {
102 return false;
103 }
104
Robert Phillips62000362018-02-01 09:10:04 -0500105 fLazyProxyData = sk_sp<SkDeferredDisplayList::LazyProxyData>(
106 new SkDeferredDisplayList::LazyProxyData);
Robert Phillipse42edcc2017-12-13 11:50:22 -0500107
Robert Phillips9da87e02019-02-04 13:26:26 -0500108 auto proxyProvider = fContext->priv().proxyProvider();
Robert Phillipse42edcc2017-12-13 11:50:22 -0500109
Greg Daniela070ed72018-04-26 16:31:38 -0400110 bool usesGLFBO0 = fCharacterization.usesGLFBO0();
111 if (usesGLFBO0) {
Robert Phillips4217ea72019-01-30 13:08:28 -0500112 if (GrBackendApi::kOpenGL != fContext->backend() ||
Greg Daniela070ed72018-04-26 16:31:38 -0400113 fCharacterization.isTextureable()) {
114 return false;
115 }
116 }
117
Greg Danielb085fa92019-03-05 16:55:12 -0500118 if (fCharacterization.vulkanSecondaryCBCompatible()) {
119 // Because of the restrictive API allowed for a GrVkSecondaryCBDrawContext, we know ahead
120 // of time that we don't be able to support certain parameter combinations. Specifially we
121 // fail on usesGLFBO0 since we can't mix GL and Vulkan. We can't have a texturable object.
122 // And finally the GrVkSecondaryCBDrawContext always assumes a top left origin.
123 if (usesGLFBO0 ||
124 fCharacterization.isTextureable() ||
125 fCharacterization.origin() == kBottomLeft_GrSurfaceOrigin) {
126 return false;
127 }
128 }
129
Robert Phillips62000362018-02-01 09:10:04 -0500130 GrSurfaceDesc desc;
131 desc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillips62000362018-02-01 09:10:04 -0500132 desc.fWidth = fCharacterization.width();
133 desc.fHeight = fCharacterization.height();
134 desc.fConfig = fCharacterization.config();
135 desc.fSampleCnt = fCharacterization.stencilCount();
136
137 sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData;
138
139 // What we're doing here is we're creating a lazy proxy to back the SkSurface. The lazy
Robert Phillipse8fabb22018-02-04 14:33:21 -0500140 // proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the
Robert Phillips62000362018-02-01 09:10:04 -0500141 // DDL is being replayed into.
142
Robert Phillipsabf7b762018-03-21 12:13:37 -0400143 GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone;
Robert Phillips9da87e02019-02-04 13:26:26 -0500144 if (fContext->priv().caps()->usesMixedSamples() && desc.fSampleCnt > 1 && !usesGLFBO0) {
Greg Daniela070ed72018-04-26 16:31:38 -0400145 // In GL, FBO 0 never supports mixed samples
Robert Phillipsabf7b762018-03-21 12:13:37 -0400146 surfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
147 }
Greg Daniela070ed72018-04-26 16:31:38 -0400148 if (usesGLFBO0) {
149 surfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0;
150 }
Brian Salomon7226c232018-07-30 13:13:17 -0400151 static constexpr GrProxyProvider::TextureInfo kTextureInfo{GrMipMapped::kNo,
152 GrTextureType::k2D};
153 const GrProxyProvider::TextureInfo* optionalTextureInfo = nullptr;
154 if (fCharacterization.isTextureable()) {
155 optionalTextureInfo = &kTextureInfo;
156 }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400157
Robert Phillips9da87e02019-02-04 13:26:26 -0500158 const GrBackendFormat format = fContext->priv().caps()->getBackendFormatFromColorType(
Greg Daniel4065d452018-11-16 15:43:41 -0500159 fCharacterization.colorType());
160
Robert Phillipse8fabb22018-02-04 14:33:21 -0500161 sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
Brian Salomonf7778972018-03-08 10:13:17 -0500162 [lazyProxyData](GrResourceProvider* resourceProvider) {
Robert Phillips83373a82018-02-14 07:35:32 -0500163 if (!resourceProvider) {
164 return sk_sp<GrSurface>();
165 }
Robert Phillips62000362018-02-01 09:10:04 -0500166
Robert Phillips83373a82018-02-14 07:35:32 -0500167 // The proxy backing the destination surface had better have been instantiated
168 // prior to the proxy backing the DLL's surface. Steal its GrRenderTarget.
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400169 SkASSERT(lazyProxyData->fReplayDest->peekSurface());
170 return sk_ref_sp<GrSurface>(lazyProxyData->fReplayDest->peekSurface());
Robert Phillips83373a82018-02-14 07:35:32 -0500171 },
Greg Daniel4065d452018-11-16 15:43:41 -0500172 format,
Robert Phillips83373a82018-02-14 07:35:32 -0500173 desc,
Robert Phillipsc7c2baf2018-03-08 09:51:04 -0500174 fCharacterization.origin(),
Robert Phillipsabf7b762018-03-21 12:13:37 -0400175 surfaceFlags,
Brian Salomon7226c232018-07-30 13:13:17 -0400176 optionalTextureInfo,
Robert Phillips83373a82018-02-14 07:35:32 -0500177 SkBackingFit::kExact,
Greg Danielb085fa92019-03-05 16:55:12 -0500178 SkBudgeted::kYes,
179 fCharacterization.vulkanSecondaryCBCompatible());
Robert Phillips62000362018-02-01 09:10:04 -0500180
Robert Phillips9da87e02019-02-04 13:26:26 -0500181 sk_sp<GrSurfaceContext> c = fContext->priv().makeWrappedSurfaceContext(
Robert Phillips62000362018-02-01 09:10:04 -0500182 std::move(proxy),
183 fCharacterization.refColorSpace(),
184 &fCharacterization.surfaceProps());
185 fSurface = SkSurface_Gpu::MakeWrappedRenderTarget(fContext.get(),
186 sk_ref_sp(c->asRenderTargetContext()));
Robert Phillipse42edcc2017-12-13 11:50:22 -0500187 return SkToBool(fSurface.get());
188}
189
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400190SkCanvas* SkDeferredDisplayListRecorder::getCanvas() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400191 if (!fContext) {
192 return nullptr;
193 }
194
195 if (!fSurface && !this->init()) {
196 return nullptr;
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400197 }
198
199 return fSurface->getCanvas();
200}
201
202std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() {
Robert Phillipsb67edbd2018-12-18 12:45:00 +0000203 if (!fContext) {
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400204 return nullptr;
205 }
206
Robert Phillipsf54883c2018-12-18 08:29:09 -0500207 if (fSurface) {
208 SkCanvas* canvas = fSurface->getCanvas();
209
210 canvas->restoreToCount(0);
211 }
212
Robert Phillips62000362018-02-01 09:10:04 -0500213 auto ddl = std::unique_ptr<SkDeferredDisplayList>(
214 new SkDeferredDisplayList(fCharacterization, std::move(fLazyProxyData)));
215
Robert Phillips9da87e02019-02-04 13:26:26 -0500216 fContext->priv().moveOpListsToDDL(ddl.get());
Robert Phillipsf54883c2018-12-18 08:29:09 -0500217
218 // We want a new lazy proxy target for each recorded DDL so force the (lazy proxy-backed)
219 // SkSurface to be regenerated for each DDL.
220 fSurface = nullptr;
Robert Phillips62000362018-02-01 09:10:04 -0500221 return ddl;
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400222}
223
Greg Daniela8d92112018-03-09 12:05:04 -0500224sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture(
225 const GrBackendFormat& backendFormat,
226 int width,
227 int height,
228 GrMipMapped mipMapped,
229 GrSurfaceOrigin origin,
230 SkColorType colorType,
231 SkAlphaType alphaType,
232 sk_sp<SkColorSpace> colorSpace,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500233 PromiseImageTextureFulfillProc textureFulfillProc,
234 PromiseImageTextureReleaseProc textureReleaseProc,
235 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon7d88f312019-02-28 10:03:03 -0500236 PromiseImageTextureContext textureContext) {
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400237 if (!fContext) {
238 return nullptr;
239 }
240
Greg Daniela8d92112018-03-09 12:05:04 -0500241 return SkImage_Gpu::MakePromiseTexture(fContext.get(),
242 backendFormat,
243 width,
244 height,
245 mipMapped,
246 origin,
247 colorType,
248 alphaType,
Kevin Lubickb5502b22018-03-12 10:17:06 -0400249 std::move(colorSpace),
Greg Daniela8d92112018-03-09 12:05:04 -0500250 textureFulfillProc,
251 textureReleaseProc,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500252 textureDoneProc,
Brian Salomon7d88f312019-02-28 10:03:03 -0500253 textureContext);
Greg Daniela8d92112018-03-09 12:05:04 -0500254}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400255
Robert Phillipse8e2bb12018-09-27 14:26:47 -0400256sk_sp<SkImage> SkDeferredDisplayListRecorder::makeYUVAPromiseTexture(
257 SkYUVColorSpace yuvColorSpace,
258 const GrBackendFormat yuvaFormats[],
Jim Van Verthf9f07352018-10-24 10:32:20 -0400259 const SkISize yuvaSizes[],
Robert Phillipse8e2bb12018-09-27 14:26:47 -0400260 const SkYUVAIndex yuvaIndices[4],
261 int imageWidth,
262 int imageHeight,
263 GrSurfaceOrigin imageOrigin,
264 sk_sp<SkColorSpace> imageColorSpace,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500265 PromiseImageTextureFulfillProc textureFulfillProc,
266 PromiseImageTextureReleaseProc textureReleaseProc,
267 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon7d88f312019-02-28 10:03:03 -0500268 PromiseImageTextureContext textureContexts[]) {
Robert Phillipse8e2bb12018-09-27 14:26:47 -0400269 if (!fContext) {
270 return nullptr;
271 }
272
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400273 return SkImage_GpuYUVA::MakePromiseYUVATexture(fContext.get(),
274 yuvColorSpace,
275 yuvaFormats,
Jim Van Verthf9f07352018-10-24 10:32:20 -0400276 yuvaSizes,
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400277 yuvaIndices,
Jim Van Verthcea39022018-10-12 16:15:34 -0400278 imageWidth,
279 imageHeight,
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400280 imageOrigin,
281 std::move(imageColorSpace),
282 textureFulfillProc,
283 textureReleaseProc,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500284 textureDoneProc,
Brian Salomon7d88f312019-02-28 10:03:03 -0500285 textureContexts);
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400286}
287
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400288#endif