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