diff options
Diffstat (limited to 'src/gpu')
-rwxr-xr-x | src/gpu/GrContext.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrLayerCache.cpp | 29 | ||||
-rw-r--r-- | src/gpu/GrLayerCache.h | 25 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 85 |
4 files changed, 83 insertions, 58 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index d59d2e8d40..cdef414535 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -130,7 +130,7 @@ bool GrContext::init(GrBackend backend, GrBackendContext backendContext) { fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); - fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (fGpu))); + fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this))); fLastDrawWasBuffered = kNo_BufferedDraw; diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp index f6377bf7e9..86258abf42 100644 --- a/src/gpu/GrLayerCache.cpp +++ b/src/gpu/GrLayerCache.cpp @@ -41,8 +41,8 @@ private: int fLayerID; }; -GrLayerCache::GrLayerCache(GrGpu* gpu) - : fGpu(SkRef(gpu)) +GrLayerCache::GrLayerCache(GrContext* context) + : fContext(context) , fLayerPool(16) { // TODO: may need to increase this later } @@ -57,7 +57,7 @@ void GrLayerCache::init() { // The layer cache only gets 1 plot SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight); - fAtlasMgr.reset(SkNEW_ARGS(GrAtlasMgr, (fGpu, kSkia8888_GrPixelConfig, + fAtlasMgr.reset(SkNEW_ARGS(GrAtlasMgr, (fContext->getGpu(), kSkia8888_GrPixelConfig, textureSize, 1, 1, false))); } @@ -75,6 +75,10 @@ GrCachedLayer* GrLayerCache::createLayer(const SkPicture* picture, int layerID) return layer; } +GrCachedLayer* GrLayerCache::findLayer(const SkPicture* picture, int layerID) { + SkASSERT(picture->uniqueID() != SK_InvalidGenID); + return fLayerHash.find(PictureLayerKey(picture->uniqueID(), layerID)); +} GrCachedLayer* GrLayerCache::findLayerOrCreate(const SkPicture* picture, int layerID) { SkASSERT(picture->uniqueID() != SK_InvalidGenID); @@ -82,5 +86,24 @@ GrCachedLayer* GrLayerCache::findLayerOrCreate(const SkPicture* picture, int lay if (NULL == layer) { layer = this->createLayer(picture, layerID); } + return layer; } + +bool GrLayerCache::lock(GrCachedLayer* layer, const GrTextureDesc& desc) { + SkASSERT(NULL == layer->getTexture()); + + // This just uses scratch textures and doesn't cache the texture. + // This can yield a lot of re-rendering + layer->setTexture(fContext->lockAndRefScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); + return false; +} + +void GrLayerCache::unlock(GrCachedLayer* layer) { + if (NULL == layer || NULL == layer->getTexture()) { + return; + } + + fContext->unlockScratchTexture(layer->getTexture()); + layer->setTexture(NULL); +} diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h index a957e78013..d06b748ae8 100644 --- a/src/gpu/GrLayerCache.h +++ b/src/gpu/GrLayerCache.h @@ -9,13 +9,12 @@ #define GrLayerCache_DEFINED #include "GrAllocPool.h" +#include "GrAtlas.h" #include "GrTHashTable.h" #include "GrPictureUtils.h" #include "GrRect.h" -class GrAtlasMgr; class GrGpu; -class GrPlot; class SkPicture; // GrAtlasLocation captures an atlased item's position in the atlas. This @@ -97,24 +96,36 @@ private: // classes. class GrLayerCache { public: - GrLayerCache(GrGpu*); + GrLayerCache(GrContext*); ~GrLayerCache(); + // As a cache, the GrLayerCache can be ordered to free up all its cached + // elements by the GrContext void freeAll(); - GrCachedLayer* findLayerOrCreate(const SkPicture* picture, int id); + GrCachedLayer* findLayer(const SkPicture* picture, int layerID); + GrCachedLayer* findLayerOrCreate(const SkPicture* picture, int layerID); + + // Inform the cache that layer's cached image is now required. Return true + // if it was found in the ResourceCache and doesn't need to be regenerated. + // If false is returned the caller should (re)render the layer into the + // newly acquired texture. + bool lock(GrCachedLayer* layer, const GrTextureDesc& desc); + + // Inform the cache that layer's cached image is not currently required + void unlock(GrCachedLayer* layer); private: - SkAutoTUnref<GrGpu> fGpu; + GrContext* fContext; // pointer back to owning context SkAutoTDelete<GrAtlasMgr> fAtlasMgr; // TODO: could lazily allocate + GrAtlas fPlotUsage; class PictureLayerKey; GrTHashTable<GrCachedLayer, PictureLayerKey, 7> fLayerHash; GrTAllocPool<GrCachedLayer> fLayerPool; void init(); - GrCachedLayer* createLayer(const SkPicture* picture, int id); - + GrCachedLayer* createLayer(const SkPicture* picture, int layerID); }; #endif diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 861383bf6a..d34170cba1 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1842,6 +1842,10 @@ void SkGpuDevice::EXPERIMENTAL_purge(const SkPicture* picture) { bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture) { + if (NULL == picture->fPlayback.get()) { + return false; + } + SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey(); const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); @@ -1938,60 +1942,50 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* pi SkPicturePlayback::PlaybackReplacements replacements; + // Generate the layer and/or ensure it is locked for (int i = 0; i < gpuData->numSaveLayers(); ++i) { if (pullForward[i]) { GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture, i); const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); - if (NULL != picture->fPlayback.get()) { - SkPicturePlayback::PlaybackReplacements::ReplacementInfo* layerInfo = + SkPicturePlayback::PlaybackReplacements::ReplacementInfo* layerInfo = replacements.push(); - layerInfo->fStart = info.fSaveLayerOpID; - layerInfo->fStop = info.fRestoreOpID; - layerInfo->fPos = info.fOffset; - - GrTextureDesc desc; - desc.fFlags = kRenderTarget_GrTextureFlagBit; - desc.fWidth = info.fSize.fWidth; - desc.fHeight = info.fSize.fHeight; - desc.fConfig = kSkia8888_GrPixelConfig; - // TODO: need to deal with sample count - - bool bNeedsRendering = true; - - // This just uses scratch textures and doesn't cache the texture. - // This can yield a lot of re-rendering - if (NULL == layer->getTexture()) { - layer->setTexture(fContext->lockAndRefScratchTexture(desc, - GrContext::kApprox_ScratchTexMatch)); - if (NULL == layer->getTexture()) { - continue; - } - } else { - bNeedsRendering = false; - } + layerInfo->fStart = info.fSaveLayerOpID; + layerInfo->fStop = info.fRestoreOpID; + layerInfo->fPos = info.fOffset; + + GrTextureDesc desc; + desc.fFlags = kRenderTarget_GrTextureFlagBit; + desc.fWidth = info.fSize.fWidth; + desc.fHeight = info.fSize.fHeight; + desc.fConfig = kSkia8888_GrPixelConfig; + // TODO: need to deal with sample count + + bool needsRendering = !fContext->getLayerCache()->lock(layer, desc); + if (NULL == layer->getTexture()) { + continue; + } - layerInfo->fBM = SkNEW(SkBitmap); - wrap_texture(layer->getTexture(), desc.fWidth, desc.fHeight, layerInfo->fBM); + layerInfo->fBM = SkNEW(SkBitmap); // fBM is allocated so ReplacementInfo can be POD + wrap_texture(layer->getTexture(), desc.fWidth, desc.fHeight, layerInfo->fBM); - SkASSERT(info.fPaint); - layerInfo->fPaint = info.fPaint; + SkASSERT(info.fPaint); + layerInfo->fPaint = info.fPaint; - if (bNeedsRendering) { - SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( - layer->getTexture()->asRenderTarget())); + if (needsRendering) { + SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( + layer->getTexture()->asRenderTarget())); - SkCanvas* canvas = surface->getCanvas(); + SkCanvas* canvas = surface->getCanvas(); - canvas->setMatrix(info.fCTM); - canvas->clear(SK_ColorTRANSPARENT); + canvas->setMatrix(info.fCTM); + canvas->clear(SK_ColorTRANSPARENT); - picture->fPlayback->setDrawLimits(info.fSaveLayerOpID, info.fRestoreOpID); - picture->fPlayback->draw(*canvas, NULL); - picture->fPlayback->setDrawLimits(0, 0); - canvas->flush(); - } + picture->fPlayback->setDrawLimits(info.fSaveLayerOpID, info.fRestoreOpID); + picture->fPlayback->draw(*canvas, NULL); + picture->fPlayback->setDrawLimits(0, 0); + canvas->flush(); } } } @@ -2001,13 +1995,10 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* pi picture->fPlayback->draw(*canvas, NULL); picture->fPlayback->setReplacements(NULL); + // unlock the layers for (int i = 0; i < gpuData->numSaveLayers(); ++i) { - GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture, i); - - if (NULL != layer->getTexture()) { - fContext->unlockScratchTexture(layer->getTexture()); - layer->setTexture(NULL); - } + GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture, i); + fContext->getLayerCache()->unlock(layer); } return true; |