blob: f45baa08d6528b41e03352654076158679585dfc [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkDeferredDisplayListRecorder.h"
Robert Phillips4d5594d2020-02-21 14:24:40 -05009
10#include "include/core/SkDeferredDisplayList.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkSurface.h"
12#include "include/core/SkSurfaceCharacterization.h"
Ben Wagner21bca282019-05-15 10:15:52 -040013#include "src/core/SkMessageBus.h"
Robert Phillipsad8a43f2017-08-30 12:06:35 -040014
Robert Phillips6ceaafa2018-03-15 16:53:06 -040015#if !SK_SUPPORT_GPU
16SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(const SkSurfaceCharacterization&) {}
17
18SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() {}
19
20bool SkDeferredDisplayListRecorder::init() { return false; }
21
22SkCanvas* SkDeferredDisplayListRecorder::getCanvas() { return nullptr; }
23
24std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() { return nullptr; }
25
26sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture(
27 const GrBackendFormat& backendFormat,
28 int width,
29 int height,
30 GrMipMapped mipMapped,
31 GrSurfaceOrigin origin,
32 SkColorType colorType,
33 SkAlphaType alphaType,
34 sk_sp<SkColorSpace> colorSpace,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -050035 PromiseImageTextureFulfillProc textureFulfillProc,
36 PromiseImageTextureReleaseProc textureReleaseProc,
37 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon0cc57542019-03-08 13:28:46 -050038 PromiseImageTextureContext textureContext,
39 PromiseImageApiVersion) {
Brian Salomoncdd8a0a2019-01-10 12:09:52 -050040 return nullptr;
41}
42
Robert Phillipse8e2bb12018-09-27 14:26:47 -040043sk_sp<SkImage> SkDeferredDisplayListRecorder::makeYUVAPromiseTexture(
Brian Salomoncdd8a0a2019-01-10 12:09:52 -050044 SkYUVColorSpace yuvColorSpace,
45 const GrBackendFormat yuvaFormats[],
46 const SkISize yuvaSizes[],
47 const SkYUVAIndex yuvaIndices[4],
48 int imageWidth,
49 int imageHeight,
50 GrSurfaceOrigin imageOrigin,
51 sk_sp<SkColorSpace> imageColorSpace,
52 PromiseImageTextureFulfillProc textureFulfillProc,
53 PromiseImageTextureReleaseProc textureReleaseProc,
54 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon0cc57542019-03-08 13:28:46 -050055 PromiseImageTextureContext textureContexts[],
56 PromiseImageApiVersion) {
Brian Salomoncdd8a0a2019-01-10 12:09:52 -050057 return nullptr;
58}
59
Robert Phillips6ceaafa2018-03-15 16:53:06 -040060#else
61
Mike Kleinc0bd9f92019-04-23 12:05:21 -050062#include "include/core/SkPromiseImageTexture.h"
63#include "include/core/SkYUVASizeInfo.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050064#include "src/gpu/GrContextPriv.h"
65#include "src/gpu/GrProxyProvider.h"
66#include "src/gpu/GrRenderTargetContext.h"
Greg Daniel456f9b52020-03-05 19:14:18 +000067#include "src/gpu/GrTexture.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050068#include "src/gpu/SkGr.h"
69#include "src/image/SkImage_Gpu.h"
70#include "src/image/SkImage_GpuYUVA.h"
71#include "src/image/SkSurface_Gpu.h"
Robert Phillips6ceaafa2018-03-15 16:53:06 -040072
73SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(const SkSurfaceCharacterization& c)
74 : fCharacterization(c) {
75 if (fCharacterization.isValid()) {
76 fContext = GrContextPriv::MakeDDL(fCharacterization.refContextInfo());
77 }
Robert Phillipsad8a43f2017-08-30 12:06:35 -040078}
79
Robert Phillips62000362018-02-01 09:10:04 -050080SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -040081 if (fContext) {
Robert Phillips9da87e02019-02-04 13:26:26 -050082 auto proxyProvider = fContext->priv().proxyProvider();
Robert Phillips62000362018-02-01 09:10:04 -050083
Robert Phillips0790f8a2018-09-18 13:11:03 -040084 // This allows the uniquely keyed proxies to keep their keys but removes their back
85 // pointer to the about-to-be-deleted proxy provider. The proxies will use their
86 // unique key to reattach to cached versions of themselves or to appropriately tag new
87 // resources (if a cached version was not found). This system operates independent of
88 // the replaying context's proxy provider (i.e., these uniquely keyed proxies will not
89 // appear in the replaying proxy providers uniquely keyed proxy map). This should be fine
90 // since no one else should be trying to reconnect to the orphaned proxies and orphaned
91 // proxies from different DDLs that share the same key should simply reconnect to the
92 // same cached resource.
93 proxyProvider->orphanAllUniqueKeys();
Robert Phillips6ceaafa2018-03-15 16:53:06 -040094 }
Robert Phillips62000362018-02-01 09:10:04 -050095}
96
97
Robert Phillipse42edcc2017-12-13 11:50:22 -050098bool SkDeferredDisplayListRecorder::init() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -040099 SkASSERT(fContext);
100 SkASSERT(!fLazyProxyData);
Robert Phillipse42edcc2017-12-13 11:50:22 -0500101 SkASSERT(!fSurface);
102
Robert Phillipsfc711a22018-02-13 17:03:00 -0500103 if (!fCharacterization.isValid()) {
104 return false;
105 }
106
Robert Phillips62000362018-02-01 09:10:04 -0500107 fLazyProxyData = sk_sp<SkDeferredDisplayList::LazyProxyData>(
108 new SkDeferredDisplayList::LazyProxyData);
Robert Phillipse42edcc2017-12-13 11:50:22 -0500109
Robert Phillips9da87e02019-02-04 13:26:26 -0500110 auto proxyProvider = fContext->priv().proxyProvider();
Robert Phillipsb2adbef2019-07-02 16:33:05 -0400111 const GrCaps* caps = fContext->priv().caps();
Robert Phillipse42edcc2017-12-13 11:50:22 -0500112
Greg Daniela070ed72018-04-26 16:31:38 -0400113 bool usesGLFBO0 = fCharacterization.usesGLFBO0();
114 if (usesGLFBO0) {
Robert Phillips4217ea72019-01-30 13:08:28 -0500115 if (GrBackendApi::kOpenGL != fContext->backend() ||
Greg Daniela070ed72018-04-26 16:31:38 -0400116 fCharacterization.isTextureable()) {
117 return false;
118 }
119 }
120
Greg Danielb085fa92019-03-05 16:55:12 -0500121 if (fCharacterization.vulkanSecondaryCBCompatible()) {
122 // Because of the restrictive API allowed for a GrVkSecondaryCBDrawContext, we know ahead
123 // of time that we don't be able to support certain parameter combinations. Specifially we
124 // fail on usesGLFBO0 since we can't mix GL and Vulkan. We can't have a texturable object.
125 // And finally the GrVkSecondaryCBDrawContext always assumes a top left origin.
126 if (usesGLFBO0 ||
127 fCharacterization.isTextureable() ||
128 fCharacterization.origin() == kBottomLeft_GrSurfaceOrigin) {
129 return false;
130 }
131 }
132
Greg Daniel627d0532019-07-08 16:48:14 -0400133 GrColorType grColorType = SkColorTypeToGrColorType(fCharacterization.colorType());
134
Robert Phillips62000362018-02-01 09:10:04 -0500135 sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData;
136
137 // 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 -0500138 // proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the
Robert Phillips62000362018-02-01 09:10:04 -0500139 // DDL is being replayed into.
140
Robert Phillipsabf7b762018-03-21 12:13:37 -0400141 GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone;
Greg Daniela070ed72018-04-26 16:31:38 -0400142 if (usesGLFBO0) {
Jim Van Verth5fab9092019-11-25 21:23:53 +0000143 surfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0;
Greg Daniela070ed72018-04-26 16:31:38 -0400144 }
Chris Dalton95d8ceb2019-07-30 11:17:59 -0600145 // FIXME: Why do we use GrMipMapped::kNo instead of SkSurfaceCharacterization::fIsMipMapped?
Brian Salomon7226c232018-07-30 13:13:17 -0400146 static constexpr GrProxyProvider::TextureInfo kTextureInfo{GrMipMapped::kNo,
147 GrTextureType::k2D};
148 const GrProxyProvider::TextureInfo* optionalTextureInfo = nullptr;
149 if (fCharacterization.isTextureable()) {
150 optionalTextureInfo = &kTextureInfo;
151 }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400152
Greg Danielce3ddaa2020-01-22 16:58:15 -0500153 GrSwizzle readSwizzle = caps->getReadSwizzle(fCharacterization.backendFormat(), grColorType);
154
Robert Phillipse8fabb22018-02-04 14:33:21 -0500155 sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
Brian Salomonf7778972018-03-08 10:13:17 -0500156 [lazyProxyData](GrResourceProvider* resourceProvider) {
Robert Phillips83373a82018-02-14 07:35:32 -0500157 // The proxy backing the destination surface had better have been instantiated
158 // prior to the proxy backing the DLL's surface. Steal its GrRenderTarget.
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400159 SkASSERT(lazyProxyData->fReplayDest->peekSurface());
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400160 auto surface = sk_ref_sp<GrSurface>(lazyProxyData->fReplayDest->peekSurface());
Brian Salomonbeb7f522019-08-30 16:19:42 -0400161 return GrSurfaceProxy::LazyCallbackResult(std::move(surface));
Robert Phillips83373a82018-02-14 07:35:32 -0500162 },
Robert Phillips0e0113d2019-07-03 10:16:37 -0400163 fCharacterization.backendFormat(),
Brian Salomona56a7462020-02-07 14:17:25 -0500164 fCharacterization.dimensions(),
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400165 fCharacterization.sampleCount(),
Robert Phillipsabf7b762018-03-21 12:13:37 -0400166 surfaceFlags,
Brian Salomon7226c232018-07-30 13:13:17 -0400167 optionalTextureInfo,
Chris Dalton95d8ceb2019-07-30 11:17:59 -0600168 GrMipMapsStatus::kNotAllocated,
Robert Phillips83373a82018-02-14 07:35:32 -0500169 SkBackingFit::kExact,
Greg Danielb085fa92019-03-05 16:55:12 -0500170 SkBudgeted::kYes,
Brian Salomone8a766b2019-07-19 14:24:36 -0400171 fCharacterization.isProtected(),
Brian Salomonbeb7f522019-08-30 16:19:42 -0400172 fCharacterization.vulkanSecondaryCBCompatible(),
173 GrSurfaceProxy::UseAllocator::kYes);
Robert Phillips62000362018-02-01 09:10:04 -0500174
Brian Salomon9d8cac82019-07-16 15:59:31 -0400175 if (!proxy) {
176 return false;
177 }
178
Brian Salomon982f5462020-03-30 12:52:33 -0400179 GrSwizzle writeSwizzle = caps->getWriteSwizzle(fCharacterization.backendFormat(), grColorType);
Greg Danielbfa19c42019-12-19 16:41:40 -0500180
Greg Daniel3912a4b2020-01-14 09:56:04 -0500181 GrSurfaceProxyView readView(proxy, fCharacterization.origin(), readSwizzle);
Brian Salomon8afde5f2020-04-01 16:22:00 -0400182 GrSurfaceProxyView writeView(std::move(proxy), fCharacterization.origin(), writeSwizzle);
Greg Daniel3912a4b2020-01-14 09:56:04 -0500183
184 auto rtc = std::make_unique<GrRenderTargetContext>(fContext.get(), std::move(readView),
Brian Salomon8afde5f2020-04-01 16:22:00 -0400185 std::move(writeView), grColorType,
Greg Danielbfa19c42019-12-19 16:41:40 -0500186 fCharacterization.refColorSpace(),
187 &fCharacterization.surfaceProps());
Brian Salomonbf6b9792019-08-21 09:38:10 -0400188 fSurface = SkSurface_Gpu::MakeWrappedRenderTarget(fContext.get(), std::move(rtc));
Robert Phillipse42edcc2017-12-13 11:50:22 -0500189 return SkToBool(fSurface.get());
190}
191
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400192SkCanvas* SkDeferredDisplayListRecorder::getCanvas() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400193 if (!fContext) {
194 return nullptr;
195 }
196
197 if (!fSurface && !this->init()) {
198 return nullptr;
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400199 }
200
201 return fSurface->getCanvas();
202}
203
204std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() {
Robert Phillipsb67edbd2018-12-18 12:45:00 +0000205 if (!fContext) {
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400206 return nullptr;
207 }
208
Robert Phillipsf54883c2018-12-18 08:29:09 -0500209 if (fSurface) {
210 SkCanvas* canvas = fSurface->getCanvas();
211
212 canvas->restoreToCount(0);
213 }
214
Robert Phillips62000362018-02-01 09:10:04 -0500215 auto ddl = std::unique_ptr<SkDeferredDisplayList>(
216 new SkDeferredDisplayList(fCharacterization, std::move(fLazyProxyData)));
217
Chris Dalton6b498102019-08-01 14:14:52 -0600218 fContext->priv().moveRenderTasksToDDL(ddl.get());
Robert Phillipsf54883c2018-12-18 08:29:09 -0500219
220 // We want a new lazy proxy target for each recorded DDL so force the (lazy proxy-backed)
221 // SkSurface to be regenerated for each DDL.
222 fSurface = nullptr;
Robert Phillips62000362018-02-01 09:10:04 -0500223 return ddl;
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400224}
225
Greg Daniela8d92112018-03-09 12:05:04 -0500226sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture(
227 const GrBackendFormat& backendFormat,
228 int width,
229 int height,
230 GrMipMapped mipMapped,
231 GrSurfaceOrigin origin,
232 SkColorType colorType,
233 SkAlphaType alphaType,
234 sk_sp<SkColorSpace> colorSpace,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500235 PromiseImageTextureFulfillProc textureFulfillProc,
236 PromiseImageTextureReleaseProc textureReleaseProc,
237 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500238 PromiseImageTextureContext textureContext,
239 PromiseImageApiVersion version) {
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400240 if (!fContext) {
241 return nullptr;
242 }
243
Greg Daniela8d92112018-03-09 12:05:04 -0500244 return SkImage_Gpu::MakePromiseTexture(fContext.get(),
245 backendFormat,
246 width,
247 height,
248 mipMapped,
249 origin,
250 colorType,
251 alphaType,
Kevin Lubickb5502b22018-03-12 10:17:06 -0400252 std::move(colorSpace),
Greg Daniela8d92112018-03-09 12:05:04 -0500253 textureFulfillProc,
254 textureReleaseProc,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500255 textureDoneProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500256 textureContext,
257 version);
Greg Daniela8d92112018-03-09 12:05:04 -0500258}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400259
Robert Phillipse8e2bb12018-09-27 14:26:47 -0400260sk_sp<SkImage> SkDeferredDisplayListRecorder::makeYUVAPromiseTexture(
261 SkYUVColorSpace yuvColorSpace,
262 const GrBackendFormat yuvaFormats[],
Jim Van Verthf9f07352018-10-24 10:32:20 -0400263 const SkISize yuvaSizes[],
Robert Phillipse8e2bb12018-09-27 14:26:47 -0400264 const SkYUVAIndex yuvaIndices[4],
265 int imageWidth,
266 int imageHeight,
267 GrSurfaceOrigin imageOrigin,
268 sk_sp<SkColorSpace> imageColorSpace,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500269 PromiseImageTextureFulfillProc textureFulfillProc,
270 PromiseImageTextureReleaseProc textureReleaseProc,
271 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500272 PromiseImageTextureContext textureContexts[],
273 PromiseImageApiVersion version) {
Robert Phillipse8e2bb12018-09-27 14:26:47 -0400274 if (!fContext) {
275 return nullptr;
276 }
277
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400278 return SkImage_GpuYUVA::MakePromiseYUVATexture(fContext.get(),
279 yuvColorSpace,
280 yuvaFormats,
Jim Van Verthf9f07352018-10-24 10:32:20 -0400281 yuvaSizes,
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400282 yuvaIndices,
Jim Van Verthcea39022018-10-12 16:15:34 -0400283 imageWidth,
284 imageHeight,
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400285 imageOrigin,
286 std::move(imageColorSpace),
287 textureFulfillProc,
288 textureReleaseProc,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500289 textureDoneProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500290 textureContexts,
291 version);
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400292}
293
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400294#endif