Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #include "GrGpuResource.h"
     10 #include "GrResourceCache.h"
     11 #include "GrGpu.h"
     12 #include "GrGpuResourcePriv.h"
     13 
     14 static inline GrResourceCache* get_resource_cache(GrGpu* gpu) {
     15     SkASSERT(gpu);
     16     SkASSERT(gpu->getContext());
     17     SkASSERT(gpu->getContext()->getResourceCache());
     18     return gpu->getContext()->getResourceCache();
     19 }
     20 
     21 GrGpuResource::GrGpuResource(GrGpu* gpu, LifeCycle lifeCycle)
     22     : fGpu(gpu)
     23     , fGpuMemorySize(kInvalidGpuMemorySize)
     24     , fLifeCycle(lifeCycle)
     25     , fUniqueID(CreateUniqueID()) {
     26     SkDEBUGCODE(fCacheArrayIndex = -1);
     27 }
     28 
     29 void GrGpuResource::registerWithCache() {
     30     get_resource_cache(fGpu)->resourceAccess().insertResource(this);
     31 }
     32 
     33 GrGpuResource::~GrGpuResource() {
     34     // The cache should have released or destroyed this resource.
     35     SkASSERT(this->wasDestroyed());
     36 }
     37 
     38 void GrGpuResource::release() {
     39     SkASSERT(fGpu);
     40     this->onRelease();
     41     get_resource_cache(fGpu)->resourceAccess().removeResource(this);
     42     fGpu = NULL;
     43     fGpuMemorySize = 0;
     44 }
     45 
     46 void GrGpuResource::abandon() {
     47     SkASSERT(fGpu);
     48     this->onAbandon();
     49     get_resource_cache(fGpu)->resourceAccess().removeResource(this);
     50     fGpu = NULL;
     51     fGpuMemorySize = 0;
     52 }
     53 
     54 const SkData* GrGpuResource::setCustomData(const SkData* data) {
     55     SkSafeRef(data);
     56     fData.reset(data);
     57     return data;
     58 }
     59 
     60 const GrContext* GrGpuResource::getContext() const {
     61     if (fGpu) {
     62         return fGpu->getContext();
     63     } else {
     64         return NULL;
     65     }
     66 }
     67 
     68 GrContext* GrGpuResource::getContext() {
     69     if (fGpu) {
     70         return fGpu->getContext();
     71     } else {
     72         return NULL;
     73     }
     74 }
     75 
     76 void GrGpuResource::didChangeGpuMemorySize() const {
     77     if (this->wasDestroyed()) {
     78         return;
     79     }
     80 
     81     size_t oldSize = fGpuMemorySize;
     82     SkASSERT(kInvalidGpuMemorySize != oldSize);
     83     fGpuMemorySize = kInvalidGpuMemorySize;
     84     get_resource_cache(fGpu)->resourceAccess().didChangeGpuMemorySize(this, oldSize);
     85 }
     86 
     87 void GrGpuResource::removeUniqueKey() {
     88     SkASSERT(fUniqueKey.isValid());
     89     get_resource_cache(fGpu)->resourceAccess().removeUniqueKey(this);
     90 }
     91 
     92 void GrGpuResource::setUniqueKey(const GrUniqueKey& key) {
     93     SkASSERT(this->internalHasRef());
     94     SkASSERT(key.isValid());
     95 
     96     // Wrapped and uncached resources can never have a unique key.
     97     if (!this->resourcePriv().isBudgeted()) {
     98         return;
     99     }
    100 
    101     if (this->wasDestroyed()) {
    102         return;
    103     }
    104 
    105     get_resource_cache(fGpu)->resourceAccess().changeUniqueKey(this, key);
    106 }
    107 
    108 void GrGpuResource::notifyAllCntsAreZero(CntType lastCntTypeToReachZero) const {
    109     if (this->wasDestroyed()) {
    110         // We've already been removed from the cache. Goodbye cruel world!
    111         SkDELETE(this);
    112         return;
    113     }
    114 
    115     // We should have already handled this fully in notifyRefCntIsZero().
    116     SkASSERT(kRef_CntType != lastCntTypeToReachZero);
    117 
    118     GrGpuResource* mutableThis = const_cast<GrGpuResource*>(this);
    119     static const uint32_t kFlag =
    120         GrResourceCache::ResourceAccess::kAllCntsReachedZero_RefNotificationFlag;
    121     get_resource_cache(fGpu)->resourceAccess().notifyCntReachedZero(mutableThis, kFlag);
    122 }
    123 
    124 bool GrGpuResource::notifyRefCountIsZero() const {
    125     if (this->wasDestroyed()) {
    126         // handle this in notifyAllCntsAreZero().
    127         return true;
    128     }
    129 
    130     GrGpuResource* mutableThis = const_cast<GrGpuResource*>(this);
    131     uint32_t flags =
    132         GrResourceCache::ResourceAccess::kRefCntReachedZero_RefNotificationFlag;
    133     if (!this->internalHasPendingIO()) {
    134         flags |= GrResourceCache::ResourceAccess::kAllCntsReachedZero_RefNotificationFlag;
    135     }
    136     get_resource_cache(fGpu)->resourceAccess().notifyCntReachedZero(mutableThis, flags);
    137 
    138     // There is no need to call our notifyAllCntsAreZero function at this point since we already
    139     // told the cache about the state of cnts.
    140     return false;
    141 }
    142 
    143 void GrGpuResource::setScratchKey(const GrScratchKey& scratchKey) {
    144     SkASSERT(!fScratchKey.isValid());
    145     SkASSERT(scratchKey.isValid());
    146     // Wrapped resources can never have a scratch key.
    147     if (this->isWrapped()) {
    148         return;
    149     }
    150     fScratchKey = scratchKey;
    151 }
    152 
    153 void GrGpuResource::removeScratchKey() {
    154     if (!this->wasDestroyed() && fScratchKey.isValid()) {
    155         get_resource_cache(fGpu)->resourceAccess().willRemoveScratchKey(this);
    156         fScratchKey.reset();
    157     }
    158 }
    159 
    160 void GrGpuResource::makeBudgeted() {
    161     if (GrGpuResource::kUncached_LifeCycle == fLifeCycle) {
    162         fLifeCycle = kCached_LifeCycle;
    163         get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this);
    164     }
    165 }
    166 
    167 void GrGpuResource::makeUnbudgeted() {
    168     if (GrGpuResource::kCached_LifeCycle == fLifeCycle && !fUniqueKey.isValid()) {
    169         fLifeCycle = kUncached_LifeCycle;
    170         get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this);
    171     }
    172 }
    173 
    174 uint32_t GrGpuResource::CreateUniqueID() {
    175     static int32_t gUniqueID = SK_InvalidUniqueID;
    176     uint32_t id;
    177     do {
    178         id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
    179     } while (id == SK_InvalidUniqueID);
    180     return id;
    181 }
    182