aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2014-06-24 13:10:43 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-06-24 13:10:43 -0700
commit4ec84da746d66e1bcb76ab2f8b94602b8e966589 (patch)
tree3d889de63a2a91b5111a753f8d62dafd6b009472 /src
parent332600fb43fcaaa022c3c0b04ba52b371930fb15 (diff)
Move allocation of texture from SkGpuDevice to GrLayerCache
In order to atlas the layers the GrLayerCache needs to be given more control over where a given layer's texture is allocated (i.e., it could be a raw scratch texture or in the cache). R=bsalomon@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/350183006
Diffstat (limited to 'src')
-rw-r--r--src/core/SkPicturePlayback.h2
-rwxr-xr-xsrc/gpu/GrContext.cpp2
-rw-r--r--src/gpu/GrLayerCache.cpp29
-rw-r--r--src/gpu/GrLayerCache.h25
-rw-r--r--src/gpu/SkGpuDevice.cpp85
5 files changed, 84 insertions, 59 deletions
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index 3cdd9af3f3..87380a6aaf 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -345,7 +345,7 @@ private:
size_t fStart;
size_t fStop;
SkIPoint fPos;
- SkBitmap* fBM;
+ SkBitmap* fBM; // fBM is allocated so ReplacementInfo can remain POD
const SkPaint* fPaint; // Note: this object doesn't own the paint
};
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;