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