Make all GrContext members that return a texture also ref the texture for the caller.
Review URL: https://codereview.appspot.com/7198049 git-svn-id: http://skia.googlecode.com/svn/trunk@7362 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
baa0220dfd
commit
95ed55adc6
@ -118,7 +118,8 @@ public:
|
||||
// Textures
|
||||
|
||||
/**
|
||||
* Create a new entry, based on the specified key and texture and return it.
|
||||
* Creates a new entry, based on the specified key and texture and returns it. The caller owns a
|
||||
* ref on the returned texture which must be balanced by a call to unref.
|
||||
*
|
||||
* @param params The texture params used to draw a texture may help determine
|
||||
* the cache entry used. (e.g. different versions may exist
|
||||
@ -136,8 +137,8 @@ public:
|
||||
void* srcData, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* Search for an entry based on key and dimensions. If found,
|
||||
* return it. The return value will be NULL if not found.
|
||||
* Search for an entry based on key and dimensions. If found, ref it and return it. The return
|
||||
* value will be NULL if not found. The caller must balance with a call to unref.
|
||||
*
|
||||
* @param desc Description of the texture properties.
|
||||
* @param cacheID Cache-specific properties (e.g., texture gen ID)
|
||||
@ -146,9 +147,9 @@ public:
|
||||
* for different wrap modes on GPUs with limited NPOT
|
||||
* texture support). NULL implies clamp wrap modes.
|
||||
*/
|
||||
GrTexture* findTexture(const GrTextureDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrTextureParams* params);
|
||||
GrTexture* findAndRefTexture(const GrTextureDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrTextureParams* params);
|
||||
/**
|
||||
* Determines whether a texture is in the cache. If the texture is found it
|
||||
* will not be locked or returned. This call does not affect the priority of
|
||||
@ -182,7 +183,8 @@ public:
|
||||
* Returns a texture matching the desc. It's contents are unknown. Subsequent
|
||||
* requests with the same descriptor are not guaranteed to return the same
|
||||
* texture. The same texture is guaranteed not be returned again until it is
|
||||
* unlocked. Call must be balanced with an unlockTexture() call.
|
||||
* unlocked. Call must be balanced with an unlockTexture() call. The caller
|
||||
* owns a ref on the returned texture and must balance with a call to unref.
|
||||
*
|
||||
* Textures created by createAndLockTexture() hide the complications of
|
||||
* tiling non-power-of-two textures on APIs that don't support this (e.g.
|
||||
@ -190,11 +192,11 @@ public:
|
||||
* such an API will create gaps in the tiling pattern. This includes clamp
|
||||
* mode. (This may be addressed in a future update.)
|
||||
*/
|
||||
GrTexture* lockScratchTexture(const GrTextureDesc&, ScratchTexMatch match);
|
||||
GrTexture* lockAndRefScratchTexture(const GrTextureDesc&, ScratchTexMatch match);
|
||||
|
||||
/**
|
||||
* When done with an entry, call unlockScratchTexture(entry) on it, which returns
|
||||
* it to the cache, where it may be purged.
|
||||
* it to the cache, where it may be purged. This does not unref the texture.
|
||||
*/
|
||||
void unlockScratchTexture(GrTexture* texture);
|
||||
|
||||
@ -946,6 +948,7 @@ public:
|
||||
void reset() {
|
||||
if (NULL != fContext && NULL != fTexture) {
|
||||
fContext->unlockScratchTexture(fTexture);
|
||||
fTexture->unref();
|
||||
fTexture = NULL;
|
||||
}
|
||||
}
|
||||
@ -956,23 +959,26 @@ public:
|
||||
* "locked" in the texture cache until it is freed and recycled in
|
||||
* GrTexture::internal_dispose. In reality, the texture has been removed
|
||||
* from the cache (because this is in AutoScratchTexture) and by not
|
||||
* calling unlockTexture we simply don't re-add it. It will be reattached
|
||||
* in GrTexture::internal_dispose.
|
||||
* calling unlockScratchTexture we simply don't re-add it. It will be
|
||||
* reattached in GrTexture::internal_dispose.
|
||||
*
|
||||
* Note that the caller is assumed to accept and manage the ref to the
|
||||
* returned texture.
|
||||
*/
|
||||
GrTexture* detach() {
|
||||
GrTexture* temp = fTexture;
|
||||
|
||||
// Conceptually the texture's cache entry loses its ref to the
|
||||
// texture while the caller of this method gets a ref.
|
||||
GrAssert(NULL != temp->getCacheEntry());
|
||||
|
||||
GrTexture* texture = fTexture;
|
||||
fTexture = NULL;
|
||||
|
||||
temp->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
|
||||
return temp;
|
||||
// This GrAutoScratchTexture has a ref from lockAndRefScratchTexture, which we give up now.
|
||||
// The cache also has a ref which we are lending to the caller of detach(). When the caller
|
||||
// lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is
|
||||
// set and re-ref the texture, thereby restoring the cache's ref.
|
||||
GrAssert(texture->getRefCnt() > 1);
|
||||
texture->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
|
||||
texture->unref();
|
||||
GrAssert(NULL != texture->getCacheEntry());
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
GrTexture* set(GrContext* context,
|
||||
@ -982,7 +988,7 @@ public:
|
||||
|
||||
fContext = context;
|
||||
if (NULL != fContext) {
|
||||
fTexture = fContext->lockScratchTexture(desc, match);
|
||||
fTexture = fContext->lockAndRefScratchTexture(desc, match);
|
||||
if (NULL == fTexture) {
|
||||
fContext = NULL;
|
||||
}
|
||||
|
@ -77,9 +77,9 @@ static inline GrColor SkColor2GrColor(SkColor c) {
|
||||
|
||||
bool GrIsBitmapInCache(const GrContext*, const SkBitmap&, const GrTextureParams*);
|
||||
|
||||
GrTexture* GrLockCachedBitmapTexture(GrContext*, const SkBitmap&, const GrTextureParams*);
|
||||
GrTexture* GrLockAndRefCachedBitmapTexture(GrContext*, const SkBitmap&, const GrTextureParams*);
|
||||
|
||||
void GrUnlockCachedBitmapTexture(GrTexture*);
|
||||
void GrUnlockAndUnrefCachedBitmapTexture(GrTexture*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Classes
|
||||
|
@ -353,7 +353,7 @@ GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint&
|
||||
|
||||
// Must set wrap and filter on the sampler before requesting a texture.
|
||||
GrTextureParams params(tm, paint.isFilterBitmap());
|
||||
GrTexture* texture = GrLockCachedBitmapTexture(context, fRawBitmap, ¶ms);
|
||||
GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, fRawBitmap, ¶ms);
|
||||
|
||||
if (NULL == texture) {
|
||||
SkDebugf("Couldn't convert bitmap to texture.\n");
|
||||
@ -361,7 +361,7 @@ GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint&
|
||||
}
|
||||
|
||||
GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
|
||||
GrUnlockCachedBitmapTexture(texture);
|
||||
GrUnlockAndUnrefCachedBitmapTexture(texture);
|
||||
return effect;
|
||||
}
|
||||
#endif
|
||||
|
@ -191,9 +191,9 @@ static GrTexture* getInputResultAsTexture(SkImageFilter::Proxy* proxy,
|
||||
if (result.getTexture()) {
|
||||
resultTex = (GrTexture*) result.getTexture();
|
||||
} else {
|
||||
resultTex = GrLockCachedBitmapTexture(src->getContext(), result, NULL);
|
||||
SkSafeRef(resultTex);
|
||||
GrUnlockCachedBitmapTexture(resultTex);
|
||||
resultTex = GrLockAndRefCachedBitmapTexture(src->getContext(), result, NULL);
|
||||
SkSafeRef(resultTex); // for the caller
|
||||
GrUnlockAndUnrefCachedBitmapTexture(resultTex);
|
||||
return resultTex;
|
||||
}
|
||||
} else {
|
||||
|
@ -295,9 +295,9 @@ static GrTexture* getInputResultAsTexture(SkImageFilter::Proxy* proxy,
|
||||
if (result.getTexture()) {
|
||||
resultTex = (GrTexture*) result.getTexture();
|
||||
} else {
|
||||
resultTex = GrLockCachedBitmapTexture(src->getContext(), result, NULL);
|
||||
SkSafeRef(resultTex);
|
||||
GrUnlockCachedBitmapTexture(resultTex);
|
||||
resultTex = GrLockAndRefCachedBitmapTexture(src->getContext(), result, NULL);
|
||||
SkSafeRef(resultTex); // for the caller
|
||||
GrUnlockAndUnrefCachedBitmapTexture(resultTex);
|
||||
return resultTex;
|
||||
}
|
||||
} else {
|
||||
|
@ -57,9 +57,9 @@ GrTexture* SkSingleInputImageFilter::getInputResultAsTexture(Proxy* proxy,
|
||||
if (result.getTexture()) {
|
||||
resultTex = (GrTexture*) result.getTexture();
|
||||
} else {
|
||||
resultTex = GrLockCachedBitmapTexture(src->getContext(), result, NULL);
|
||||
SkSafeRef(resultTex);
|
||||
GrUnlockCachedBitmapTexture(resultTex);
|
||||
resultTex = GrLockAndRefCachedBitmapTexture(src->getContext(), result, NULL);
|
||||
SkSafeRef(resultTex); // for the caller
|
||||
GrUnlockAndUnrefCachedBitmapTexture(resultTex);
|
||||
return resultTex;
|
||||
}
|
||||
} else {
|
||||
|
@ -381,13 +381,13 @@ GrEffectRef* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
|
||||
SkBitmap bitmap;
|
||||
this->asComponentTable(&bitmap);
|
||||
// passing NULL because this effect does no tiling or filtering.
|
||||
GrTexture* texture = GrLockCachedBitmapTexture(context, bitmap, NULL);
|
||||
GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, bitmap, NULL);
|
||||
GrEffectRef* effect = ColorTableEffect::Create(texture, fFlags);
|
||||
|
||||
// Unlock immediately, this is not great, but we don't have a way of
|
||||
// knowing when else to unlock it currently. TODO: Remove this when
|
||||
// unref becomes the unlock replacement for all types of textures.
|
||||
GrUnlockCachedBitmapTexture(texture);
|
||||
GrUnlockAndUnrefCachedBitmapTexture(texture);
|
||||
return effect;
|
||||
}
|
||||
|
||||
|
@ -811,14 +811,14 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
|
||||
fAtlas->getVerticalScaleFactor();
|
||||
fTextureAccess.reset(fAtlas->getTexture(), params);
|
||||
} else {
|
||||
GrTexture* texture = GrLockCachedBitmapTexture(ctx, bitmap, ¶ms);
|
||||
GrTexture* texture = GrLockAndRefCachedBitmapTexture(ctx, bitmap, ¶ms);
|
||||
fTextureAccess.reset(texture, params);
|
||||
fYCoord = SK_ScalarHalf;
|
||||
|
||||
// Unlock immediately, this is not great, but we don't have a way of
|
||||
// knowing when else to unlock it currently, so it may get purged from
|
||||
// the cache, but it'll still be ref'd until it's no longer being used.
|
||||
GrUnlockCachedBitmapTexture(texture);
|
||||
GrUnlockAndUnrefCachedBitmapTexture(texture);
|
||||
}
|
||||
this->addTextureAccess(&fTextureAccess);
|
||||
}
|
||||
|
@ -177,6 +177,7 @@ GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
|
||||
GrAssert(0 == kA8_GrMaskFormat);
|
||||
GrAssert(1 == kA565_GrMaskFormat);
|
||||
if (NULL == fTexture[format]) {
|
||||
// TODO: Update this to use the cache rather than directly creating a texture.
|
||||
GrTextureDesc desc;
|
||||
desc.fFlags = kDynamicUpdate_GrTextureFlagBit;
|
||||
desc.fWidth = GR_ATLAS_TEXTURE_WIDTH;
|
||||
@ -203,5 +204,3 @@ void GrAtlasMgr::freePlot(int x, int y) {
|
||||
GrAssert(fPlotMgr->isBusy(x, y));
|
||||
fPlotMgr->freePlot(x, y);
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,11 +212,12 @@ void convolve_gaussian(GrDrawTarget* target,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrTexture* GrContext::findTexture(const GrTextureDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrTextureParams* params) {
|
||||
GrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrTextureParams* params) {
|
||||
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID);
|
||||
GrResource* resource = fTextureCache->find(resourceKey);
|
||||
SkSafeRef(resource);
|
||||
return static_cast<GrTexture*>(resource);
|
||||
}
|
||||
|
||||
@ -279,17 +280,15 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
|
||||
void* srcData,
|
||||
size_t rowBytes,
|
||||
bool needsFiltering) {
|
||||
GrTexture* clampedTexture = this->findTexture(desc, cacheID, NULL);
|
||||
SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, cacheID, NULL));
|
||||
if (NULL == clampedTexture) {
|
||||
clampedTexture = this->createTexture(NULL, desc, cacheID, srcData, rowBytes);
|
||||
clampedTexture.reset(this->createTexture(NULL, desc, cacheID, srcData, rowBytes));
|
||||
|
||||
if (NULL == clampedTexture) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
clampedTexture->ref();
|
||||
|
||||
GrTextureDesc rtDesc = desc;
|
||||
rtDesc.fFlags = rtDesc.fFlags |
|
||||
kRenderTarget_GrTextureFlagBit |
|
||||
@ -310,19 +309,14 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
|
||||
GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering);
|
||||
drawState->createTextureEffect(0, clampedTexture, SkMatrix::I(), params);
|
||||
|
||||
static const GrVertexLayout layout =
|
||||
GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
|
||||
static const GrVertexLayout layout = GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
|
||||
GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
|
||||
|
||||
if (arg.succeeded()) {
|
||||
GrPoint* verts = (GrPoint*) arg.vertices();
|
||||
verts[0].setIRectFan(0, 0,
|
||||
texture->width(),
|
||||
texture->height(),
|
||||
2*sizeof(GrPoint));
|
||||
verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint));
|
||||
fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType,
|
||||
0, 4);
|
||||
verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(GrPoint));
|
||||
verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(GrPoint));
|
||||
fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
|
||||
}
|
||||
texture->releaseRenderTarget();
|
||||
} else {
|
||||
@ -346,16 +340,14 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
|
||||
GrAssert(NULL != texture);
|
||||
}
|
||||
|
||||
clampedTexture->unref();
|
||||
return texture;
|
||||
}
|
||||
|
||||
GrTexture* GrContext::createTexture(
|
||||
const GrTextureParams* params,
|
||||
const GrTextureDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
void* srcData,
|
||||
size_t rowBytes) {
|
||||
GrTexture* GrContext::createTexture(const GrTextureParams* params,
|
||||
const GrTextureDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
void* srcData,
|
||||
size_t rowBytes) {
|
||||
SK_TRACE_EVENT0("GrContext::createTexture");
|
||||
|
||||
#if GR_DUMP_TEXTURE_UPLOAD
|
||||
@ -364,13 +356,13 @@ GrTexture* GrContext::createTexture(
|
||||
|
||||
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID);
|
||||
|
||||
SkAutoTUnref<GrTexture> texture;
|
||||
GrTexture* texture;
|
||||
if (GrTexture::NeedsResizing(resourceKey)) {
|
||||
texture.reset(this->createResizedTexture(desc, cacheID,
|
||||
srcData, rowBytes,
|
||||
GrTexture::NeedsFiltering(resourceKey)));
|
||||
texture = this->createResizedTexture(desc, cacheID,
|
||||
srcData, rowBytes,
|
||||
GrTexture::NeedsFiltering(resourceKey));
|
||||
} else {
|
||||
texture.reset(fGpu->createTexture(desc, srcData, rowBytes));
|
||||
texture= fGpu->createTexture(desc, srcData, rowBytes);
|
||||
}
|
||||
|
||||
if (NULL != texture) {
|
||||
@ -380,7 +372,7 @@ GrTexture* GrContext::createTexture(
|
||||
return texture;
|
||||
}
|
||||
|
||||
GrTexture* GrContext::lockScratchTexture(const GrTextureDesc& inDesc, ScratchTexMatch match) {
|
||||
GrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, ScratchTexMatch match) {
|
||||
GrTextureDesc desc = inDesc;
|
||||
|
||||
GrAssert((desc.fFlags & kRenderTarget_GrTextureFlagBit) ||
|
||||
@ -403,11 +395,16 @@ GrTexture* GrContext::lockScratchTexture(const GrTextureDesc& inDesc, ScratchTex
|
||||
GrResourceKey key = GrTexture::ComputeScratchKey(desc);
|
||||
// Ensure we have exclusive access to the texture so future 'find' calls don't return it
|
||||
resource = fTextureCache->find(key, GrResourceCache::kHide_OwnershipFlag);
|
||||
// if we miss, relax the fit of the flags...
|
||||
// then try doubling width... then height.
|
||||
if (NULL != resource || kExact_ScratchTexMatch == match) {
|
||||
if (NULL != resource) {
|
||||
resource->ref();
|
||||
break;
|
||||
}
|
||||
if (kExact_ScratchTexMatch == match) {
|
||||
break;
|
||||
}
|
||||
// We had a cache miss and we are in approx mode, relax the fit of the flags... then try
|
||||
// doubling width... then the height.
|
||||
|
||||
// We no longer try to reuse textures that were previously used as render targets in
|
||||
// situations where no RT is needed; doing otherwise can confuse the video driver and
|
||||
// cause significant performance problems in some cases.
|
||||
@ -432,7 +429,7 @@ GrTexture* GrContext::lockScratchTexture(const GrTextureDesc& inDesc, ScratchTex
|
||||
desc.fFlags = inDesc.fFlags;
|
||||
desc.fWidth = origWidth;
|
||||
desc.fHeight = origHeight;
|
||||
SkAutoTUnref<GrTexture> texture(fGpu->createTexture(desc, NULL, 0));
|
||||
GrTexture* texture = fGpu->createTexture(desc, NULL, 0);
|
||||
if (NULL != texture) {
|
||||
GrResourceKey key = GrTexture::ComputeScratchKey(texture->desc());
|
||||
// Make the resource exclusive so future 'find' calls don't return it
|
||||
|
@ -96,7 +96,7 @@ public:
|
||||
|
||||
~SkAutoCachedTexture() {
|
||||
if (NULL != fTexture) {
|
||||
GrUnlockCachedBitmapTexture(fTexture);
|
||||
GrUnlockAndUnrefCachedBitmapTexture(fTexture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,14 +104,14 @@ public:
|
||||
const SkBitmap& bitmap,
|
||||
const GrTextureParams* params) {
|
||||
if (NULL != fTexture) {
|
||||
GrUnlockCachedBitmapTexture(fTexture);
|
||||
GrUnlockAndUnrefCachedBitmapTexture(fTexture);
|
||||
fTexture = NULL;
|
||||
}
|
||||
fDevice = device;
|
||||
GrTexture* result = (GrTexture*)bitmap.getTexture();
|
||||
if (NULL == result) {
|
||||
// Cannot return the native texture so look it up in our cache
|
||||
fTexture = GrLockCachedBitmapTexture(device->context(), bitmap, params);
|
||||
fTexture = GrLockAndRefCachedBitmapTexture(device->context(), bitmap, params);
|
||||
result = fTexture;
|
||||
}
|
||||
return result;
|
||||
@ -1801,8 +1801,7 @@ SkDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config,
|
||||
desc.fHeight = height;
|
||||
desc.fSampleCnt = fRenderTarget->numSamples();
|
||||
|
||||
GrTexture* texture;
|
||||
SkAutoTUnref<GrTexture> tunref;
|
||||
SkAutoTUnref<GrTexture> texture;
|
||||
// Skia's convention is to only clear a device if it is non-opaque.
|
||||
bool needClear = !isOpaque;
|
||||
|
||||
@ -1812,18 +1811,14 @@ SkDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config,
|
||||
const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == usage) ?
|
||||
GrContext::kApprox_ScratchTexMatch :
|
||||
GrContext::kExact_ScratchTexMatch;
|
||||
texture = fContext->lockScratchTexture(desc, match);
|
||||
texture.reset(fContext->lockAndRefScratchTexture(desc, match));
|
||||
#else
|
||||
tunref.reset(fContext->createUncachedTexture(desc, NULL, 0));
|
||||
texture = tunref.get();
|
||||
texture.reset(fContext->createUncachedTexture(desc, NULL, 0));
|
||||
#endif
|
||||
if (texture) {
|
||||
return SkNEW_ARGS(SkGpuDevice,(fContext,
|
||||
texture,
|
||||
needClear));
|
||||
if (NULL != texture.get()) {
|
||||
return SkNEW_ARGS(SkGpuDevice,(fContext, texture, needClear));
|
||||
} else {
|
||||
GrPrintf("---- failed to create compatible device texture [%d %d]\n",
|
||||
width, height);
|
||||
GrPrintf("---- failed to create compatible device texture [%d %d]\n", width, height);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -118,11 +118,9 @@ static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx,
|
||||
if (cache) {
|
||||
GrCacheID cacheID;
|
||||
generate_bitmap_cache_id(origBitmap, &cacheID);
|
||||
return ctx->createTexture(params, desc, cacheID,
|
||||
storage.get(),
|
||||
bitmap->width());
|
||||
return ctx->createTexture(params, desc, cacheID, storage.get(), bitmap->width());
|
||||
} else {
|
||||
GrTexture* result = ctx->lockScratchTexture(desc,
|
||||
GrTexture* result = ctx->lockAndRefScratchTexture(desc,
|
||||
GrContext::kExact_ScratchTexMatch);
|
||||
result->writePixels(0, 0, bitmap->width(),
|
||||
bitmap->height(), desc.fConfig,
|
||||
@ -141,16 +139,14 @@ static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx,
|
||||
// This texture is likely to be used again so leave it in the cache
|
||||
GrCacheID cacheID;
|
||||
generate_bitmap_cache_id(origBitmap, &cacheID);
|
||||
return ctx->createTexture(params, desc, cacheID,
|
||||
bitmap->getPixels(),
|
||||
bitmap->rowBytes());
|
||||
return ctx->createTexture(params, desc, cacheID, bitmap->getPixels(), bitmap->rowBytes());
|
||||
} else {
|
||||
// This texture is unlikely to be used again (in its present form) so
|
||||
// just use a scratch texture. This will remove the texture from the
|
||||
// cache so no one else can find it. Additionally, once unlocked, the
|
||||
// scratch texture will go to the end of the list for purging so will
|
||||
// likely be available for this volatile bitmap the next time around.
|
||||
GrTexture* result = ctx->lockScratchTexture(desc, GrContext::kExact_ScratchTexMatch);
|
||||
GrTexture* result = ctx->lockAndRefScratchTexture(desc, GrContext::kExact_ScratchTexMatch);
|
||||
result->writePixels(0, 0,
|
||||
bitmap->width(), bitmap->height(),
|
||||
desc.fConfig,
|
||||
@ -171,9 +167,9 @@ bool GrIsBitmapInCache(const GrContext* ctx,
|
||||
return ctx->isTextureInCache(desc, cacheID, params);
|
||||
}
|
||||
|
||||
GrTexture* GrLockCachedBitmapTexture(GrContext* ctx,
|
||||
const SkBitmap& bitmap,
|
||||
const GrTextureParams* params) {
|
||||
GrTexture* GrLockAndRefCachedBitmapTexture(GrContext* ctx,
|
||||
const SkBitmap& bitmap,
|
||||
const GrTextureParams* params) {
|
||||
GrTexture* result = NULL;
|
||||
|
||||
bool cache = !bitmap.isVolatile();
|
||||
@ -187,7 +183,7 @@ GrTexture* GrLockCachedBitmapTexture(GrContext* ctx,
|
||||
GrTextureDesc desc;
|
||||
generate_bitmap_texture_desc(bitmap, &desc);
|
||||
|
||||
result = ctx->findTexture(desc, cacheID, params);
|
||||
result = ctx->findAndRefTexture(desc, cacheID, params);
|
||||
}
|
||||
if (NULL == result) {
|
||||
result = sk_gr_create_bitmap_texture(ctx, cache, params, bitmap);
|
||||
@ -199,10 +195,11 @@ GrTexture* GrLockCachedBitmapTexture(GrContext* ctx,
|
||||
return result;
|
||||
}
|
||||
|
||||
void GrUnlockCachedBitmapTexture(GrTexture* texture) {
|
||||
void GrUnlockAndUnrefCachedBitmapTexture(GrTexture* texture) {
|
||||
GrAssert(NULL != texture->getContext());
|
||||
|
||||
texture->getContext()->unlockScratchTexture(texture);
|
||||
texture->unref();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -224,4 +221,3 @@ GrPixelConfig SkBitmapConfig2GrPixelConfig(SkBitmap::Config config) {
|
||||
return kUnknown_GrPixelConfig;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ void GrTextureStripAtlas::lockTexture() {
|
||||
memset(key.fData32 + 1, 0, sizeof(key) - sizeof(uint32_t));
|
||||
GrCacheID cacheID(gTextureStripAtlasDomain, key);
|
||||
|
||||
fTexture = fDesc.fContext->findTexture(texDesc, cacheID, ¶ms);
|
||||
fTexture = fDesc.fContext->findAndRefTexture(texDesc, cacheID, ¶ms);
|
||||
if (NULL == fTexture) {
|
||||
fTexture = fDesc.fContext->createTexture(¶ms, texDesc, cacheID, NULL, 0);
|
||||
// This is a new texture, so all of our cache info is now invalid
|
||||
@ -210,7 +210,6 @@ void GrTextureStripAtlas::lockTexture() {
|
||||
fKeyTable.rewind();
|
||||
}
|
||||
GrAssert(NULL != fTexture);
|
||||
fTexture->ref();
|
||||
}
|
||||
|
||||
void GrTextureStripAtlas::unlockTexture() {
|
||||
@ -345,4 +344,3 @@ void GrTextureStripAtlas::validate() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -155,14 +155,14 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
|
||||
|
||||
// check that the set took
|
||||
check_state(reporter, cache, clip1, texture1, bound1);
|
||||
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture1->getRefCnt());
|
||||
|
||||
// push the state
|
||||
cache.push();
|
||||
|
||||
// verify that the pushed state is initially empty
|
||||
check_state(reporter, cache, emptyClip, NULL, emptyBound);
|
||||
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture1->getRefCnt());
|
||||
|
||||
// modify the new state
|
||||
GrIRect bound2;
|
||||
@ -180,8 +180,8 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
|
||||
|
||||
// check that the changes took
|
||||
check_state(reporter, cache, clip2, texture2, bound2);
|
||||
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, 1 == texture2->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture2->getRefCnt());
|
||||
|
||||
// check to make sure canReuse works
|
||||
REPORTER_ASSERT(reporter, cache.canReuse(clip2.getTopmostGenID(), bound2));
|
||||
@ -192,16 +192,16 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
|
||||
|
||||
// verify that the old state is restored
|
||||
check_state(reporter, cache, clip1, texture1, bound1);
|
||||
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, 1 == texture2->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture2->getRefCnt());
|
||||
|
||||
// manually clear the state
|
||||
cache.reset();
|
||||
|
||||
// verify it is now empty
|
||||
check_state(reporter, cache, emptyClip, NULL, emptyBound);
|
||||
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, 1 == texture2->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture2->getRefCnt());
|
||||
|
||||
// pop again - so there is no state
|
||||
cache.pop();
|
||||
@ -211,8 +211,8 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
|
||||
// only do in release since it generates asserts in debug
|
||||
check_state(reporter, cache, emptyClip, NULL, emptyBound);
|
||||
#endif
|
||||
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, 1 == texture2->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture1->getRefCnt());
|
||||
REPORTER_ASSERT(reporter, texture2->getRefCnt());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user