blob: aa7a1e1572114337a5f3c3d4178fe97a319fc9b6 [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
Greg Daniela8d92112018-03-09 12:05:04 -050010
Robert Phillipse42edcc2017-12-13 11:50:22 -050011#if SK_SUPPORT_GPU
12#include "GrContextPriv.h"
Robert Phillips62000362018-02-01 09:10:04 -050013#include "GrProxyProvider.h"
14#include "GrTexture.h"
15
16#include "SkGpuDevice.h"
Robert Phillipse42edcc2017-12-13 11:50:22 -050017#include "SkGr.h"
Greg Daniela8d92112018-03-09 12:05:04 -050018#include "SkImage_Gpu.h"
Robert Phillips62000362018-02-01 09:10:04 -050019#include "SkSurface_Gpu.h"
Robert Phillipse42edcc2017-12-13 11:50:22 -050020#endif
Robert Phillips8def8bf2017-11-30 08:46:03 -050021
Robert Phillipsad8a43f2017-08-30 12:06:35 -040022#include "SkCanvas.h" // TODO: remove
23#include "SkDeferredDisplayList.h"
Robert Phillipse42edcc2017-12-13 11:50:22 -050024#include "SkSurface.h"
25#include "SkSurfaceCharacterization.h"
Robert Phillipsad8a43f2017-08-30 12:06:35 -040026
27SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(
28 const SkSurfaceCharacterization& characterization)
29 : fCharacterization(characterization) {
30}
31
Robert Phillips62000362018-02-01 09:10:04 -050032SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() {
33#if SK_SUPPORT_GPU && !defined(SK_RASTER_RECORDER_IMPLEMENTATION)
34 auto proxyProvider = fContext->contextPriv().proxyProvider();
35
36 // DDL TODO: Remove this. DDL contexts should allow for deletion while still having live
37 // uniquely keyed proxies.
38 proxyProvider->removeAllUniqueKeys();
39#endif
40}
41
42
Robert Phillipse42edcc2017-12-13 11:50:22 -050043bool SkDeferredDisplayListRecorder::init() {
44 SkASSERT(!fSurface);
45
Robert Phillipsfc711a22018-02-13 17:03:00 -050046 if (!fCharacterization.isValid()) {
47 return false;
48 }
49
Robert Phillipse42edcc2017-12-13 11:50:22 -050050#ifdef SK_RASTER_RECORDER_IMPLEMENTATION
51 // Use raster right now to allow threading
52 const SkImageInfo ii = SkImageInfo::Make(fCharacterization.width(), fCharacterization.height(),
53 kN32_SkColorType, kOpaque_SkAlphaType,
54 fCharacterization.refColorSpace());
55
56 fSurface = SkSurface::MakeRaster(ii, &fCharacterization.surfaceProps());
Robert Phillips62000362018-02-01 09:10:04 -050057 return SkToBool(fSurface.get());
Robert Phillipse42edcc2017-12-13 11:50:22 -050058#else
Robert Phillips62000362018-02-01 09:10:04 -050059 SkASSERT(!fLazyProxyData);
60
61#if SK_SUPPORT_GPU
Robert Phillipse42edcc2017-12-13 11:50:22 -050062 if (!fContext) {
Robert Phillipsfde6fa02018-03-02 08:53:14 -050063 fContext = GrContextPriv::MakeDDL(fCharacterization.refContextInfo());
Robert Phillipse42edcc2017-12-13 11:50:22 -050064 if (!fContext) {
65 return false;
66 }
67 }
68
Robert Phillips62000362018-02-01 09:10:04 -050069 fLazyProxyData = sk_sp<SkDeferredDisplayList::LazyProxyData>(
70 new SkDeferredDisplayList::LazyProxyData);
Robert Phillipse42edcc2017-12-13 11:50:22 -050071
Robert Phillips62000362018-02-01 09:10:04 -050072 auto proxyProvider = fContext->contextPriv().proxyProvider();
Robert Phillipse42edcc2017-12-13 11:50:22 -050073
Robert Phillips62000362018-02-01 09:10:04 -050074 GrSurfaceDesc desc;
75 desc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillips62000362018-02-01 09:10:04 -050076 desc.fWidth = fCharacterization.width();
77 desc.fHeight = fCharacterization.height();
78 desc.fConfig = fCharacterization.config();
79 desc.fSampleCnt = fCharacterization.stencilCount();
80
81 sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData;
82
83 // 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 -050084 // proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the
Robert Phillips62000362018-02-01 09:10:04 -050085 // DDL is being replayed into.
86
Robert Phillipse8fabb22018-02-04 14:33:21 -050087 sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
Brian Salomonf7778972018-03-08 10:13:17 -050088 [lazyProxyData](GrResourceProvider* resourceProvider) {
Robert Phillips83373a82018-02-14 07:35:32 -050089 if (!resourceProvider) {
90 return sk_sp<GrSurface>();
91 }
Robert Phillips62000362018-02-01 09:10:04 -050092
Robert Phillips83373a82018-02-14 07:35:32 -050093 // The proxy backing the destination surface had better have been instantiated
94 // prior to the proxy backing the DLL's surface. Steal its GrRenderTarget.
95 SkASSERT(lazyProxyData->fReplayDest->priv().peekSurface());
96 return sk_ref_sp<GrSurface>(lazyProxyData->fReplayDest->priv().peekSurface());
97 },
98 desc,
Robert Phillipsc7c2baf2018-03-08 09:51:04 -050099 fCharacterization.origin(),
Robert Phillipsfde6fa02018-03-02 08:53:14 -0500100 GrRenderTargetFlags::kNone,
Robert Phillips83373a82018-02-14 07:35:32 -0500101 GrProxyProvider::Textureable(fCharacterization.isTextureable()),
102 GrMipMapped::kNo,
103 SkBackingFit::kExact,
104 SkBudgeted::kYes);
Robert Phillips62000362018-02-01 09:10:04 -0500105
106 sk_sp<GrSurfaceContext> c = fContext->contextPriv().makeWrappedSurfaceContext(
107 std::move(proxy),
108 fCharacterization.refColorSpace(),
109 &fCharacterization.surfaceProps());
110 fSurface = SkSurface_Gpu::MakeWrappedRenderTarget(fContext.get(),
111 sk_ref_sp(c->asRenderTargetContext()));
Robert Phillipse42edcc2017-12-13 11:50:22 -0500112 return SkToBool(fSurface.get());
Robert Phillips62000362018-02-01 09:10:04 -0500113#else
114 return false;
115#endif
116
117#endif
Robert Phillipse42edcc2017-12-13 11:50:22 -0500118}
119
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400120SkCanvas* SkDeferredDisplayListRecorder::getCanvas() {
121 if (!fSurface) {
Robert Phillipse42edcc2017-12-13 11:50:22 -0500122 if (!this->init()) {
123 return nullptr;
124 }
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400125 }
126
127 return fSurface->getCanvas();
128}
129
130std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() {
Robert Phillips62000362018-02-01 09:10:04 -0500131#ifdef SK_RASTER_RECORDER_IMPLEMENTATION
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400132 sk_sp<SkImage> img = fSurface->makeImageSnapshot();
133 fSurface.reset();
134
135 // TODO: need to wrap the opLists associated with the deferred draws
136 // in the SkDeferredDisplayList.
137 return std::unique_ptr<SkDeferredDisplayList>(
138 new SkDeferredDisplayList(fCharacterization, std::move(img)));
Robert Phillips62000362018-02-01 09:10:04 -0500139#else
140
141#if SK_SUPPORT_GPU
142 auto ddl = std::unique_ptr<SkDeferredDisplayList>(
143 new SkDeferredDisplayList(fCharacterization, std::move(fLazyProxyData)));
144
145 fContext->contextPriv().moveOpListsToDDL(ddl.get());
146 return ddl;
147#else
148 return nullptr;
149#endif
150
151#endif // SK_RASTER_RECORDER_IMPLEMENTATION
152
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400153}
154
Greg Daniela8d92112018-03-09 12:05:04 -0500155sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture(
156 const GrBackendFormat& backendFormat,
157 int width,
158 int height,
159 GrMipMapped mipMapped,
160 GrSurfaceOrigin origin,
161 SkColorType colorType,
162 SkAlphaType alphaType,
163 sk_sp<SkColorSpace> colorSpace,
164 TextureFulfillProc textureFulfillProc,
165 TextureReleaseProc textureReleaseProc,
166 TextureContext textureContext) {
Greg Daniel7946c0c2018-03-09 14:10:26 -0500167#if !defined(SK_RASTER_RECORDER_IMPLEMENTATION) && SK_SUPPORT_GPU
Greg Daniela8d92112018-03-09 12:05:04 -0500168 return SkImage_Gpu::MakePromiseTexture(fContext.get(),
169 backendFormat,
170 width,
171 height,
172 mipMapped,
173 origin,
174 colorType,
175 alphaType,
176 colorSpace,
177 textureFulfillProc,
178 textureReleaseProc,
179 textureContext);
180#else
181 return nullptr;
182#endif
183}