xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrBackendTextureImageGenerator.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2017 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrBackendTextureImageGenerator.h"
8*c8dee2aaSAndroid Build Coastguard Worker 
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/RefCntedCallback.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SkBackingFit.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpu.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpuResourcePriv.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProxyProvider.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceCache.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceProvider.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceProviderPriv.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSemaphore.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurface.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxy.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTexture.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureProxy.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SkGr.h"
37*c8dee2aaSAndroid Build Coastguard Worker 
38*c8dee2aaSAndroid Build Coastguard Worker #include <functional>
39*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
40*c8dee2aaSAndroid Build Coastguard Worker 
RefHelper(sk_sp<GrTexture> texture,GrDirectContext::DirectContextID owningContextID,std::unique_ptr<GrSemaphore> semaphore)41*c8dee2aaSAndroid Build Coastguard Worker GrBackendTextureImageGenerator::RefHelper::RefHelper(
42*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<GrTexture> texture,
43*c8dee2aaSAndroid Build Coastguard Worker         GrDirectContext::DirectContextID owningContextID,
44*c8dee2aaSAndroid Build Coastguard Worker         std::unique_ptr<GrSemaphore> semaphore)
45*c8dee2aaSAndroid Build Coastguard Worker         : fOriginalTexture(std::move(texture))
46*c8dee2aaSAndroid Build Coastguard Worker         , fOwningContextID(owningContextID)
47*c8dee2aaSAndroid Build Coastguard Worker         , fBorrowingContextReleaseProc(nullptr)
48*c8dee2aaSAndroid Build Coastguard Worker         , fSemaphore(std::move(semaphore)) {}
49*c8dee2aaSAndroid Build Coastguard Worker 
~RefHelper()50*c8dee2aaSAndroid Build Coastguard Worker GrBackendTextureImageGenerator::RefHelper::~RefHelper() {
51*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!fBorrowingContextID.isValid());
52*c8dee2aaSAndroid Build Coastguard Worker     // Generator has been freed, and no one is borrowing the texture. Notify the original cache
53*c8dee2aaSAndroid Build Coastguard Worker     // that it can free the last ref, so it happens on the correct thread.
54*c8dee2aaSAndroid Build Coastguard Worker     GrResourceCache::ReturnResourceFromThread(std::move(fOriginalTexture), fOwningContextID);
55*c8dee2aaSAndroid Build Coastguard Worker }
56*c8dee2aaSAndroid Build Coastguard Worker 
57*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrTextureGenerator>
Make(const sk_sp<GrTexture> & texture,GrSurfaceOrigin origin,std::unique_ptr<GrSemaphore> semaphore,SkColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace)58*c8dee2aaSAndroid Build Coastguard Worker GrBackendTextureImageGenerator::Make(const sk_sp<GrTexture>& texture,
59*c8dee2aaSAndroid Build Coastguard Worker                                      GrSurfaceOrigin origin,
60*c8dee2aaSAndroid Build Coastguard Worker                                      std::unique_ptr<GrSemaphore> semaphore,
61*c8dee2aaSAndroid Build Coastguard Worker                                      SkColorType colorType,
62*c8dee2aaSAndroid Build Coastguard Worker                                      SkAlphaType alphaType,
63*c8dee2aaSAndroid Build Coastguard Worker                                      sk_sp<SkColorSpace> colorSpace) {
64*c8dee2aaSAndroid Build Coastguard Worker     GrDirectContext* dContext = texture->getContext();
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     if (!dContext->priv().caps()->areColorTypeAndFormatCompatible(
67*c8dee2aaSAndroid Build Coastguard Worker                 SkColorTypeToGrColorType(colorType), texture->backendFormat())) {
68*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
69*c8dee2aaSAndroid Build Coastguard Worker     }
70*c8dee2aaSAndroid Build Coastguard Worker 
71*c8dee2aaSAndroid Build Coastguard Worker     SkColorInfo info(colorType, alphaType, std::move(colorSpace));
72*c8dee2aaSAndroid Build Coastguard Worker     return std::unique_ptr<GrTextureGenerator>(new GrBackendTextureImageGenerator(
73*c8dee2aaSAndroid Build Coastguard Worker             info,
74*c8dee2aaSAndroid Build Coastguard Worker             texture,
75*c8dee2aaSAndroid Build Coastguard Worker             origin,
76*c8dee2aaSAndroid Build Coastguard Worker             dContext->directContextID(),
77*c8dee2aaSAndroid Build Coastguard Worker             std::move(semaphore)));
78*c8dee2aaSAndroid Build Coastguard Worker }
79*c8dee2aaSAndroid Build Coastguard Worker 
GrBackendTextureImageGenerator(const SkColorInfo & info,const sk_sp<GrTexture> & texture,GrSurfaceOrigin origin,GrDirectContext::DirectContextID owningContextID,std::unique_ptr<GrSemaphore> semaphore)80*c8dee2aaSAndroid Build Coastguard Worker GrBackendTextureImageGenerator::GrBackendTextureImageGenerator(
81*c8dee2aaSAndroid Build Coastguard Worker         const SkColorInfo& info,
82*c8dee2aaSAndroid Build Coastguard Worker         const sk_sp<GrTexture>& texture,
83*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceOrigin origin,
84*c8dee2aaSAndroid Build Coastguard Worker         GrDirectContext::DirectContextID owningContextID,
85*c8dee2aaSAndroid Build Coastguard Worker         std::unique_ptr<GrSemaphore> semaphore)
86*c8dee2aaSAndroid Build Coastguard Worker         : INHERITED(SkImageInfo::Make(texture->dimensions(), info))
87*c8dee2aaSAndroid Build Coastguard Worker         , fRefHelper(new RefHelper(texture, owningContextID, std::move(semaphore)))
88*c8dee2aaSAndroid Build Coastguard Worker         , fBackendTexture(texture->getBackendTexture())
89*c8dee2aaSAndroid Build Coastguard Worker         , fSurfaceOrigin(origin) {}
90*c8dee2aaSAndroid Build Coastguard Worker 
~GrBackendTextureImageGenerator()91*c8dee2aaSAndroid Build Coastguard Worker GrBackendTextureImageGenerator::~GrBackendTextureImageGenerator() {
92*c8dee2aaSAndroid Build Coastguard Worker     fRefHelper->unref();
93*c8dee2aaSAndroid Build Coastguard Worker }
94*c8dee2aaSAndroid Build Coastguard Worker 
onIsProtected() const95*c8dee2aaSAndroid Build Coastguard Worker bool GrBackendTextureImageGenerator::onIsProtected() const {
96*c8dee2aaSAndroid Build Coastguard Worker     return fBackendTexture.isProtected();
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker 
99*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////////////////////////
100*c8dee2aaSAndroid Build Coastguard Worker 
ReleaseRefHelper_TextureReleaseProc(void * ctx)101*c8dee2aaSAndroid Build Coastguard Worker void GrBackendTextureImageGenerator::ReleaseRefHelper_TextureReleaseProc(void* ctx) {
102*c8dee2aaSAndroid Build Coastguard Worker     RefHelper* refHelper = static_cast<RefHelper*>(ctx);
103*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(refHelper);
104*c8dee2aaSAndroid Build Coastguard Worker 
105*c8dee2aaSAndroid Build Coastguard Worker     refHelper->fBorrowingContextReleaseProc = nullptr;
106*c8dee2aaSAndroid Build Coastguard Worker     refHelper->fBorrowingContextID.makeInvalid();
107*c8dee2aaSAndroid Build Coastguard Worker     refHelper->unref();
108*c8dee2aaSAndroid Build Coastguard Worker }
109*c8dee2aaSAndroid Build Coastguard Worker 
onGenerateTexture(GrRecordingContext * rContext,const SkImageInfo & info,skgpu::Mipmapped mipmapped,GrImageTexGenPolicy texGenPolicy)110*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceProxyView GrBackendTextureImageGenerator::onGenerateTexture(
111*c8dee2aaSAndroid Build Coastguard Worker         GrRecordingContext* rContext,
112*c8dee2aaSAndroid Build Coastguard Worker         const SkImageInfo& info,
113*c8dee2aaSAndroid Build Coastguard Worker         skgpu::Mipmapped mipmapped,
114*c8dee2aaSAndroid Build Coastguard Worker         GrImageTexGenPolicy texGenPolicy) {
115*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(rContext);
116*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT_RELEASE(info.dimensions() == fBackendTexture.dimensions());
117*c8dee2aaSAndroid Build Coastguard Worker 
118*c8dee2aaSAndroid Build Coastguard Worker     // We currently limit GrBackendTextureImageGenerators to direct contexts since
119*c8dee2aaSAndroid Build Coastguard Worker     // only Flutter uses them and doesn't use recording/DDL contexts. Ideally, the
120*c8dee2aaSAndroid Build Coastguard Worker     // cross context texture functionality can be subsumed by the thread-safe cache
121*c8dee2aaSAndroid Build Coastguard Worker     // working with utility contexts.
122*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = rContext->asDirectContext();
123*c8dee2aaSAndroid Build Coastguard Worker     if (!dContext) {
124*c8dee2aaSAndroid Build Coastguard Worker         return {};
125*c8dee2aaSAndroid Build Coastguard Worker     }
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker     if (dContext->backend() != fBackendTexture.backend()) {
128*c8dee2aaSAndroid Build Coastguard Worker         return {};
129*c8dee2aaSAndroid Build Coastguard Worker     }
130*c8dee2aaSAndroid Build Coastguard Worker     if (info.colorType() != this->getInfo().colorType()) {
131*c8dee2aaSAndroid Build Coastguard Worker         return {};
132*c8dee2aaSAndroid Build Coastguard Worker     }
133*c8dee2aaSAndroid Build Coastguard Worker 
134*c8dee2aaSAndroid Build Coastguard Worker     auto proxyProvider = dContext->priv().proxyProvider();
135*c8dee2aaSAndroid Build Coastguard Worker 
136*c8dee2aaSAndroid Build Coastguard Worker     fBorrowingMutex.acquire();
137*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<skgpu::RefCntedCallback> releaseProcHelper;
138*c8dee2aaSAndroid Build Coastguard Worker     if (fRefHelper->fBorrowingContextID.isValid()) {
139*c8dee2aaSAndroid Build Coastguard Worker         if (fRefHelper->fBorrowingContextID != dContext->directContextID()) {
140*c8dee2aaSAndroid Build Coastguard Worker             fBorrowingMutex.release();
141*c8dee2aaSAndroid Build Coastguard Worker             rContext->priv().printWarningMessage(
142*c8dee2aaSAndroid Build Coastguard Worker                     "GrBackendTextureImageGenerator: Trying to use texture on two GrContexts!\n");
143*c8dee2aaSAndroid Build Coastguard Worker             return {};
144*c8dee2aaSAndroid Build Coastguard Worker         } else {
145*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(fRefHelper->fBorrowingContextReleaseProc);
146*c8dee2aaSAndroid Build Coastguard Worker             // Ref the release proc to be held by the proxy we make below
147*c8dee2aaSAndroid Build Coastguard Worker             releaseProcHelper = sk_ref_sp(fRefHelper->fBorrowingContextReleaseProc);
148*c8dee2aaSAndroid Build Coastguard Worker         }
149*c8dee2aaSAndroid Build Coastguard Worker     } else {
150*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!fRefHelper->fBorrowingContextReleaseProc);
151*c8dee2aaSAndroid Build Coastguard Worker         // The ref we add to fRefHelper here will be passed into and owned by the
152*c8dee2aaSAndroid Build Coastguard Worker         // skgpu::RefCntedCallback.
153*c8dee2aaSAndroid Build Coastguard Worker         fRefHelper->ref();
154*c8dee2aaSAndroid Build Coastguard Worker         releaseProcHelper =
155*c8dee2aaSAndroid Build Coastguard Worker                 skgpu::RefCntedCallback::Make(ReleaseRefHelper_TextureReleaseProc, fRefHelper);
156*c8dee2aaSAndroid Build Coastguard Worker         fRefHelper->fBorrowingContextReleaseProc = releaseProcHelper.get();
157*c8dee2aaSAndroid Build Coastguard Worker     }
158*c8dee2aaSAndroid Build Coastguard Worker     fRefHelper->fBorrowingContextID = dContext->directContextID();
159*c8dee2aaSAndroid Build Coastguard Worker     if (!fRefHelper->fBorrowedTextureKey.isValid()) {
160*c8dee2aaSAndroid Build Coastguard Worker         static const auto kDomain = skgpu::UniqueKey::GenerateDomain();
161*c8dee2aaSAndroid Build Coastguard Worker         skgpu::UniqueKey::Builder builder(&fRefHelper->fBorrowedTextureKey, kDomain, 1);
162*c8dee2aaSAndroid Build Coastguard Worker         builder[0] = this->uniqueID();
163*c8dee2aaSAndroid Build Coastguard Worker     }
164*c8dee2aaSAndroid Build Coastguard Worker     fBorrowingMutex.release();
165*c8dee2aaSAndroid Build Coastguard Worker 
166*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fRefHelper->fBorrowingContextID == dContext->directContextID());
167*c8dee2aaSAndroid Build Coastguard Worker 
168*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat backendFormat = fBackendTexture.getBackendFormat();
169*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(backendFormat.isValid());
170*c8dee2aaSAndroid Build Coastguard Worker 
171*c8dee2aaSAndroid Build Coastguard Worker     GrColorType grColorType = SkColorTypeToGrColorType(info.colorType());
172*c8dee2aaSAndroid Build Coastguard Worker 
173*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Mipmapped textureIsMipMapped =
174*c8dee2aaSAndroid Build Coastguard Worker             fBackendTexture.hasMipmaps() ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
175*c8dee2aaSAndroid Build Coastguard Worker 
176*c8dee2aaSAndroid Build Coastguard Worker     // Ganesh assumes that, when wrapping a mipmapped backend texture from a client, that its
177*c8dee2aaSAndroid Build Coastguard Worker     // mipmaps are fully fleshed out.
178*c8dee2aaSAndroid Build Coastguard Worker     GrMipmapStatus mipmapStatus = fBackendTexture.hasMipmaps()
179*c8dee2aaSAndroid Build Coastguard Worker             ? GrMipmapStatus::kValid : GrMipmapStatus::kNotAllocated;
180*c8dee2aaSAndroid Build Coastguard Worker 
181*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Swizzle readSwizzle = dContext->priv().caps()->getReadSwizzle(backendFormat,
182*c8dee2aaSAndroid Build Coastguard Worker                                                                          grColorType);
183*c8dee2aaSAndroid Build Coastguard Worker 
184*c8dee2aaSAndroid Build Coastguard Worker     // Must make copies of member variables to capture in the lambda since this image generator may
185*c8dee2aaSAndroid Build Coastguard Worker     // be deleted before we actually execute the lambda.
186*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
187*c8dee2aaSAndroid Build Coastguard Worker             [refHelper = fRefHelper, releaseProcHelper, backendTexture = fBackendTexture](
188*c8dee2aaSAndroid Build Coastguard Worker                     GrResourceProvider* resourceProvider,
189*c8dee2aaSAndroid Build Coastguard Worker                     const GrSurfaceProxy::LazySurfaceDesc&) -> GrSurfaceProxy::LazyCallbackResult {
190*c8dee2aaSAndroid Build Coastguard Worker                 if (refHelper->fSemaphore) {
191*c8dee2aaSAndroid Build Coastguard Worker                     resourceProvider->priv().gpu()->waitSemaphore(refHelper->fSemaphore.get());
192*c8dee2aaSAndroid Build Coastguard Worker                 }
193*c8dee2aaSAndroid Build Coastguard Worker 
194*c8dee2aaSAndroid Build Coastguard Worker                 // If a client re-draws the same image multiple times, the texture we return
195*c8dee2aaSAndroid Build Coastguard Worker                 // will be cached and re-used. If they draw a subset, though, we may be
196*c8dee2aaSAndroid Build Coastguard Worker                 // re-called. In that case, we want to re-use the borrowed texture we've
197*c8dee2aaSAndroid Build Coastguard Worker                 // previously created.
198*c8dee2aaSAndroid Build Coastguard Worker                 sk_sp<GrTexture> tex;
199*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(refHelper->fBorrowedTextureKey.isValid());
200*c8dee2aaSAndroid Build Coastguard Worker                 auto surf = resourceProvider->findByUniqueKey<GrSurface>(
201*c8dee2aaSAndroid Build Coastguard Worker                         refHelper->fBorrowedTextureKey);
202*c8dee2aaSAndroid Build Coastguard Worker                 if (surf) {
203*c8dee2aaSAndroid Build Coastguard Worker                     SkASSERT(surf->asTexture());
204*c8dee2aaSAndroid Build Coastguard Worker                     tex = sk_ref_sp(surf->asTexture());
205*c8dee2aaSAndroid Build Coastguard Worker                 } else {
206*c8dee2aaSAndroid Build Coastguard Worker                     // We just gained access to the texture. If we're on the original
207*c8dee2aaSAndroid Build Coastguard Worker                     // context, we could use the original texture, but we'd have no way of
208*c8dee2aaSAndroid Build Coastguard Worker                     // detecting that it's no longer in-use. So we always make a wrapped
209*c8dee2aaSAndroid Build Coastguard Worker                     // copy, where the release proc informs us that the context is done with
210*c8dee2aaSAndroid Build Coastguard Worker                     // it. This is unfortunate - we'll have two texture objects referencing
211*c8dee2aaSAndroid Build Coastguard Worker                     // the same GPU object. However, no client can ever see the original
212*c8dee2aaSAndroid Build Coastguard Worker                     // texture, so this should be safe. We make the texture uncacheable so
213*c8dee2aaSAndroid Build Coastguard Worker                     // that the release proc is called ASAP.
214*c8dee2aaSAndroid Build Coastguard Worker                     tex = resourceProvider->wrapBackendTexture(
215*c8dee2aaSAndroid Build Coastguard Worker                             backendTexture, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
216*c8dee2aaSAndroid Build Coastguard Worker                             kRead_GrIOType);
217*c8dee2aaSAndroid Build Coastguard Worker                     if (!tex) {
218*c8dee2aaSAndroid Build Coastguard Worker                         return {};
219*c8dee2aaSAndroid Build Coastguard Worker                     }
220*c8dee2aaSAndroid Build Coastguard Worker                     tex->setRelease(releaseProcHelper);
221*c8dee2aaSAndroid Build Coastguard Worker                     tex->resourcePriv().setUniqueKey(refHelper->fBorrowedTextureKey);
222*c8dee2aaSAndroid Build Coastguard Worker                 }
223*c8dee2aaSAndroid Build Coastguard Worker                 // We use keys to avoid re-wrapping the GrBackendTexture in a GrTexture.
224*c8dee2aaSAndroid Build Coastguard Worker                 // This is unrelated to the whatever SkImage key may be assigned to the
225*c8dee2aaSAndroid Build Coastguard Worker                 // proxy.
226*c8dee2aaSAndroid Build Coastguard Worker                 return {std::move(tex), true, GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
227*c8dee2aaSAndroid Build Coastguard Worker             },
228*c8dee2aaSAndroid Build Coastguard Worker             backendFormat,
229*c8dee2aaSAndroid Build Coastguard Worker             fBackendTexture.dimensions(),
230*c8dee2aaSAndroid Build Coastguard Worker             textureIsMipMapped,
231*c8dee2aaSAndroid Build Coastguard Worker             mipmapStatus,
232*c8dee2aaSAndroid Build Coastguard Worker             GrInternalSurfaceFlags::kReadOnly,
233*c8dee2aaSAndroid Build Coastguard Worker             SkBackingFit::kExact,
234*c8dee2aaSAndroid Build Coastguard Worker             skgpu::Budgeted::kNo,
235*c8dee2aaSAndroid Build Coastguard Worker             GrProtected::kNo,
236*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceProxy::UseAllocator::kYes,
237*c8dee2aaSAndroid Build Coastguard Worker             "BackendTextureImageGenerator");
238*c8dee2aaSAndroid Build Coastguard Worker     if (!proxy) {
239*c8dee2aaSAndroid Build Coastguard Worker         return {};
240*c8dee2aaSAndroid Build Coastguard Worker     }
241*c8dee2aaSAndroid Build Coastguard Worker 
242*c8dee2aaSAndroid Build Coastguard Worker     if (texGenPolicy == GrImageTexGenPolicy::kDraw &&
243*c8dee2aaSAndroid Build Coastguard Worker         (mipmapped == skgpu::Mipmapped::kNo || proxy->mipmapped() == skgpu::Mipmapped::kYes)) {
244*c8dee2aaSAndroid Build Coastguard Worker         // If we have the correct mip support, we're done
245*c8dee2aaSAndroid Build Coastguard Worker         return GrSurfaceProxyView(std::move(proxy), fSurfaceOrigin, readSwizzle);
246*c8dee2aaSAndroid Build Coastguard Worker     } else {
247*c8dee2aaSAndroid Build Coastguard Worker         skgpu::Budgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
248*c8dee2aaSAndroid Build Coastguard Worker                                            ? skgpu::Budgeted::kNo
249*c8dee2aaSAndroid Build Coastguard Worker                                            : skgpu::Budgeted::kYes;
250*c8dee2aaSAndroid Build Coastguard Worker 
251*c8dee2aaSAndroid Build Coastguard Worker         auto copy = GrSurfaceProxy::Copy(dContext,
252*c8dee2aaSAndroid Build Coastguard Worker                                          std::move(proxy),
253*c8dee2aaSAndroid Build Coastguard Worker                                          fSurfaceOrigin,
254*c8dee2aaSAndroid Build Coastguard Worker                                          mipmapped,
255*c8dee2aaSAndroid Build Coastguard Worker                                          SkIRect::MakeWH(info.width(), info.height()),
256*c8dee2aaSAndroid Build Coastguard Worker                                          SkBackingFit::kExact,
257*c8dee2aaSAndroid Build Coastguard Worker                                          budgeted,
258*c8dee2aaSAndroid Build Coastguard Worker                                          /*label=*/"BackendTextureImageGenerator_GenerateTexture");
259*c8dee2aaSAndroid Build Coastguard Worker         return {std::move(copy), fSurfaceOrigin, readSwizzle};
260*c8dee2aaSAndroid Build Coastguard Worker     }
261*c8dee2aaSAndroid Build Coastguard Worker }
262