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 "GrTexturePriv.h"
     16 
     17 // Deferred version
     18 GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped mipMapped,
     19                                SkBackingFit fit, SkBudgeted budgeted, const void* srcData,
     20                                size_t /*rowBytes*/, uint32_t flags)
     21         : INHERITED(srcDesc, fit, budgeted, flags)
     22         , fMipMapped(mipMapped)
     23         , fProxyProvider(nullptr)
     24         , fDeferredUploader(nullptr) {
     25     SkASSERT(!srcData);  // currently handled in Make()
     26 }
     27 
     28 // Lazy-callback version
     29 GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
     30                                const GrSurfaceDesc& desc, GrMipMapped mipMapped, SkBackingFit fit,
     31                                SkBudgeted budgeted, uint32_t flags)
     32         : INHERITED(std::move(callback), lazyType, desc, fit, budgeted, flags)
     33         , fMipMapped(mipMapped)
     34         , fProxyProvider(nullptr)
     35         , fDeferredUploader(nullptr) {
     36 }
     37 
     38 // Wrapped version
     39 GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin)
     40         : INHERITED(std::move(surf), origin, SkBackingFit::kExact)
     41         , fMipMapped(fTarget->asTexture()->texturePriv().mipMapped())
     42         , fProxyProvider(nullptr)
     43         , fDeferredUploader(nullptr) {
     44     if (fTarget->getUniqueKey().isValid()) {
     45         fProxyProvider = fTarget->asTexture()->getContext()->contextPriv().proxyProvider();
     46         fProxyProvider->adoptUniqueKeyFromSurface(this, fTarget);
     47     }
     48 }
     49 
     50 GrTextureProxy::~GrTextureProxy() {
     51     // Due to the order of cleanup the GrSurface this proxy may have wrapped may have gone away
     52     // at this point. Zero out the pointer so the cache invalidation code doesn't try to use it.
     53     fTarget = nullptr;
     54     if (fUniqueKey.isValid()) {
     55         fProxyProvider->processInvalidProxyUniqueKey(fUniqueKey, this, false);
     56     } else {
     57         SkASSERT(!fProxyProvider);
     58     }
     59 }
     60 
     61 bool GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) {
     62     if (LazyState::kNot != this->lazyInstantiationState()) {
     63         return false;
     64     }
     65     if (!this->instantiateImpl(resourceProvider, 1, /* needsStencil = */ false,
     66                                kNone_GrSurfaceFlags, fMipMapped,
     67                                fUniqueKey.isValid() ? &fUniqueKey : nullptr)) {
     68         return false;
     69     }
     70 
     71     SkASSERT(!fTarget->asRenderTarget());
     72     SkASSERT(fTarget->asTexture());
     73     return true;
     74 }
     75 
     76 sk_sp<GrSurface> GrTextureProxy::createSurface(GrResourceProvider* resourceProvider) const {
     77     sk_sp<GrSurface> surface= this->createSurfaceImpl(resourceProvider, 1,
     78                                                       /* needsStencil = */ false,
     79                                                       kNone_GrSurfaceFlags,
     80                                                       fMipMapped);
     81     if (!surface) {
     82         return nullptr;
     83     }
     84 
     85     SkASSERT(!surface->asRenderTarget());
     86     SkASSERT(surface->asTexture());
     87     return surface;
     88 }
     89 
     90 void GrTextureProxyPriv::setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader) {
     91     SkASSERT(!fTextureProxy->fDeferredUploader);
     92     fTextureProxy->fDeferredUploader = std::move(uploader);
     93 }
     94 
     95 void GrTextureProxyPriv::scheduleUpload(GrOpFlushState* flushState) {
     96     // The texture proxy's contents may already have been uploaded or instantiation may have failed
     97     if (fTextureProxy->fDeferredUploader && fTextureProxy->fTarget) {
     98         fTextureProxy->fDeferredUploader->scheduleUpload(flushState, fTextureProxy);
     99     }
    100 }
    101 
    102 void GrTextureProxyPriv::resetDeferredUploader() {
    103     SkASSERT(fTextureProxy->fDeferredUploader);
    104     fTextureProxy->fDeferredUploader.reset();
    105 }
    106 
    107 // This method parallels the highest_filter_mode functions in GrGLTexture & GrVkTexture.
    108 GrSamplerState::Filter GrTextureProxy::highestFilterMode() const {
    109     if (fTarget) {
    110         return fTarget->asTexture()->texturePriv().highestFilterMode();
    111     }
    112 
    113     // In OpenGL, GR_GL_TEXTURE_RECTANGLE and GR_GL_TEXTURE_EXTERNAL (which have a highest filter
    114     // mode of bilerp) can only be created via wrapping.
    115 
    116     return GrSamplerState::Filter::kMipMap;
    117 }
    118 
    119 GrMipMapped GrTextureProxy::mipMapped() const {
    120     if (this->priv().isInstantiated()) {
    121         return this->priv().peekTexture()->texturePriv().mipMapped();
    122     }
    123     return fMipMapped;
    124 }
    125 
    126 size_t GrTextureProxy::onUninstantiatedGpuMemorySize() const {
    127     return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 1,
    128                                   this->texPriv().proxyMipMapped(), !this->priv().isExact());
    129 }
    130 
    131 void GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) {
    132     SkASSERT(key.isValid());
    133     SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
    134 
    135     if (fTarget) {
    136         if (!fTarget->getUniqueKey().isValid()) {
    137             fTarget->resourcePriv().setUniqueKey(key);
    138         }
    139         SkASSERT(fTarget->getUniqueKey() == key);
    140     }
    141 
    142     fUniqueKey = key;
    143     fProxyProvider = proxyProvider;
    144 }
    145 
    146 void GrTextureProxy::clearUniqueKey() {
    147     fUniqueKey.reset();
    148     fProxyProvider = nullptr;
    149 }
    150 
    151 #ifdef SK_DEBUG
    152 void GrTextureProxy::validateLazySurface(const GrSurface* surface) {
    153     SkASSERT(!surface->asRenderTarget());
    154 
    155     // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
    156     SkASSERT(surface->asTexture());
    157     SkASSERT(GrMipMapped::kNo == this->texPriv().proxyMipMapped() ||
    158              GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
    159 }
    160 #endif
    161 
    162