blob: 1016390f7e30028100146782391e02320cca635a [file] [log] [blame]
robertphillips76948d42016-05-04 12:47:41 -07001/*
2 * Copyright 2016 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 "GrSurfaceProxy.h"
Robert Phillipsb726d582017-03-09 16:36:32 -05009#include "GrSurfaceProxyPriv.h"
robertphillips76948d42016-05-04 12:47:41 -070010
Robert Phillips784b7bf2016-12-09 13:35:02 -050011#include "GrCaps.h"
Robert Phillipse2f7d182016-12-15 09:23:05 -050012#include "GrContext.h"
13#include "GrContextPriv.h"
Robert Phillipsc7635fa2016-10-28 13:25:24 -040014#include "GrGpuResourcePriv.h"
Robert Phillipsf2361d22016-10-25 14:20:06 -040015#include "GrOpList.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050016#include "GrProxyProvider.h"
Robert Phillipse2f7d182016-12-15 09:23:05 -050017#include "GrSurfaceContext.h"
Robert Phillipsfe0253f2018-03-16 16:47:25 -040018#include "GrSurfacePriv.h"
Robert Phillipsa4c41b32017-03-15 13:02:45 -040019#include "GrTexturePriv.h"
Robert Phillips37430132016-11-09 06:50:43 -050020#include "GrTextureRenderTargetProxy.h"
Robert Phillipsf2361d22016-10-25 14:20:06 -040021
Robert Phillips93f16332016-11-23 19:37:13 -050022#include "SkMathPriv.h"
Greg Daniele1da1d92017-10-06 15:59:27 -040023#include "SkMipMap.h"
Robert Phillips93f16332016-11-23 19:37:13 -050024
Greg Daniel65fa8ca2018-01-10 17:06:31 -050025#ifdef SK_DEBUG
Robert Phillipsc7c2baf2018-03-08 09:51:04 -050026#include "GrRenderTarget.h"
27#include "GrRenderTargetPriv.h"
28
Greg Daniel65fa8ca2018-01-10 17:06:31 -050029static bool is_valid_fully_lazy(const GrSurfaceDesc& desc, SkBackingFit fit) {
30 return desc.fWidth <= 0 &&
31 desc.fHeight <= 0 &&
32 desc.fConfig != kUnknown_GrPixelConfig &&
Brian Salomonbdecacf2018-02-02 20:32:49 -050033 desc.fSampleCnt == 1 &&
Greg Daniel65fa8ca2018-01-10 17:06:31 -050034 SkBackingFit::kApprox == fit;
35}
36
37static bool is_valid_partially_lazy(const GrSurfaceDesc& desc) {
38 return ((desc.fWidth > 0 && desc.fHeight > 0) ||
39 (desc.fWidth <= 0 && desc.fHeight <= 0)) &&
40 desc.fConfig != kUnknown_GrPixelConfig;
41}
42
43static bool is_valid_non_lazy(const GrSurfaceDesc& desc) {
44 return desc.fWidth > 0 &&
45 desc.fHeight > 0 &&
46 desc.fConfig != kUnknown_GrPixelConfig;
47}
48#endif
49
Chris Dalton706a6ff2017-11-29 22:01:06 -070050// Lazy-callback version
Greg Daniel457469c2018-02-08 15:05:44 -050051GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
Brian Salomon2a4f9832018-03-03 22:43:43 -050052 const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit,
Robert Phillipsfe0253f2018-03-16 16:47:25 -040053 SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
Greg Daniel65fa8ca2018-01-10 17:06:31 -050054 : fConfig(desc.fConfig)
55 , fWidth(desc.fWidth)
56 , fHeight(desc.fHeight)
Brian Salomon2a4f9832018-03-03 22:43:43 -050057 , fOrigin(origin)
Greg Daniel65fa8ca2018-01-10 17:06:31 -050058 , fFit(fit)
59 , fBudgeted(budgeted)
Robert Phillipsfe0253f2018-03-16 16:47:25 -040060 , fSurfaceFlags(surfaceFlags)
Chris Dalton706a6ff2017-11-29 22:01:06 -070061 , fLazyInstantiateCallback(std::move(callback))
Greg Daniel457469c2018-02-08 15:05:44 -050062 , fLazyInstantiationType(lazyType)
Greg Daniel65fa8ca2018-01-10 17:06:31 -050063 , fNeedsClear(SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag))
Chris Dalton706a6ff2017-11-29 22:01:06 -070064 , fGpuMemorySize(kInvalidGpuMemorySize)
65 , fLastOpList(nullptr) {
66 // NOTE: the default fUniqueID ctor pulls a value from the same pool as the GrGpuResources.
Greg Daniel65fa8ca2018-01-10 17:06:31 -050067 if (fLazyInstantiateCallback) {
68 SkASSERT(is_valid_fully_lazy(desc, fit) || is_valid_partially_lazy(desc));
69 } else {
70 SkASSERT(is_valid_non_lazy(desc));
71 }
Chris Dalton706a6ff2017-11-29 22:01:06 -070072}
73
74// Wrapped version
Robert Phillips066f0202017-07-25 10:16:35 -040075GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface, GrSurfaceOrigin origin, SkBackingFit fit)
Brian Salomonbb5711a2017-05-17 13:49:59 -040076 : INHERITED(std::move(surface))
77 , fConfig(fTarget->config())
78 , fWidth(fTarget->width())
79 , fHeight(fTarget->height())
Robert Phillips066f0202017-07-25 10:16:35 -040080 , fOrigin(origin)
Brian Salomonbb5711a2017-05-17 13:49:59 -040081 , fFit(fit)
82 , fBudgeted(fTarget->resourcePriv().isBudgeted())
Robert Phillipsfe0253f2018-03-16 16:47:25 -040083 , fSurfaceFlags(fTarget->surfacePriv().flags())
Brian Salomonbb5711a2017-05-17 13:49:59 -040084 , fUniqueID(fTarget->uniqueID()) // Note: converting from unique resource ID to a proxy ID!
Brian Salomond17b4a62017-05-23 16:53:47 -040085 , fNeedsClear(false)
Brian Salomonbb5711a2017-05-17 13:49:59 -040086 , fGpuMemorySize(kInvalidGpuMemorySize)
Robert Phillips019ff272017-07-24 14:47:57 -040087 , fLastOpList(nullptr) {
Robert Phillips019ff272017-07-24 14:47:57 -040088}
Robert Phillipsc7635fa2016-10-28 13:25:24 -040089
Robert Phillipsf2361d22016-10-25 14:20:06 -040090GrSurfaceProxy::~GrSurfaceProxy() {
Greg Daniel94a6ce82018-01-16 16:14:41 -050091 if (fLazyInstantiateCallback) {
Greg Daniel0a375db2018-02-01 12:21:39 -050092 // We call the callback with a null GrResourceProvider to signal that the lambda should
93 // clean itself up if it is holding onto any captured objects.
Robert Phillipsce5209a2018-02-13 11:13:51 -050094 this->fLazyInstantiateCallback(nullptr);
Greg Daniel94a6ce82018-01-16 16:14:41 -050095 }
Robert Phillips6cdc22c2017-05-11 16:29:14 -040096 // For this to be deleted the opList that held a ref on it (if there was one) must have been
97 // deleted. Which would have cleared out this back pointer.
98 SkASSERT(!fLastOpList);
Robert Phillipsf2361d22016-10-25 14:20:06 -040099}
100
Robert Phillipseafd48a2017-11-16 07:52:08 -0500101bool GrSurfaceProxyPriv::AttachStencilIfNeeded(GrResourceProvider* resourceProvider,
102 GrSurface* surface, bool needsStencil) {
Robert Phillips65048132017-08-10 08:44:49 -0400103 if (needsStencil) {
104 GrRenderTarget* rt = surface->asRenderTarget();
105 if (!rt) {
106 SkASSERT(0);
107 return false;
108 }
109
110 if (!resourceProvider->attachStencilAttachment(rt)) {
111 return false;
112 }
113 }
114
115 return true;
116}
117
Robert Phillips5af44de2017-07-18 14:49:38 -0400118sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl(
Robert Phillips65048132017-08-10 08:44:49 -0400119 GrResourceProvider* resourceProvider,
120 int sampleCnt, bool needsStencil,
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400121 GrSurfaceDescFlags descFlags, GrMipMapped mipMapped) const {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500122 SkASSERT(GrSurfaceProxy::LazyState::kNot == this->lazyInstantiationState());
Greg Danield2d8e922018-02-12 12:07:39 -0500123 SkASSERT(!fTarget);
Brian Salomonbb5711a2017-05-17 13:49:59 -0400124 GrSurfaceDesc desc;
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400125 desc.fFlags = descFlags;
Brian Salomond17b4a62017-05-23 16:53:47 -0400126 if (fNeedsClear) {
127 desc.fFlags |= kPerformInitialClear_GrSurfaceFlag;
128 }
Robert Phillips16d8ec62017-07-27 16:16:25 -0400129 desc.fWidth = fWidth;
130 desc.fHeight = fHeight;
131 desc.fConfig = fConfig;
132 desc.fSampleCnt = sampleCnt;
Robert Phillipseaa86252016-11-08 13:49:39 +0000133
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400134 GrResourceProvider::Flags resourceProviderFlags = GrResourceProvider::kNone_Flag;
135 if (fSurfaceFlags & GrInternalSurfaceFlags::kNoPendingIO) {
136 resourceProviderFlags = GrResourceProvider::kNoPendingIO_Flag;
137 }
138
Robert Phillips5af44de2017-07-18 14:49:38 -0400139 sk_sp<GrSurface> surface;
Greg Danielf6f7b672018-02-15 13:06:26 -0500140 if (GrMipMapped::kYes == mipMapped) {
141 SkASSERT(SkBackingFit::kExact == fFit);
142
143 // SkMipMap doesn't include the base level in the level count so we have to add 1
144 int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
145 // We should have caught the case where mipCount == 1 when making the proxy and instead
146 // created a non-mipmapped proxy.
147 SkASSERT(mipCount > 1);
148 std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipCount]);
149
150 // We don't want to upload any texel data
151 for (int i = 0; i < mipCount; i++) {
152 texels[i].fPixels = nullptr;
153 texels[i].fRowBytes = 0;
154 }
155
Brian Salomon58389b92018-03-07 13:01:25 -0500156 surface = resourceProvider->createTexture(desc, fBudgeted, texels.get(), mipCount,
Greg Danielf6f7b672018-02-15 13:06:26 -0500157 SkDestinationSurfaceColorMode::kLegacy);
158 if (surface) {
159 SkASSERT(surface->asTexture());
160 SkASSERT(GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
161 }
Robert Phillipseaa86252016-11-08 13:49:39 +0000162 } else {
Greg Danielf6f7b672018-02-15 13:06:26 -0500163 if (SkBackingFit::kApprox == fFit) {
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400164 surface = resourceProvider->createApproxTexture(desc, resourceProviderFlags);
Greg Danielf6f7b672018-02-15 13:06:26 -0500165 } else {
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400166 surface = resourceProvider->createTexture(desc, fBudgeted, resourceProviderFlags);
Greg Danielf6f7b672018-02-15 13:06:26 -0500167 }
Robert Phillipseaa86252016-11-08 13:49:39 +0000168 }
Robert Phillips65048132017-08-10 08:44:49 -0400169 if (!surface) {
170 return nullptr;
171 }
172
Robert Phillipseafd48a2017-11-16 07:52:08 -0500173 if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(resourceProvider, surface.get(), needsStencil)) {
Robert Phillips65048132017-08-10 08:44:49 -0400174 return nullptr;
Robert Phillipseaa86252016-11-08 13:49:39 +0000175 }
176
Robert Phillips5af44de2017-07-18 14:49:38 -0400177 return surface;
178}
179
180void GrSurfaceProxy::assign(sk_sp<GrSurface> surface) {
181 SkASSERT(!fTarget && surface);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400182
183 // Check that our a priori computation matched the ultimate reality
Robert Phillips12a68422018-03-23 14:20:42 -0400184 // DDL TODO: re-enable this after skbug.com/7748 (Add FBO-0-ness to SkSurfaceCharacterization)
185 // is fixed.
186// SkASSERT((fSurfaceFlags & ~GrInternalSurfaceFlags::kNoPendingIO) ==
187// surface->surfacePriv().flags());
Robert Phillipsabf7b762018-03-21 12:13:37 -0400188
Robert Phillips5af44de2017-07-18 14:49:38 -0400189 fTarget = surface.release();
Robert Phillipsc7c2baf2018-03-08 09:51:04 -0500190
robertphillips1125a032016-11-16 11:17:17 -0800191 this->INHERITED::transferRefs();
192
Robert Phillipseaa86252016-11-08 13:49:39 +0000193#ifdef SK_DEBUG
Robert Phillipsc7c2baf2018-03-08 09:51:04 -0500194 if (this->asRenderTargetProxy()) {
195 SkASSERT(fTarget->asRenderTarget());
196 if (this->asRenderTargetProxy()->needsStencil()) {
197 SkASSERT(fTarget->asRenderTarget()->renderTargetPriv().getStencilAttachment());
198 }
199 }
200
Robert Phillipseaa86252016-11-08 13:49:39 +0000201 if (kInvalidGpuMemorySize != this->getRawGpuMemorySize_debugOnly()) {
Robert Phillips784b7bf2016-12-09 13:35:02 -0500202 SkASSERT(fTarget->gpuMemorySize() <= this->getRawGpuMemorySize_debugOnly());
Robert Phillipseaa86252016-11-08 13:49:39 +0000203 }
204#endif
Robert Phillips5af44de2017-07-18 14:49:38 -0400205}
Robert Phillipseaa86252016-11-08 13:49:39 +0000206
Robert Phillips5af44de2017-07-18 14:49:38 -0400207bool GrSurfaceProxy::instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt,
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400208 bool needsStencil, GrSurfaceDescFlags descFlags,
209 GrMipMapped mipMapped, const GrUniqueKey* uniqueKey) {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500210 SkASSERT(LazyState::kNot == this->lazyInstantiationState());
Robert Phillips5af44de2017-07-18 14:49:38 -0400211 if (fTarget) {
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400212 if (uniqueKey) {
213 SkASSERT(fTarget->getUniqueKey() == *uniqueKey);
214 }
Robert Phillipseafd48a2017-11-16 07:52:08 -0500215 return GrSurfaceProxyPriv::AttachStencilIfNeeded(resourceProvider, fTarget, needsStencil);
Robert Phillips5af44de2017-07-18 14:49:38 -0400216 }
217
Robert Phillips65048132017-08-10 08:44:49 -0400218 sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, sampleCnt, needsStencil,
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400219 descFlags, mipMapped);
Robert Phillips5af44de2017-07-18 14:49:38 -0400220 if (!surface) {
221 return false;
222 }
223
Brian Osman28c434b2017-09-27 13:11:16 -0400224 // If there was an invalidation message pending for this key, we might have just processed it,
225 // causing the key (stored on this proxy) to become invalid.
226 if (uniqueKey && uniqueKey->isValid()) {
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400227 resourceProvider->assignUniqueKeyToResource(*uniqueKey, surface.get());
228 }
229
Robert Phillips5af44de2017-07-18 14:49:38 -0400230 this->assign(std::move(surface));
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400231
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400232 return true;
Robert Phillipseaa86252016-11-08 13:49:39 +0000233}
234
Robert Phillips4bc70112018-03-01 10:24:02 -0500235void GrSurfaceProxy::deInstantiate() {
236 SkASSERT(this->priv().isInstantiated());
237
238 this->release();
239}
240
241
Robert Phillips57aa3672017-07-21 11:38:13 -0400242void GrSurfaceProxy::computeScratchKey(GrScratchKey* key) const {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500243 SkASSERT(LazyState::kFully != this->lazyInstantiationState());
Robert Phillips57aa3672017-07-21 11:38:13 -0400244 const GrRenderTargetProxy* rtp = this->asRenderTargetProxy();
Brian Salomonbdecacf2018-02-02 20:32:49 -0500245 int sampleCount = 1;
Robert Phillips57aa3672017-07-21 11:38:13 -0400246 if (rtp) {
247 sampleCount = rtp->numStencilSamples();
248 }
249
250 const GrTextureProxy* tp = this->asTextureProxy();
Greg Daniele252f082017-10-23 16:05:23 -0400251 GrMipMapped mipMapped = GrMipMapped::kNo;
Robert Phillips57aa3672017-07-21 11:38:13 -0400252 if (tp) {
Greg Daniele252f082017-10-23 16:05:23 -0400253 mipMapped = tp->mipMapped();
Robert Phillips57aa3672017-07-21 11:38:13 -0400254 }
255
Robert Phillipsa108c922017-10-10 10:42:19 -0400256 int width = this->worstCaseWidth();
257 int height = this->worstCaseHeight();
Robert Phillips57aa3672017-07-21 11:38:13 -0400258
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400259 GrTexturePriv::ComputeScratchKey(this->config(), width, height, SkToBool(rtp), sampleCount,
Greg Daniele252f082017-10-23 16:05:23 -0400260 mipMapped, key);
Robert Phillips57aa3672017-07-21 11:38:13 -0400261}
262
Robert Phillipsf2361d22016-10-25 14:20:06 -0400263void GrSurfaceProxy::setLastOpList(GrOpList* opList) {
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400264#ifdef SK_DEBUG
Robert Phillipsf2361d22016-10-25 14:20:06 -0400265 if (fLastOpList) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400266 SkASSERT(fLastOpList->isClosed());
Robert Phillips4a395042017-04-24 16:27:17 +0000267 }
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400268#endif
Robert Phillipsf2361d22016-10-25 14:20:06 -0400269
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400270 // Un-reffed
271 fLastOpList = opList;
Robert Phillipsf2361d22016-10-25 14:20:06 -0400272}
Robert Phillips37430132016-11-09 06:50:43 -0500273
Brian Osman45580d32016-11-23 09:37:01 -0500274GrRenderTargetOpList* GrSurfaceProxy::getLastRenderTargetOpList() {
275 return fLastOpList ? fLastOpList->asRenderTargetOpList() : nullptr;
276}
277
278GrTextureOpList* GrSurfaceProxy::getLastTextureOpList() {
279 return fLastOpList ? fLastOpList->asTextureOpList() : nullptr;
280}
281
Robert Phillipsa108c922017-10-10 10:42:19 -0400282int GrSurfaceProxy::worstCaseWidth() const {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500283 SkASSERT(LazyState::kFully != this->lazyInstantiationState());
Robert Phillipsa108c922017-10-10 10:42:19 -0400284 if (fTarget) {
285 return fTarget->width();
286 }
287
288 if (SkBackingFit::kExact == fFit) {
289 return fWidth;
290 }
291 return SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(fWidth));
292}
293
294int GrSurfaceProxy::worstCaseHeight() const {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500295 SkASSERT(LazyState::kFully != this->lazyInstantiationState());
Robert Phillipsa108c922017-10-10 10:42:19 -0400296 if (fTarget) {
297 return fTarget->height();
298 }
299
300 if (SkBackingFit::kExact == fFit) {
301 return fHeight;
302 }
303 return SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(fHeight));
304}
305
Brian Osman45580d32016-11-23 09:37:01 -0500306#ifdef SK_DEBUG
307void GrSurfaceProxy::validate(GrContext* context) const {
308 if (fTarget) {
309 SkASSERT(fTarget->getContext() == context);
310 }
311
312 INHERITED::validate();
313}
314#endif
Robert Phillipse2f7d182016-12-15 09:23:05 -0500315
Robert Phillips63c67462017-02-15 14:19:01 -0500316sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrContext* context,
Robert Phillipse2f7d182016-12-15 09:23:05 -0500317 GrSurfaceProxy* src,
Greg Daniel65c7f662017-10-30 13:39:09 -0400318 GrMipMapped mipMapped,
Robert Phillipse2f7d182016-12-15 09:23:05 -0500319 SkIRect srcRect,
320 SkBudgeted budgeted) {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500321 SkASSERT(LazyState::kFully != src->lazyInstantiationState());
Robert Phillipse2f7d182016-12-15 09:23:05 -0500322 if (!srcRect.intersect(SkIRect::MakeWH(src->width(), src->height()))) {
323 return nullptr;
324 }
325
Brian Salomon63e79732017-05-15 21:23:13 -0400326 GrSurfaceDesc dstDesc;
Robert Phillipse2f7d182016-12-15 09:23:05 -0500327 dstDesc.fWidth = srcRect.width();
328 dstDesc.fHeight = srcRect.height();
Robert Phillips16d8ec62017-07-27 16:16:25 -0400329 dstDesc.fConfig = src->config();
Robert Phillipse2f7d182016-12-15 09:23:05 -0500330
Brian Salomon366093f2018-02-13 09:25:22 -0500331 // We use an ephemeral surface context to make the copy. Here it isn't clear what color space
332 // to tag it with. That's ok because GrSurfaceContext::copy doesn't do any color space
333 // conversions. However, if the pixel config is sRGB then the passed color space here must
334 // have sRGB gamma or GrSurfaceContext creation fails. See skbug.com/7611 about making this
335 // with the correct color space information and returning the context to the caller.
336 sk_sp<SkColorSpace> colorSpace;
337 if (GrPixelConfigIsSRGB(dstDesc.fConfig)) {
338 colorSpace = SkColorSpace::MakeSRGB();
339 }
Robert Phillipse2f7d182016-12-15 09:23:05 -0500340 sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
Brian Salomon2a4f9832018-03-03 22:43:43 -0500341 dstDesc, src->origin(), mipMapped, SkBackingFit::kExact, budgeted,
342 std::move(colorSpace)));
Robert Phillipse2f7d182016-12-15 09:23:05 -0500343 if (!dstContext) {
344 return nullptr;
345 }
346
347 if (!dstContext->copy(src, srcRect, SkIPoint::Make(0, 0))) {
348 return nullptr;
349 }
350
Robert Phillips63c67462017-02-15 14:19:01 -0500351 return dstContext->asTextureProxyRef();
352}
353
354sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrContext* context, GrSurfaceProxy* src,
Greg Daniel65c7f662017-10-30 13:39:09 -0400355 GrMipMapped mipMapped, SkBudgeted budgeted) {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500356 SkASSERT(LazyState::kFully != src->lazyInstantiationState());
Greg Daniel65c7f662017-10-30 13:39:09 -0400357 return Copy(context, src, mipMapped, SkIRect::MakeWH(src->width(), src->height()), budgeted);
Robert Phillipse2f7d182016-12-15 09:23:05 -0500358}
359
Robert Phillipsd46697a2017-01-25 12:10:37 -0500360sk_sp<GrSurfaceContext> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
Brian Salomon2a4f9832018-03-03 22:43:43 -0500361 GrSurfaceOrigin origin, GrSurfaceProxy* srcProxy) {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500362 SkASSERT(LazyState::kFully != srcProxy->lazyInstantiationState());
Robert Phillipse2f7d182016-12-15 09:23:05 -0500363 sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
Brian Salomon2a4f9832018-03-03 22:43:43 -0500364 dstDesc, origin, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kYes));
Robert Phillipse2f7d182016-12-15 09:23:05 -0500365 if (!dstContext) {
366 return nullptr;
367 }
368
Robert Phillipsd46697a2017-01-25 12:10:37 -0500369 if (!dstContext->copy(srcProxy)) {
Robert Phillipse2f7d182016-12-15 09:23:05 -0500370 return nullptr;
371 }
372
Robert Phillipsd46697a2017-01-25 12:10:37 -0500373 return dstContext;
Robert Phillipse2f7d182016-12-15 09:23:05 -0500374}
Robert Phillipsb726d582017-03-09 16:36:32 -0500375
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400376void GrSurfaceProxyPriv::exactify() {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500377 SkASSERT(GrSurfaceProxy::LazyState::kFully != fProxy->lazyInstantiationState());
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400378 if (this->isExact()) {
379 return;
380 }
381
382 SkASSERT(SkBackingFit::kApprox == fProxy->fFit);
383
384 if (fProxy->fTarget) {
385 // The kApprox but already instantiated case. Setting the proxy's width & height to
386 // the instantiated width & height could have side-effects going forward, since we're
Ben Wagner63fd7602017-10-09 15:45:33 -0400387 // obliterating the area of interest information. This call (exactify) only used
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400388 // when converting an SkSpecialImage to an SkImage so the proxy shouldn't be
389 // used for additional draws.
Brian Salomonbb5711a2017-05-17 13:49:59 -0400390 fProxy->fWidth = fProxy->fTarget->width();
391 fProxy->fHeight = fProxy->fTarget->height();
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400392 return;
393 }
394
395 // The kApprox uninstantiated case. Making this proxy be exact should be okay.
396 // It could mess things up if prior decisions were based on the approximate size.
397 fProxy->fFit = SkBackingFit::kExact;
398 // If fGpuMemorySize is used when caching specialImages for the image filter DAG. If it has
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400399 // already been computed we want to leave it alone so that amount will be removed when
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400400 // the special image goes away. If it hasn't been computed yet it might as well compute the
401 // exact amount.
402}
403
Greg Danielbddcc952018-01-24 13:22:24 -0500404bool GrSurfaceProxyPriv::doLazyInstantiation(GrResourceProvider* resourceProvider) {
Greg Daniel0a375db2018-02-01 12:21:39 -0500405 SkASSERT(GrSurfaceProxy::LazyState::kNot != fProxy->lazyInstantiationState());
Chris Dalton706a6ff2017-11-29 22:01:06 -0700406
Robert Phillipsce5209a2018-02-13 11:13:51 -0500407 sk_sp<GrSurface> surface = fProxy->fLazyInstantiateCallback(resourceProvider);
Greg Daniel457469c2018-02-08 15:05:44 -0500408 if (GrSurfaceProxy::LazyInstantiationType::kSingleUse == fProxy->fLazyInstantiationType) {
Robert Phillipsce5209a2018-02-13 11:13:51 -0500409 fProxy->fLazyInstantiateCallback(nullptr);
Greg Daniel457469c2018-02-08 15:05:44 -0500410 fProxy->fLazyInstantiateCallback = nullptr;
411 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500412 if (!surface) {
Chris Dalton706a6ff2017-11-29 22:01:06 -0700413 fProxy->fWidth = 0;
414 fProxy->fHeight = 0;
Greg Danielbddcc952018-01-24 13:22:24 -0500415 return false;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700416 }
417
Robert Phillipse8fabb22018-02-04 14:33:21 -0500418 fProxy->fWidth = surface->width();
419 fProxy->fHeight = surface->height();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700420
Robert Phillipsc7c2baf2018-03-08 09:51:04 -0500421 bool needsStencil = fProxy->asRenderTargetProxy()
422 ? fProxy->asRenderTargetProxy()->needsStencil()
423 : false;
424
425 GrSurfaceProxyPriv::AttachStencilIfNeeded(resourceProvider, surface.get(), needsStencil);
426
Robert Phillipse8fabb22018-02-04 14:33:21 -0500427 SkASSERT(surface->config() == fProxy->fConfig);
428 SkDEBUGCODE(fProxy->validateLazySurface(surface.get());)
429 this->assign(std::move(surface));
Greg Danielbddcc952018-01-24 13:22:24 -0500430 return true;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700431}
432