1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxy.h"
9cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxyPriv.h"
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrDeferredProxyUploader.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrGpuResourcePriv.h"
15cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h"
16cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h"
17cb93a386Sopenharmony_ci#include "src/gpu/GrSurface.h"
18cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h"
19cb93a386Sopenharmony_ci
20cb93a386Sopenharmony_ci// Deferred version - no data
21cb93a386Sopenharmony_ciGrTextureProxy::GrTextureProxy(const GrBackendFormat& format,
22cb93a386Sopenharmony_ci                               SkISize dimensions,
23cb93a386Sopenharmony_ci                               GrMipmapped mipMapped,
24cb93a386Sopenharmony_ci                               GrMipmapStatus mipmapStatus,
25cb93a386Sopenharmony_ci                               SkBackingFit fit,
26cb93a386Sopenharmony_ci                               SkBudgeted budgeted,
27cb93a386Sopenharmony_ci                               GrProtected isProtected,
28cb93a386Sopenharmony_ci                               GrInternalSurfaceFlags surfaceFlags,
29cb93a386Sopenharmony_ci                               UseAllocator useAllocator,
30cb93a386Sopenharmony_ci                               GrDDLProvider creatingProvider)
31cb93a386Sopenharmony_ci        : INHERITED(format, dimensions, fit, budgeted, isProtected, surfaceFlags, useAllocator)
32cb93a386Sopenharmony_ci        , fMipmapped(mipMapped)
33cb93a386Sopenharmony_ci        , fMipmapStatus(mipmapStatus)
34cb93a386Sopenharmony_ci        SkDEBUGCODE(, fInitialMipmapStatus(fMipmapStatus))
35cb93a386Sopenharmony_ci        , fCreatingProvider(creatingProvider)
36cb93a386Sopenharmony_ci        , fProxyProvider(nullptr)
37cb93a386Sopenharmony_ci        , fDeferredUploader(nullptr) {
38cb93a386Sopenharmony_ci    SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly));
39cb93a386Sopenharmony_ci    if (this->textureType() == GrTextureType::kExternal) {
40cb93a386Sopenharmony_ci        fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
41cb93a386Sopenharmony_ci    }
42cb93a386Sopenharmony_ci}
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_ci// Lazy-callback version
45cb93a386Sopenharmony_ciGrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback,
46cb93a386Sopenharmony_ci                               const GrBackendFormat& format,
47cb93a386Sopenharmony_ci                               SkISize dimensions,
48cb93a386Sopenharmony_ci                               GrMipmapped mipMapped,
49cb93a386Sopenharmony_ci                               GrMipmapStatus mipmapStatus,
50cb93a386Sopenharmony_ci                               SkBackingFit fit,
51cb93a386Sopenharmony_ci                               SkBudgeted budgeted,
52cb93a386Sopenharmony_ci                               GrProtected isProtected,
53cb93a386Sopenharmony_ci                               GrInternalSurfaceFlags surfaceFlags,
54cb93a386Sopenharmony_ci                               UseAllocator useAllocator,
55cb93a386Sopenharmony_ci                               GrDDLProvider creatingProvider)
56cb93a386Sopenharmony_ci        : INHERITED(std::move(callback), format, dimensions, fit, budgeted, isProtected,
57cb93a386Sopenharmony_ci                    surfaceFlags, useAllocator)
58cb93a386Sopenharmony_ci        , fMipmapped(mipMapped)
59cb93a386Sopenharmony_ci        , fMipmapStatus(mipmapStatus)
60cb93a386Sopenharmony_ci        SkDEBUGCODE(, fInitialMipmapStatus(fMipmapStatus))
61cb93a386Sopenharmony_ci        , fCreatingProvider(creatingProvider)
62cb93a386Sopenharmony_ci        , fProxyProvider(nullptr)
63cb93a386Sopenharmony_ci        , fDeferredUploader(nullptr) {
64cb93a386Sopenharmony_ci    SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly));
65cb93a386Sopenharmony_ci    if (this->textureType() == GrTextureType::kExternal) {
66cb93a386Sopenharmony_ci        fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
67cb93a386Sopenharmony_ci    }
68cb93a386Sopenharmony_ci}
69cb93a386Sopenharmony_ci
70cb93a386Sopenharmony_ci// Wrapped version
71cb93a386Sopenharmony_ciGrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf,
72cb93a386Sopenharmony_ci                               UseAllocator useAllocator,
73cb93a386Sopenharmony_ci                               GrDDLProvider creatingProvider)
74cb93a386Sopenharmony_ci        : INHERITED(std::move(surf), SkBackingFit::kExact, useAllocator)
75cb93a386Sopenharmony_ci        , fMipmapped(fTarget->asTexture()->mipmapped())
76cb93a386Sopenharmony_ci        , fMipmapStatus(fTarget->asTexture()->mipmapStatus())
77cb93a386Sopenharmony_ci        SkDEBUGCODE(, fInitialMipmapStatus(fMipmapStatus))
78cb93a386Sopenharmony_ci        , fCreatingProvider(creatingProvider)
79cb93a386Sopenharmony_ci        , fProxyProvider(nullptr)
80cb93a386Sopenharmony_ci        , fDeferredUploader(nullptr) {
81cb93a386Sopenharmony_ci    if (fTarget->getUniqueKey().isValid()) {
82cb93a386Sopenharmony_ci        fProxyProvider = fTarget->asTexture()->getContext()->priv().proxyProvider();
83cb93a386Sopenharmony_ci        fProxyProvider->adoptUniqueKeyFromSurface(this, fTarget.get());
84cb93a386Sopenharmony_ci    }
85cb93a386Sopenharmony_ci    if (this->textureType() == GrTextureType::kExternal) {
86cb93a386Sopenharmony_ci        fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
87cb93a386Sopenharmony_ci    }
88cb93a386Sopenharmony_ci}
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ciGrTextureProxy::~GrTextureProxy() {
91cb93a386Sopenharmony_ci    // Due to the order of cleanup the GrSurface this proxy may have wrapped may have gone away
92cb93a386Sopenharmony_ci    // at this point. Zero out the pointer so the cache invalidation code doesn't try to use it.
93cb93a386Sopenharmony_ci    fTarget = nullptr;
94cb93a386Sopenharmony_ci
95cb93a386Sopenharmony_ci    // In DDL-mode, uniquely keyed proxies keep their key even after their originating
96cb93a386Sopenharmony_ci    // proxy provider has gone away. In that case there is noone to send the invalid key
97cb93a386Sopenharmony_ci    // message to (Note: in this case we don't want to remove its cached resource).
98cb93a386Sopenharmony_ci    if (fUniqueKey.isValid() && fProxyProvider) {
99cb93a386Sopenharmony_ci        sk_sp<GrGpuResource> invalidGpuResource;
100cb93a386Sopenharmony_ci        auto direct = fProxyProvider->getfImageContext()->asDirectContext();
101cb93a386Sopenharmony_ci        if (direct) {
102cb93a386Sopenharmony_ci            GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
103cb93a386Sopenharmony_ci            if (resourceProvider) {
104cb93a386Sopenharmony_ci                invalidGpuResource = resourceProvider->findByUniqueKey<GrGpuResource>(fUniqueKey);
105cb93a386Sopenharmony_ci            }
106cb93a386Sopenharmony_ci        }
107cb93a386Sopenharmony_ci        // less than 1024 Bytes resources will be delated
108cb93a386Sopenharmony_ci        if (invalidGpuResource && invalidGpuResource->gpuMemorySize() < 1024) {
109cb93a386Sopenharmony_ci            fProxyProvider->processInvalidUniqueKey(
110cb93a386Sopenharmony_ci                fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kYes);
111cb93a386Sopenharmony_ci        } else {
112cb93a386Sopenharmony_ci            fProxyProvider->processInvalidUniqueKey(
113cb93a386Sopenharmony_ci                fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kNo);
114cb93a386Sopenharmony_ci        }
115cb93a386Sopenharmony_ci    } else {
116cb93a386Sopenharmony_ci        SkASSERT(!fProxyProvider);
117cb93a386Sopenharmony_ci    }
118cb93a386Sopenharmony_ci}
119cb93a386Sopenharmony_ci
120cb93a386Sopenharmony_cibool GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) {
121cb93a386Sopenharmony_ci    if (this->isLazy()) {
122cb93a386Sopenharmony_ci        return false;
123cb93a386Sopenharmony_ci    }
124cb93a386Sopenharmony_ci    if (!this->instantiateImpl(resourceProvider, 1, GrRenderable::kNo, fMipmapped,
125cb93a386Sopenharmony_ci                               fUniqueKey.isValid() ? &fUniqueKey : nullptr)) {
126cb93a386Sopenharmony_ci        return false;
127cb93a386Sopenharmony_ci    }
128cb93a386Sopenharmony_ci
129cb93a386Sopenharmony_ci    SkASSERT(!this->peekRenderTarget());
130cb93a386Sopenharmony_ci    SkASSERT(this->peekTexture());
131cb93a386Sopenharmony_ci    return true;
132cb93a386Sopenharmony_ci}
133cb93a386Sopenharmony_ci
134cb93a386Sopenharmony_cisk_sp<GrSurface> GrTextureProxy::createSurface(GrResourceProvider* resourceProvider) const {
135cb93a386Sopenharmony_ci    sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, 1, GrRenderable::kNo,
136cb93a386Sopenharmony_ci                                                       fMipmapped);
137cb93a386Sopenharmony_ci    if (!surface) {
138cb93a386Sopenharmony_ci        return nullptr;
139cb93a386Sopenharmony_ci    }
140cb93a386Sopenharmony_ci
141cb93a386Sopenharmony_ci    if (fUserCacheTaget) {
142cb93a386Sopenharmony_ci        if (!(surface->getUniqueKey().isValid()) && !(surface->resourcePriv().getScratchKey().isValid())) {
143cb93a386Sopenharmony_ci            surface->resourcePriv().userRegisterResource();
144cb93a386Sopenharmony_ci        }
145cb93a386Sopenharmony_ci    }
146cb93a386Sopenharmony_ci
147cb93a386Sopenharmony_ci    SkASSERT(!surface->asRenderTarget());
148cb93a386Sopenharmony_ci    SkASSERT(surface->asTexture());
149cb93a386Sopenharmony_ci    return surface;
150cb93a386Sopenharmony_ci}
151cb93a386Sopenharmony_ci
152cb93a386Sopenharmony_civoid GrTextureProxyPriv::setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader) {
153cb93a386Sopenharmony_ci    SkASSERT(!fTextureProxy->fDeferredUploader);
154cb93a386Sopenharmony_ci    fTextureProxy->fDeferredUploader = std::move(uploader);
155cb93a386Sopenharmony_ci}
156cb93a386Sopenharmony_ci
157cb93a386Sopenharmony_civoid GrTextureProxyPriv::scheduleUpload(GrOpFlushState* flushState) {
158cb93a386Sopenharmony_ci    // The texture proxy's contents may already have been uploaded or instantiation may have failed
159cb93a386Sopenharmony_ci    if (fTextureProxy->fDeferredUploader && fTextureProxy->isInstantiated()) {
160cb93a386Sopenharmony_ci        fTextureProxy->fDeferredUploader->scheduleUpload(flushState, fTextureProxy);
161cb93a386Sopenharmony_ci    }
162cb93a386Sopenharmony_ci}
163cb93a386Sopenharmony_ci
164cb93a386Sopenharmony_civoid GrTextureProxyPriv::resetDeferredUploader() {
165cb93a386Sopenharmony_ci    SkASSERT(fTextureProxy->fDeferredUploader);
166cb93a386Sopenharmony_ci    fTextureProxy->fDeferredUploader.reset();
167cb93a386Sopenharmony_ci}
168cb93a386Sopenharmony_ci
169cb93a386Sopenharmony_ciGrMipmapped GrTextureProxy::mipmapped() const {
170cb93a386Sopenharmony_ci    if (this->isInstantiated()) {
171cb93a386Sopenharmony_ci        return this->peekTexture()->mipmapped();
172cb93a386Sopenharmony_ci    }
173cb93a386Sopenharmony_ci    return fMipmapped;
174cb93a386Sopenharmony_ci}
175cb93a386Sopenharmony_ci
176cb93a386Sopenharmony_cisize_t GrTextureProxy::onUninstantiatedGpuMemorySize() const {
177cb93a386Sopenharmony_ci    return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
178cb93a386Sopenharmony_ci                                  /*colorSamplesPerPixel=*/1, this->proxyMipmapped(),
179cb93a386Sopenharmony_ci                                  !this->priv().isExact());
180cb93a386Sopenharmony_ci}
181cb93a386Sopenharmony_ci
182cb93a386Sopenharmony_cibool GrTextureProxy::ProxiesAreCompatibleAsDynamicState(const GrSurfaceProxy* first,
183cb93a386Sopenharmony_ci                                                        const GrSurfaceProxy* second) {
184cb93a386Sopenharmony_ci    // In order to be compatible, the proxies should also have the same texture type. This is
185cb93a386Sopenharmony_ci    // checked explicitly since the GrBackendFormat == operator does not compare texture type
186cb93a386Sopenharmony_ci    return first->backendFormat().textureType() == second->backendFormat().textureType() &&
187cb93a386Sopenharmony_ci           first->backendFormat() == second->backendFormat();
188cb93a386Sopenharmony_ci}
189cb93a386Sopenharmony_ci
190cb93a386Sopenharmony_civoid GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) {
191cb93a386Sopenharmony_ci    SkASSERT(key.isValid());
192cb93a386Sopenharmony_ci    SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
193cb93a386Sopenharmony_ci
194cb93a386Sopenharmony_ci    if (fTarget && fSyncTargetKey) {
195cb93a386Sopenharmony_ci        if (!fTarget->getUniqueKey().isValid()) {
196cb93a386Sopenharmony_ci            fTarget->resourcePriv().setUniqueKey(key);
197cb93a386Sopenharmony_ci        }
198cb93a386Sopenharmony_ci        SkASSERT(fTarget->getUniqueKey() == key);
199cb93a386Sopenharmony_ci    }
200cb93a386Sopenharmony_ci
201cb93a386Sopenharmony_ci    fUniqueKey = key;
202cb93a386Sopenharmony_ci    fProxyProvider = proxyProvider;
203cb93a386Sopenharmony_ci}
204cb93a386Sopenharmony_ci
205cb93a386Sopenharmony_civoid GrTextureProxy::clearUniqueKey() {
206cb93a386Sopenharmony_ci    fUniqueKey.reset();
207cb93a386Sopenharmony_ci    fProxyProvider = nullptr;
208cb93a386Sopenharmony_ci}
209cb93a386Sopenharmony_ci
210cb93a386Sopenharmony_ciGrSurfaceProxy::LazySurfaceDesc GrTextureProxy::callbackDesc() const {
211cb93a386Sopenharmony_ci    SkISize dims;
212cb93a386Sopenharmony_ci    SkBackingFit fit;
213cb93a386Sopenharmony_ci    if (this->isFullyLazy()) {
214cb93a386Sopenharmony_ci        fit = SkBackingFit::kApprox;
215cb93a386Sopenharmony_ci        dims = {-1, -1};
216cb93a386Sopenharmony_ci    } else {
217cb93a386Sopenharmony_ci        fit = this->isFunctionallyExact() ? SkBackingFit::kExact : SkBackingFit::kApprox;
218cb93a386Sopenharmony_ci        dims = this->dimensions();
219cb93a386Sopenharmony_ci    }
220cb93a386Sopenharmony_ci    return {
221cb93a386Sopenharmony_ci            dims,
222cb93a386Sopenharmony_ci            fit,
223cb93a386Sopenharmony_ci            GrRenderable::kNo,
224cb93a386Sopenharmony_ci            fMipmapped,
225cb93a386Sopenharmony_ci            1,
226cb93a386Sopenharmony_ci            this->backendFormat(),
227cb93a386Sopenharmony_ci            this->textureType(),
228cb93a386Sopenharmony_ci            this->isProtected(),
229cb93a386Sopenharmony_ci            this->isBudgeted(),
230cb93a386Sopenharmony_ci    };
231cb93a386Sopenharmony_ci}
232cb93a386Sopenharmony_ci
233cb93a386Sopenharmony_ci#ifdef SK_DEBUG
234cb93a386Sopenharmony_civoid GrTextureProxy::onValidateSurface(const GrSurface* surface) {
235cb93a386Sopenharmony_ci    SkASSERT(!surface->asRenderTarget());
236cb93a386Sopenharmony_ci
237cb93a386Sopenharmony_ci    // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
238cb93a386Sopenharmony_ci    SkASSERT(surface->asTexture());
239cb93a386Sopenharmony_ci    // It is possible to fulfill a non-mipmapped proxy with a mipmapped texture.
240cb93a386Sopenharmony_ci    SkASSERT(GrMipmapped::kNo == this->proxyMipmapped() ||
241cb93a386Sopenharmony_ci             GrMipmapped::kYes == surface->asTexture()->mipmapped());
242cb93a386Sopenharmony_ci
243cb93a386Sopenharmony_ci    SkASSERT(surface->asTexture()->textureType() == this->textureType());
244cb93a386Sopenharmony_ci
245cb93a386Sopenharmony_ci    GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
246cb93a386Sopenharmony_ci    GrInternalSurfaceFlags surfaceFlags = surface->flags();
247cb93a386Sopenharmony_ci    SkASSERT(((int)proxyFlags & kGrInternalTextureFlagsMask) ==
248cb93a386Sopenharmony_ci             ((int)surfaceFlags & kGrInternalTextureFlagsMask));
249cb93a386Sopenharmony_ci}
250cb93a386Sopenharmony_ci
251cb93a386Sopenharmony_ci#endif
252cb93a386Sopenharmony_ci
253