Home | History | Annotate | Download | only in gpu
      1 /*
      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 "GrTextureProxy.h"
      9 #include "GrTextureProxyPriv.h"
     10 
     11 #include "GrContext.h"
     12 #include "GrContextPriv.h"
     13 #include "GrDeferredProxyUploader.h"
     14 #include "GrProxyProvider.h"
     15 #include "GrSurfacePriv.h"
     16 #include "GrTexturePriv.h"
     17 
     18 // Deferred version - with data
     19 GrTextureProxy::GrTextureProxy(const GrBackendFormat& format, const GrSurfaceDesc& srcDesc,
     20                                GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted,
     21                                const void* srcData, size_t /*rowBytes*/,
     22                                GrInternalSurfaceFlags surfaceFlags)
     23         : INHERITED(format, srcDesc, kTopLeft_GrSurfaceOrigin, fit, budgeted, surfaceFlags)
     24         , fMipMapped(mipMapped)
     25         , fProxyProvider(nullptr)
     26         , fDeferredUploader(nullptr) {
     27     SkASSERT(!srcData);  // currently handled in Make()
     28 }
     29 
     30 // Deferred version - no data
     31 GrTextureProxy::GrTextureProxy(const GrBackendFormat& format, const GrSurfaceDesc& srcDesc,
     32                                GrSurfaceOrigin origin, GrMipMapped mipMapped,
     33                                SkBackingFit fit, SkBudgeted budgeted,
     34                                GrInternalSurfaceFlags surfaceFlags)
     35         : INHERITED(format, srcDesc, origin, fit, budgeted, surfaceFlags)
     36         , fMipMapped(mipMapped)
     37         , fProxyProvider(nullptr)
     38         , fDeferredUploader(nullptr) {}
     39 
     40 // Lazy-callback version
     41 GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
     42                                const GrBackendFormat& format, const GrSurfaceDesc& desc,
     43                                GrSurfaceOrigin origin, GrMipMapped mipMapped, SkBackingFit fit,
     44                                SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
     45         : INHERITED(std::move(callback), lazyType, format, desc, origin, fit, budgeted,
     46                     surfaceFlags)
     47         , fMipMapped(mipMapped)
     48         , fProxyProvider(nullptr)
     49         , fDeferredUploader(nullptr) {}
     50 
     51 // Wrapped version
     52 GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin)
     53         : INHERITED(std::move(surf), origin, SkBackingFit::kExact)
     54         , fMipMapped(fTarget->asTexture()->texturePriv().mipMapped())
     55         , fProxyProvider(nullptr)
     56         , fDeferredUploader(nullptr) {
     57     if (fTarget->getUniqueKey().isValid()) {
     58         fProxyProvider = fTarget->asTexture()->getContext()->priv().proxyProvider();
     59         fProxyProvider->adoptUniqueKeyFromSurface(this, fTarget);
     60     }
     61 }
     62 
     63 GrTextureProxy::~GrTextureProxy() {
     64     // Due to the order of cleanup the GrSurface this proxy may have wrapped may have gone away
     65     // at this point. Zero out the pointer so the cache invalidation code doesn't try to use it.
     66     fTarget = nullptr;
     67 
     68     // In DDL-mode, uniquely keyed proxies keep their key even after their originating
     69     // proxy provider has gone away. In that case there is noone to send the invalid key
     70     // message to (Note: in this case we don't want to remove its cached resource).
     71     if (fUniqueKey.isValid() && fProxyProvider) {
     72         fProxyProvider->processInvalidUniqueKey(fUniqueKey, this,
     73                                                 GrProxyProvider::InvalidateGPUResource::kNo);
     74     } else {
     75         SkASSERT(!fProxyProvider);
     76     }
     77 }
     78 
     79 bool GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) {
     80     if (LazyState::kNot != this->lazyInstantiationState()) {
     81         return false;
     82     }
     83     if (!this->instantiateImpl(resourceProvider, 1, /* needsStencil = */ false,
     84                                kNone_GrSurfaceFlags, fMipMapped,
     85                                fUniqueKey.isValid() ? &fUniqueKey : nullptr)) {
     86         return false;
     87     }
     88 
     89     SkASSERT(!fTarget->asRenderTarget());
     90     SkASSERT(fTarget->asTexture());
     91     return true;
     92 }
     93 
     94 sk_sp<GrSurface> GrTextureProxy::createSurface(GrResourceProvider* resourceProvider) const {
     95     sk_sp<GrSurface> surface= this->createSurfaceImpl(resourceProvider, 1,
     96                                                       /* needsStencil = */ false,
     97                                                       kNone_GrSurfaceFlags,
     98                                                       fMipMapped);
     99     if (!surface) {
    100         return nullptr;
    101     }
    102 
    103     SkASSERT(!surface->asRenderTarget());
    104     SkASSERT(surface->asTexture());
    105     return surface;
    106 }
    107 
    108 void GrTextureProxyPriv::setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader) {
    109     SkASSERT(!fTextureProxy->fDeferredUploader);
    110     fTextureProxy->fDeferredUploader = std::move(uploader);
    111 }
    112 
    113 void GrTextureProxyPriv::scheduleUpload(GrOpFlushState* flushState) {
    114     // The texture proxy's contents may already have been uploaded or instantiation may have failed
    115     if (fTextureProxy->fDeferredUploader && fTextureProxy->fTarget) {
    116         fTextureProxy->fDeferredUploader->scheduleUpload(flushState, fTextureProxy);
    117     }
    118 }
    119 
    120 void GrTextureProxyPriv::resetDeferredUploader() {
    121     SkASSERT(fTextureProxy->fDeferredUploader);
    122     fTextureProxy->fDeferredUploader.reset();
    123 }
    124 
    125 GrSamplerState::Filter GrTextureProxy::highestFilterMode() const {
    126     return this->hasRestrictedSampling() ? GrSamplerState::Filter::kBilerp
    127                                          : GrSamplerState::Filter::kMipMap;
    128 }
    129 
    130 GrMipMapped GrTextureProxy::mipMapped() const {
    131     if (this->isInstantiated()) {
    132         return this->peekTexture()->texturePriv().mipMapped();
    133     }
    134     return fMipMapped;
    135 }
    136 
    137 size_t GrTextureProxy::onUninstantiatedGpuMemorySize() const {
    138     return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 1,
    139                                   this->proxyMipMapped(), !this->priv().isExact());
    140 }
    141 
    142 bool GrTextureProxy::ProxiesAreCompatibleAsDynamicState(const GrTextureProxy* first,
    143                                                         const GrTextureProxy* second) {
    144     return first->config() == second->config() &&
    145            first->textureType() == second->textureType() &&
    146            first->backendFormat() == second->backendFormat();
    147 }
    148 
    149 void GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) {
    150     SkASSERT(key.isValid());
    151     SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
    152 
    153     if (fTarget) {
    154         if (!fTarget->getUniqueKey().isValid()) {
    155             fTarget->resourcePriv().setUniqueKey(key);
    156         }
    157         SkASSERT(fTarget->getUniqueKey() == key);
    158     }
    159 
    160     fUniqueKey = key;
    161     fProxyProvider = proxyProvider;
    162 }
    163 
    164 void GrTextureProxy::clearUniqueKey() {
    165     fUniqueKey.reset();
    166     fProxyProvider = nullptr;
    167 }
    168 
    169 #ifdef SK_DEBUG
    170 void GrTextureProxy::onValidateSurface(const GrSurface* surface) {
    171     SkASSERT(!surface->asRenderTarget());
    172 
    173     // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
    174     SkASSERT(surface->asTexture());
    175     SkASSERT(GrMipMapped::kNo == this->proxyMipMapped() ||
    176              GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
    177 
    178     SkASSERT(surface->asTexture()->texturePriv().textureType() == this->textureType());
    179 
    180     GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
    181     GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags();
    182     SkASSERT((proxyFlags & GrInternalSurfaceFlags::kTextureMask) ==
    183              (surfaceFlags & GrInternalSurfaceFlags::kTextureMask));
    184 }
    185 
    186 #endif
    187 
    188