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
This commit is contained in:
parent
332600fb43
commit
4ec84da746
@ -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
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
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
|
||||
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;
|
||||
bool needsRendering = !fContext->getLayerCache()->lock(layer, desc);
|
||||
if (NULL == layer->getTexture()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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->fBM = SkNEW(SkBitmap); // fBM is allocated so ReplacementInfo can be POD
|
||||
wrap_texture(layer->getTexture(), desc.fWidth, desc.fHeight, layerInfo->fBM);
|
||||
|
||||
layerInfo->fBM = SkNEW(SkBitmap);
|
||||
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 (needsRendering) {
|
||||
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
|
||||
layer->getTexture()->asRenderTarget()));
|
||||
|
||||
if (bNeedsRendering) {
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user