blob: 3d84aeb7bb06933212f0f20acf9166093f87ac8a [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"
9
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,
34 TextureFulfillProc textureFulfillProc,
35 TextureReleaseProc textureReleaseProc,
36 TextureContext textureContext) {
37 return nullptr;
38}
39
40#else
41
42#include "GrContextPriv.h"
43#include "GrProxyProvider.h"
44#include "GrTexture.h"
45
46#include "SkGr.h"
47#include "SkImage_Gpu.h"
48#include "SkSurface_Gpu.h"
49
50SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(const SkSurfaceCharacterization& c)
51 : fCharacterization(c) {
52 if (fCharacterization.isValid()) {
53 fContext = GrContextPriv::MakeDDL(fCharacterization.refContextInfo());
54 }
Robert Phillipsad8a43f2017-08-30 12:06:35 -040055}
56
Robert Phillips62000362018-02-01 09:10:04 -050057SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -040058 if (fContext) {
59 auto proxyProvider = fContext->contextPriv().proxyProvider();
Robert Phillips62000362018-02-01 09:10:04 -050060
Robert Phillips6ceaafa2018-03-15 16:53:06 -040061 // DDL TODO: Remove this. DDL contexts should allow for deletion while still having live
62 // uniquely keyed proxies.
63 proxyProvider->removeAllUniqueKeys();
64 }
Robert Phillips62000362018-02-01 09:10:04 -050065}
66
67
Robert Phillipse42edcc2017-12-13 11:50:22 -050068bool SkDeferredDisplayListRecorder::init() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -040069 SkASSERT(fContext);
70 SkASSERT(!fLazyProxyData);
Robert Phillipse42edcc2017-12-13 11:50:22 -050071 SkASSERT(!fSurface);
72
Robert Phillipsfc711a22018-02-13 17:03:00 -050073 if (!fCharacterization.isValid()) {
74 return false;
75 }
76
Robert Phillips62000362018-02-01 09:10:04 -050077 fLazyProxyData = sk_sp<SkDeferredDisplayList::LazyProxyData>(
78 new SkDeferredDisplayList::LazyProxyData);
Robert Phillipse42edcc2017-12-13 11:50:22 -050079
Robert Phillips62000362018-02-01 09:10:04 -050080 auto proxyProvider = fContext->contextPriv().proxyProvider();
Robert Phillipse42edcc2017-12-13 11:50:22 -050081
Robert Phillips62000362018-02-01 09:10:04 -050082 GrSurfaceDesc desc;
83 desc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillips62000362018-02-01 09:10:04 -050084 desc.fWidth = fCharacterization.width();
85 desc.fHeight = fCharacterization.height();
86 desc.fConfig = fCharacterization.config();
87 desc.fSampleCnt = fCharacterization.stencilCount();
88
89 sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData;
90
91 // 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 -050092 // proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the
Robert Phillips62000362018-02-01 09:10:04 -050093 // DDL is being replayed into.
94
Robert Phillipse8fabb22018-02-04 14:33:21 -050095 sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
Brian Salomonf7778972018-03-08 10:13:17 -050096 [lazyProxyData](GrResourceProvider* resourceProvider) {
Robert Phillips83373a82018-02-14 07:35:32 -050097 if (!resourceProvider) {
98 return sk_sp<GrSurface>();
99 }
Robert Phillips62000362018-02-01 09:10:04 -0500100
Robert Phillips83373a82018-02-14 07:35:32 -0500101 // The proxy backing the destination surface had better have been instantiated
102 // prior to the proxy backing the DLL's surface. Steal its GrRenderTarget.
103 SkASSERT(lazyProxyData->fReplayDest->priv().peekSurface());
104 return sk_ref_sp<GrSurface>(lazyProxyData->fReplayDest->priv().peekSurface());
105 },
106 desc,
Robert Phillipsc7c2baf2018-03-08 09:51:04 -0500107 fCharacterization.origin(),
Robert Phillipsfde6fa02018-03-02 08:53:14 -0500108 GrRenderTargetFlags::kNone,
Robert Phillips83373a82018-02-14 07:35:32 -0500109 GrProxyProvider::Textureable(fCharacterization.isTextureable()),
110 GrMipMapped::kNo,
111 SkBackingFit::kExact,
112 SkBudgeted::kYes);
Robert Phillips62000362018-02-01 09:10:04 -0500113
114 sk_sp<GrSurfaceContext> c = fContext->contextPriv().makeWrappedSurfaceContext(
115 std::move(proxy),
116 fCharacterization.refColorSpace(),
117 &fCharacterization.surfaceProps());
118 fSurface = SkSurface_Gpu::MakeWrappedRenderTarget(fContext.get(),
119 sk_ref_sp(c->asRenderTargetContext()));
Robert Phillipse42edcc2017-12-13 11:50:22 -0500120 return SkToBool(fSurface.get());
121}
122
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400123SkCanvas* SkDeferredDisplayListRecorder::getCanvas() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400124 if (!fContext) {
125 return nullptr;
126 }
127
128 if (!fSurface && !this->init()) {
129 return nullptr;
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400130 }
131
132 return fSurface->getCanvas();
133}
134
135std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() {
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400136 if (!fContext) {
137 return nullptr;
138 }
139
Robert Phillips62000362018-02-01 09:10:04 -0500140 auto ddl = std::unique_ptr<SkDeferredDisplayList>(
141 new SkDeferredDisplayList(fCharacterization, std::move(fLazyProxyData)));
142
143 fContext->contextPriv().moveOpListsToDDL(ddl.get());
144 return ddl;
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400145}
146
Greg Daniela8d92112018-03-09 12:05:04 -0500147sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture(
148 const GrBackendFormat& backendFormat,
149 int width,
150 int height,
151 GrMipMapped mipMapped,
152 GrSurfaceOrigin origin,
153 SkColorType colorType,
154 SkAlphaType alphaType,
155 sk_sp<SkColorSpace> colorSpace,
156 TextureFulfillProc textureFulfillProc,
157 TextureReleaseProc textureReleaseProc,
158 TextureContext textureContext) {
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400159 if (!fContext) {
160 return nullptr;
161 }
162
Greg Daniela8d92112018-03-09 12:05:04 -0500163 return SkImage_Gpu::MakePromiseTexture(fContext.get(),
164 backendFormat,
165 width,
166 height,
167 mipMapped,
168 origin,
169 colorType,
170 alphaType,
Kevin Lubickb5502b22018-03-12 10:17:06 -0400171 std::move(colorSpace),
Greg Daniela8d92112018-03-09 12:05:04 -0500172 textureFulfillProc,
173 textureReleaseProc,
174 textureContext);
Greg Daniela8d92112018-03-09 12:05:04 -0500175}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400176
177#endif