Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2011 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 "GrTexture.h"
      9 #include "GrCaps.h"
     10 #include "GrContext.h"
     11 #include "GrContextPriv.h"
     12 #include "GrGpu.h"
     13 #include "GrRenderTarget.h"
     14 #include "GrResourceKey.h"
     15 #include "GrSurfacePriv.h"
     16 #include "GrTexturePriv.h"
     17 #include "GrTypes.h"
     18 #include "SkMath.h"
     19 #include "SkMipMap.h"
     20 #include "SkTypes.h"
     21 
     22 void GrTexture::markMipMapsDirty() {
     23     if (GrMipMapsStatus::kValid == fMipMapsStatus) {
     24         fMipMapsStatus = GrMipMapsStatus::kDirty;
     25     }
     26 }
     27 
     28 void GrTexture::markMipMapsClean() {
     29     SkASSERT(GrMipMapsStatus::kNotAllocated != fMipMapsStatus);
     30     fMipMapsStatus = GrMipMapsStatus::kValid;
     31 }
     32 
     33 size_t GrTexture::onGpuMemorySize() const {
     34     return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 1,
     35                                   this->texturePriv().mipMapped(), false);
     36 }
     37 
     38 /////////////////////////////////////////////////////////////////////////////
     39 GrTexture::GrTexture(GrGpu* gpu, const GrSurfaceDesc& desc, GrTextureType textureType,
     40                      GrMipMapsStatus mipMapsStatus)
     41         : INHERITED(gpu, desc), fTextureType(textureType), fMipMapsStatus(mipMapsStatus) {
     42     if (GrMipMapsStatus::kNotAllocated == fMipMapsStatus) {
     43         fMaxMipMapLevel = 0;
     44     } else {
     45         fMaxMipMapLevel = SkMipMap::ComputeLevelCount(this->width(), this->height());
     46     }
     47 }
     48 
     49 bool GrTexture::StealBackendTexture(sk_sp<GrTexture> texture,
     50                                     GrBackendTexture* backendTexture,
     51                                     SkImage::BackendTextureReleaseProc* releaseProc) {
     52     if (!texture->surfacePriv().hasUniqueRef() || texture->surfacePriv().hasPendingIO()) {
     53         return false;
     54     }
     55 
     56     if (!texture->onStealBackendTexture(backendTexture, releaseProc)) {
     57         return false;
     58     }
     59 #ifdef SK_DEBUG
     60     GrResourceCache* cache = texture->getContext()->contextPriv().getResourceCache();
     61     int preCount = cache->getResourceCount();
     62 #endif
     63     // Ensure that the texture will be released by the cache when we drop the last ref.
     64     // A texture that has no refs and no keys should be immediately removed.
     65     if (texture->getUniqueKey().isValid()) {
     66         texture->resourcePriv().removeUniqueKey();
     67     }
     68     if (texture->resourcePriv().getScratchKey().isValid()) {
     69         texture->resourcePriv().removeScratchKey();
     70     }
     71 #ifdef SK_DEBUG
     72     texture.reset();
     73     int postCount = cache->getResourceCount();
     74     SkASSERT(postCount < preCount);
     75 #endif
     76     return true;
     77 }
     78 
     79 void GrTexture::computeScratchKey(GrScratchKey* key) const {
     80     if (!GrPixelConfigIsCompressed(this->config())) {
     81         const GrRenderTarget* rt = this->asRenderTarget();
     82         int sampleCount = 1;
     83         if (rt) {
     84             sampleCount = rt->numStencilSamples();
     85         }
     86         GrTexturePriv::ComputeScratchKey(this->config(), this->width(), this->height(),
     87                                          SkToBool(rt), sampleCount,
     88                                          this->texturePriv().mipMapped(), key);
     89     }
     90 }
     91 
     92 void GrTexturePriv::ComputeScratchKey(GrPixelConfig config, int width, int height,
     93                                       bool isRenderTarget, int sampleCnt,
     94                                       GrMipMapped mipMapped, GrScratchKey* key) {
     95     static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType();
     96     uint32_t flags = isRenderTarget;
     97     SkASSERT(width > 0);
     98     SkASSERT(height > 0);
     99     SkASSERT(sampleCnt > 0);
    100     SkASSERT(1 == sampleCnt || isRenderTarget);
    101 
    102     // make sure desc.fConfig fits in 5 bits
    103     SkASSERT(sk_float_log2(kLast_GrPixelConfig) <= 5);
    104     SkASSERT(static_cast<int>(config) < (1 << 5));
    105     SkASSERT(sampleCnt < (1 << 8));
    106     SkASSERT(flags < (1 << 10));
    107     SkASSERT(static_cast<int>(mipMapped) <= 1);
    108 
    109     GrScratchKey::Builder builder(key, kType, 3);
    110     builder[0] = width;
    111     builder[1] = height;
    112     builder[2] = config | (static_cast<uint8_t>(mipMapped) << 5) | (sampleCnt << 6) | (flags << 14);
    113 }
    114 
    115 void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, GrScratchKey* key) {
    116     // Note: the fOrigin field is not used in the scratch key
    117     return ComputeScratchKey(desc.fConfig, desc.fWidth, desc.fHeight,
    118                              SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag), desc.fSampleCnt,
    119                              GrMipMapped::kNo, key);
    120 }
    121