blob: 6c81fc0becfe55600882e40e41d32b63976da20d [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 Phillipsa4c41b32017-03-15 13:02:45 -040018#include "GrTexturePriv.h"
Robert Phillips37430132016-11-09 06:50:43 -050019#include "GrTextureRenderTargetProxy.h"
Robert Phillipsf2361d22016-10-25 14:20:06 -040020
Robert Phillips93f16332016-11-23 19:37:13 -050021#include "SkMathPriv.h"
Greg Daniele1da1d92017-10-06 15:59:27 -040022#include "SkMipMap.h"
Robert Phillips93f16332016-11-23 19:37:13 -050023
Greg Daniel65fa8ca2018-01-10 17:06:31 -050024#ifdef SK_DEBUG
25static bool is_valid_fully_lazy(const GrSurfaceDesc& desc, SkBackingFit fit) {
26 return desc.fWidth <= 0 &&
27 desc.fHeight <= 0 &&
28 desc.fConfig != kUnknown_GrPixelConfig &&
Brian Salomonbdecacf2018-02-02 20:32:49 -050029 desc.fSampleCnt == 1 &&
Greg Daniel65fa8ca2018-01-10 17:06:31 -050030 SkBackingFit::kApprox == fit;
31}
32
33static bool is_valid_partially_lazy(const GrSurfaceDesc& desc) {
34 return ((desc.fWidth > 0 && desc.fHeight > 0) ||
35 (desc.fWidth <= 0 && desc.fHeight <= 0)) &&
36 desc.fConfig != kUnknown_GrPixelConfig;
37}
38
39static bool is_valid_non_lazy(const GrSurfaceDesc& desc) {
40 return desc.fWidth > 0 &&
41 desc.fHeight > 0 &&
42 desc.fConfig != kUnknown_GrPixelConfig;
43}
44#endif
45
Chris Dalton706a6ff2017-11-29 22:01:06 -070046// Lazy-callback version
Greg Daniel457469c2018-02-08 15:05:44 -050047GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
48 const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted,
49 uint32_t flags)
Greg Daniel65fa8ca2018-01-10 17:06:31 -050050 : fConfig(desc.fConfig)
51 , fWidth(desc.fWidth)
52 , fHeight(desc.fHeight)
53 , fOrigin(desc.fOrigin)
54 , fFit(fit)
55 , fBudgeted(budgeted)
56 , fFlags(flags)
Chris Dalton706a6ff2017-11-29 22:01:06 -070057 , fLazyInstantiateCallback(std::move(callback))
Greg Daniel457469c2018-02-08 15:05:44 -050058 , fLazyInstantiationType(lazyType)
Greg Daniel65fa8ca2018-01-10 17:06:31 -050059 , fNeedsClear(SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag))
Chris Dalton706a6ff2017-11-29 22:01:06 -070060 , fGpuMemorySize(kInvalidGpuMemorySize)
61 , fLastOpList(nullptr) {
62 // NOTE: the default fUniqueID ctor pulls a value from the same pool as the GrGpuResources.
Greg Daniel65fa8ca2018-01-10 17:06:31 -050063 if (fLazyInstantiateCallback) {
64 SkASSERT(is_valid_fully_lazy(desc, fit) || is_valid_partially_lazy(desc));
65 } else {
66 SkASSERT(is_valid_non_lazy(desc));
67 }
Chris Dalton706a6ff2017-11-29 22:01:06 -070068}
69
70// Wrapped version
Robert Phillips066f0202017-07-25 10:16:35 -040071GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface, GrSurfaceOrigin origin, SkBackingFit fit)
Brian Salomonbb5711a2017-05-17 13:49:59 -040072 : INHERITED(std::move(surface))
73 , fConfig(fTarget->config())
74 , fWidth(fTarget->width())
75 , fHeight(fTarget->height())
Robert Phillips066f0202017-07-25 10:16:35 -040076 , fOrigin(origin)
Brian Salomonbb5711a2017-05-17 13:49:59 -040077 , fFit(fit)
78 , fBudgeted(fTarget->resourcePriv().isBudgeted())
79 , fFlags(0)
80 , fUniqueID(fTarget->uniqueID()) // Note: converting from unique resource ID to a proxy ID!
Brian Salomond17b4a62017-05-23 16:53:47 -040081 , fNeedsClear(false)
Brian Salomonbb5711a2017-05-17 13:49:59 -040082 , fGpuMemorySize(kInvalidGpuMemorySize)
Robert Phillips019ff272017-07-24 14:47:57 -040083 , fLastOpList(nullptr) {
Robert Phillips019ff272017-07-24 14:47:57 -040084}
Robert Phillipsc7635fa2016-10-28 13:25:24 -040085
Robert Phillipsf2361d22016-10-25 14:20:06 -040086GrSurfaceProxy::~GrSurfaceProxy() {
Greg Daniel94a6ce82018-01-16 16:14:41 -050087 if (fLazyInstantiateCallback) {
Greg Daniel0a375db2018-02-01 12:21:39 -050088 // We call the callback with a null GrResourceProvider to signal that the lambda should
89 // clean itself up if it is holding onto any captured objects.
Greg Daniel94a6ce82018-01-16 16:14:41 -050090 this->fLazyInstantiateCallback(nullptr, nullptr);
91 }
Robert Phillips6cdc22c2017-05-11 16:29:14 -040092 // For this to be deleted the opList that held a ref on it (if there was one) must have been
93 // deleted. Which would have cleared out this back pointer.
94 SkASSERT(!fLastOpList);
Robert Phillipsf2361d22016-10-25 14:20:06 -040095}
96
Robert Phillipseafd48a2017-11-16 07:52:08 -050097bool GrSurfaceProxyPriv::AttachStencilIfNeeded(GrResourceProvider* resourceProvider,
98 GrSurface* surface, bool needsStencil) {
Robert Phillips65048132017-08-10 08:44:49 -040099 if (needsStencil) {
100 GrRenderTarget* rt = surface->asRenderTarget();
101 if (!rt) {
102 SkASSERT(0);
103 return false;
104 }
105
106 if (!resourceProvider->attachStencilAttachment(rt)) {
107 return false;
108 }
109 }
110
111 return true;
112}
113
Robert Phillips5af44de2017-07-18 14:49:38 -0400114sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl(
Robert Phillips65048132017-08-10 08:44:49 -0400115 GrResourceProvider* resourceProvider,
116 int sampleCnt, bool needsStencil,
Greg Danield2d8e922018-02-12 12:07:39 -0500117 GrSurfaceFlags flags, GrMipMapped mipMapped) const {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500118 SkASSERT(GrSurfaceProxy::LazyState::kNot == this->lazyInstantiationState());
Greg Danield2d8e922018-02-12 12:07:39 -0500119 SkASSERT(!fTarget);
Greg Daniele252f082017-10-23 16:05:23 -0400120 SkASSERT(GrMipMapped::kNo == mipMapped);
Brian Salomonbb5711a2017-05-17 13:49:59 -0400121 GrSurfaceDesc desc;
Brian Salomonbb5711a2017-05-17 13:49:59 -0400122 desc.fFlags = flags;
Brian Salomond17b4a62017-05-23 16:53:47 -0400123 if (fNeedsClear) {
124 desc.fFlags |= kPerformInitialClear_GrSurfaceFlag;
125 }
Robert Phillips16d8ec62017-07-27 16:16:25 -0400126 desc.fOrigin = fOrigin;
127 desc.fWidth = fWidth;
128 desc.fHeight = fHeight;
129 desc.fConfig = fConfig;
130 desc.fSampleCnt = sampleCnt;
Robert Phillipseaa86252016-11-08 13:49:39 +0000131
Robert Phillips5af44de2017-07-18 14:49:38 -0400132 sk_sp<GrSurface> surface;
Robert Phillipseaa86252016-11-08 13:49:39 +0000133 if (SkBackingFit::kApprox == fFit) {
Robert Phillips5af44de2017-07-18 14:49:38 -0400134 surface.reset(resourceProvider->createApproxTexture(desc, fFlags).release());
Robert Phillipseaa86252016-11-08 13:49:39 +0000135 } else {
Robert Phillips5af44de2017-07-18 14:49:38 -0400136 surface.reset(resourceProvider->createTexture(desc, fBudgeted, fFlags).release());
Robert Phillipseaa86252016-11-08 13:49:39 +0000137 }
Robert Phillips65048132017-08-10 08:44:49 -0400138 if (!surface) {
139 return nullptr;
140 }
141
Robert Phillipseafd48a2017-11-16 07:52:08 -0500142 if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(resourceProvider, surface.get(), needsStencil)) {
Robert Phillips65048132017-08-10 08:44:49 -0400143 return nullptr;
Robert Phillipseaa86252016-11-08 13:49:39 +0000144 }
145
Robert Phillips5af44de2017-07-18 14:49:38 -0400146 return surface;
147}
148
149void GrSurfaceProxy::assign(sk_sp<GrSurface> surface) {
150 SkASSERT(!fTarget && surface);
151 fTarget = surface.release();
robertphillips1125a032016-11-16 11:17:17 -0800152 this->INHERITED::transferRefs();
153
Robert Phillipseaa86252016-11-08 13:49:39 +0000154#ifdef SK_DEBUG
155 if (kInvalidGpuMemorySize != this->getRawGpuMemorySize_debugOnly()) {
Robert Phillips784b7bf2016-12-09 13:35:02 -0500156 SkASSERT(fTarget->gpuMemorySize() <= this->getRawGpuMemorySize_debugOnly());
Robert Phillipseaa86252016-11-08 13:49:39 +0000157 }
158#endif
Robert Phillips5af44de2017-07-18 14:49:38 -0400159}
Robert Phillipseaa86252016-11-08 13:49:39 +0000160
Robert Phillips5af44de2017-07-18 14:49:38 -0400161bool GrSurfaceProxy::instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt,
Greg Daniele252f082017-10-23 16:05:23 -0400162 bool needsStencil, GrSurfaceFlags flags, GrMipMapped mipMapped,
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400163 const GrUniqueKey* uniqueKey) {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500164 SkASSERT(LazyState::kNot == this->lazyInstantiationState());
Robert Phillips5af44de2017-07-18 14:49:38 -0400165 if (fTarget) {
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400166 if (uniqueKey) {
167 SkASSERT(fTarget->getUniqueKey() == *uniqueKey);
168 }
Robert Phillipseafd48a2017-11-16 07:52:08 -0500169 return GrSurfaceProxyPriv::AttachStencilIfNeeded(resourceProvider, fTarget, needsStencil);
Robert Phillips5af44de2017-07-18 14:49:38 -0400170 }
171
Robert Phillips65048132017-08-10 08:44:49 -0400172 sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, sampleCnt, needsStencil,
Greg Danield2d8e922018-02-12 12:07:39 -0500173 flags, mipMapped);
Robert Phillips5af44de2017-07-18 14:49:38 -0400174 if (!surface) {
175 return false;
176 }
177
Brian Osman28c434b2017-09-27 13:11:16 -0400178 // If there was an invalidation message pending for this key, we might have just processed it,
179 // causing the key (stored on this proxy) to become invalid.
180 if (uniqueKey && uniqueKey->isValid()) {
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400181 resourceProvider->assignUniqueKeyToResource(*uniqueKey, surface.get());
182 }
183
Robert Phillips5af44de2017-07-18 14:49:38 -0400184 this->assign(std::move(surface));
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400185 return true;
Robert Phillipseaa86252016-11-08 13:49:39 +0000186}
187
Robert Phillips57aa3672017-07-21 11:38:13 -0400188void GrSurfaceProxy::computeScratchKey(GrScratchKey* key) const {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500189 SkASSERT(LazyState::kFully != this->lazyInstantiationState());
Robert Phillips57aa3672017-07-21 11:38:13 -0400190 const GrRenderTargetProxy* rtp = this->asRenderTargetProxy();
Brian Salomonbdecacf2018-02-02 20:32:49 -0500191 int sampleCount = 1;
Robert Phillips57aa3672017-07-21 11:38:13 -0400192 if (rtp) {
193 sampleCount = rtp->numStencilSamples();
194 }
195
196 const GrTextureProxy* tp = this->asTextureProxy();
Greg Daniele252f082017-10-23 16:05:23 -0400197 GrMipMapped mipMapped = GrMipMapped::kNo;
Robert Phillips57aa3672017-07-21 11:38:13 -0400198 if (tp) {
Greg Daniele252f082017-10-23 16:05:23 -0400199 mipMapped = tp->mipMapped();
Robert Phillips57aa3672017-07-21 11:38:13 -0400200 }
201
Robert Phillipsa108c922017-10-10 10:42:19 -0400202 int width = this->worstCaseWidth();
203 int height = this->worstCaseHeight();
Robert Phillips57aa3672017-07-21 11:38:13 -0400204
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400205 GrTexturePriv::ComputeScratchKey(this->config(), width, height, SkToBool(rtp), sampleCount,
Greg Daniele252f082017-10-23 16:05:23 -0400206 mipMapped, key);
Robert Phillips57aa3672017-07-21 11:38:13 -0400207}
208
Robert Phillipsf2361d22016-10-25 14:20:06 -0400209void GrSurfaceProxy::setLastOpList(GrOpList* opList) {
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400210#ifdef SK_DEBUG
Robert Phillipsf2361d22016-10-25 14:20:06 -0400211 if (fLastOpList) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400212 SkASSERT(fLastOpList->isClosed());
Robert Phillips4a395042017-04-24 16:27:17 +0000213 }
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400214#endif
Robert Phillipsf2361d22016-10-25 14:20:06 -0400215
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400216 // Un-reffed
217 fLastOpList = opList;
Robert Phillipsf2361d22016-10-25 14:20:06 -0400218}
Robert Phillips37430132016-11-09 06:50:43 -0500219
Brian Osman45580d32016-11-23 09:37:01 -0500220GrRenderTargetOpList* GrSurfaceProxy::getLastRenderTargetOpList() {
221 return fLastOpList ? fLastOpList->asRenderTargetOpList() : nullptr;
222}
223
224GrTextureOpList* GrSurfaceProxy::getLastTextureOpList() {
225 return fLastOpList ? fLastOpList->asTextureOpList() : nullptr;
226}
227
Robert Phillipsa108c922017-10-10 10:42:19 -0400228int GrSurfaceProxy::worstCaseWidth() const {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500229 SkASSERT(LazyState::kFully != this->lazyInstantiationState());
Robert Phillipsa108c922017-10-10 10:42:19 -0400230 if (fTarget) {
231 return fTarget->width();
232 }
233
234 if (SkBackingFit::kExact == fFit) {
235 return fWidth;
236 }
237 return SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(fWidth));
238}
239
240int GrSurfaceProxy::worstCaseHeight() const {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500241 SkASSERT(LazyState::kFully != this->lazyInstantiationState());
Robert Phillipsa108c922017-10-10 10:42:19 -0400242 if (fTarget) {
243 return fTarget->height();
244 }
245
246 if (SkBackingFit::kExact == fFit) {
247 return fHeight;
248 }
249 return SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(fHeight));
250}
251
Brian Osman45580d32016-11-23 09:37:01 -0500252#ifdef SK_DEBUG
253void GrSurfaceProxy::validate(GrContext* context) const {
254 if (fTarget) {
255 SkASSERT(fTarget->getContext() == context);
256 }
257
258 INHERITED::validate();
259}
260#endif
Robert Phillipse2f7d182016-12-15 09:23:05 -0500261
Robert Phillips63c67462017-02-15 14:19:01 -0500262sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrContext* context,
Robert Phillipse2f7d182016-12-15 09:23:05 -0500263 GrSurfaceProxy* src,
Greg Daniel65c7f662017-10-30 13:39:09 -0400264 GrMipMapped mipMapped,
Robert Phillipse2f7d182016-12-15 09:23:05 -0500265 SkIRect srcRect,
266 SkBudgeted budgeted) {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500267 SkASSERT(LazyState::kFully != src->lazyInstantiationState());
Robert Phillipse2f7d182016-12-15 09:23:05 -0500268 if (!srcRect.intersect(SkIRect::MakeWH(src->width(), src->height()))) {
269 return nullptr;
270 }
271
Brian Salomon63e79732017-05-15 21:23:13 -0400272 GrSurfaceDesc dstDesc;
Robert Phillips16d8ec62017-07-27 16:16:25 -0400273 dstDesc.fOrigin = src->origin();
Robert Phillipse2f7d182016-12-15 09:23:05 -0500274 dstDesc.fWidth = srcRect.width();
275 dstDesc.fHeight = srcRect.height();
Robert Phillips16d8ec62017-07-27 16:16:25 -0400276 dstDesc.fConfig = src->config();
Robert Phillipse2f7d182016-12-15 09:23:05 -0500277
Brian Salomon366093f2018-02-13 09:25:22 -0500278 // We use an ephemeral surface context to make the copy. Here it isn't clear what color space
279 // to tag it with. That's ok because GrSurfaceContext::copy doesn't do any color space
280 // conversions. However, if the pixel config is sRGB then the passed color space here must
281 // have sRGB gamma or GrSurfaceContext creation fails. See skbug.com/7611 about making this
282 // with the correct color space information and returning the context to the caller.
283 sk_sp<SkColorSpace> colorSpace;
284 if (GrPixelConfigIsSRGB(dstDesc.fConfig)) {
285 colorSpace = SkColorSpace::MakeSRGB();
286 }
Robert Phillipse2f7d182016-12-15 09:23:05 -0500287 sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
Brian Salomon366093f2018-02-13 09:25:22 -0500288 dstDesc, mipMapped, SkBackingFit::kExact, budgeted, std::move(colorSpace)));
Robert Phillipse2f7d182016-12-15 09:23:05 -0500289 if (!dstContext) {
290 return nullptr;
291 }
292
293 if (!dstContext->copy(src, srcRect, SkIPoint::Make(0, 0))) {
294 return nullptr;
295 }
296
Robert Phillips63c67462017-02-15 14:19:01 -0500297 return dstContext->asTextureProxyRef();
298}
299
300sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrContext* context, GrSurfaceProxy* src,
Greg Daniel65c7f662017-10-30 13:39:09 -0400301 GrMipMapped mipMapped, SkBudgeted budgeted) {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500302 SkASSERT(LazyState::kFully != src->lazyInstantiationState());
Greg Daniel65c7f662017-10-30 13:39:09 -0400303 return Copy(context, src, mipMapped, SkIRect::MakeWH(src->width(), src->height()), budgeted);
Robert Phillipse2f7d182016-12-15 09:23:05 -0500304}
305
Robert Phillipsd46697a2017-01-25 12:10:37 -0500306sk_sp<GrSurfaceContext> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
307 GrSurfaceProxy* srcProxy) {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500308 SkASSERT(LazyState::kFully != srcProxy->lazyInstantiationState());
Robert Phillipse2f7d182016-12-15 09:23:05 -0500309 sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
310 dstDesc,
Greg Daniel65c7f662017-10-30 13:39:09 -0400311 GrMipMapped::kNo,
Robert Phillipse2f7d182016-12-15 09:23:05 -0500312 SkBackingFit::kExact,
Robert Phillipsd46697a2017-01-25 12:10:37 -0500313 SkBudgeted::kYes));
Robert Phillipse2f7d182016-12-15 09:23:05 -0500314 if (!dstContext) {
315 return nullptr;
316 }
317
Robert Phillipsd46697a2017-01-25 12:10:37 -0500318 if (!dstContext->copy(srcProxy)) {
Robert Phillipse2f7d182016-12-15 09:23:05 -0500319 return nullptr;
320 }
321
Robert Phillipsd46697a2017-01-25 12:10:37 -0500322 return dstContext;
Robert Phillipse2f7d182016-12-15 09:23:05 -0500323}
Robert Phillipsb726d582017-03-09 16:36:32 -0500324
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400325void GrSurfaceProxyPriv::exactify() {
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500326 SkASSERT(GrSurfaceProxy::LazyState::kFully != fProxy->lazyInstantiationState());
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400327 if (this->isExact()) {
328 return;
329 }
330
331 SkASSERT(SkBackingFit::kApprox == fProxy->fFit);
332
333 if (fProxy->fTarget) {
334 // The kApprox but already instantiated case. Setting the proxy's width & height to
335 // the instantiated width & height could have side-effects going forward, since we're
Ben Wagner63fd7602017-10-09 15:45:33 -0400336 // obliterating the area of interest information. This call (exactify) only used
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400337 // when converting an SkSpecialImage to an SkImage so the proxy shouldn't be
338 // used for additional draws.
Brian Salomonbb5711a2017-05-17 13:49:59 -0400339 fProxy->fWidth = fProxy->fTarget->width();
340 fProxy->fHeight = fProxy->fTarget->height();
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400341 return;
342 }
343
344 // The kApprox uninstantiated case. Making this proxy be exact should be okay.
345 // It could mess things up if prior decisions were based on the approximate size.
346 fProxy->fFit = SkBackingFit::kExact;
347 // If fGpuMemorySize is used when caching specialImages for the image filter DAG. If it has
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400348 // already been computed we want to leave it alone so that amount will be removed when
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400349 // the special image goes away. If it hasn't been computed yet it might as well compute the
350 // exact amount.
351}
352
Greg Danielbddcc952018-01-24 13:22:24 -0500353bool GrSurfaceProxyPriv::doLazyInstantiation(GrResourceProvider* resourceProvider) {
Greg Daniel0a375db2018-02-01 12:21:39 -0500354 SkASSERT(GrSurfaceProxy::LazyState::kNot != fProxy->lazyInstantiationState());
Chris Dalton706a6ff2017-11-29 22:01:06 -0700355
Greg Danielf2336e42018-01-23 16:38:14 -0500356 GrSurfaceOrigin* outOrigin;
357 if (GrSurfaceProxy::LazyState::kPartially == fProxy->lazyInstantiationState()) {
358 // In the partially instantiated case, we set the origin on the SurfaceProxy at creation
359 // time (via a GrSurfaceDesc). In the lambda, the creation of the texture never needs to
360 // know the origin, and it also can't change or have any effect on it. Thus we just pass in
361 // nullptr in this case since it should never be set.
362 outOrigin = nullptr;
363 } else {
364 outOrigin = &fProxy->fOrigin;
365 }
366
Robert Phillipse8fabb22018-02-04 14:33:21 -0500367 sk_sp<GrSurface> surface = fProxy->fLazyInstantiateCallback(resourceProvider, outOrigin);
Greg Daniel457469c2018-02-08 15:05:44 -0500368 if (GrSurfaceProxy::LazyInstantiationType::kSingleUse == fProxy->fLazyInstantiationType) {
369 fProxy->fLazyInstantiateCallback(nullptr, nullptr);
370 fProxy->fLazyInstantiateCallback = nullptr;
371 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500372 if (!surface) {
Chris Dalton706a6ff2017-11-29 22:01:06 -0700373 fProxy->fWidth = 0;
374 fProxy->fHeight = 0;
375 fProxy->fOrigin = kTopLeft_GrSurfaceOrigin;
Greg Danielbddcc952018-01-24 13:22:24 -0500376 return false;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700377 }
378
Robert Phillipse8fabb22018-02-04 14:33:21 -0500379 fProxy->fWidth = surface->width();
380 fProxy->fHeight = surface->height();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700381
Robert Phillipse8fabb22018-02-04 14:33:21 -0500382 SkASSERT(surface->config() == fProxy->fConfig);
383 SkDEBUGCODE(fProxy->validateLazySurface(surface.get());)
384 this->assign(std::move(surface));
Greg Danielbddcc952018-01-24 13:22:24 -0500385 return true;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700386}
387