aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkLayerInfo.h2
-rw-r--r--src/core/SkMultiPictureDraw.cpp9
-rw-r--r--src/core/SkRecordDraw.cpp12
-rw-r--r--src/gpu/GrLayerCache.cpp17
-rw-r--r--src/gpu/GrLayerCache.h46
-rw-r--r--src/gpu/GrLayerHoister.cpp56
-rw-r--r--src/gpu/GrLayerHoister.h1
-rw-r--r--src/gpu/GrRecordReplaceDraw.cpp91
-rw-r--r--src/gpu/GrRecordReplaceDraw.h109
-rw-r--r--src/gpu/SkGpuDevice.cpp8
-rw-r--r--tests/GpuLayerCacheTest.cpp31
-rw-r--r--tests/RecordReplaceDrawTest.cpp67
12 files changed, 139 insertions, 310 deletions
diff --git a/src/core/SkLayerInfo.h b/src/core/SkLayerInfo.h
index 6ed77c993c..add57d780c 100644
--- a/src/core/SkLayerInfo.h
+++ b/src/core/SkLayerInfo.h
@@ -53,7 +53,7 @@ public:
// The variable length key for this saveLayer block. It stores the
// thread of drawPicture and saveLayer operation indices that lead to this
// saveLayer (including its own op index). The BlockInfo owns this memory.
- int* fKey;
+ unsigned* fKey;
int fKeySize; // # of ints
};
diff --git a/src/core/SkMultiPictureDraw.cpp b/src/core/SkMultiPictureDraw.cpp
index bd1e8fe08c..ed099a02e1 100644
--- a/src/core/SkMultiPictureDraw.cpp
+++ b/src/core/SkMultiPictureDraw.cpp
@@ -15,6 +15,7 @@
#include "SkTaskGroup.h"
#if SK_SUPPORT_GPU
+#include "GrContext.h"
#include "GrLayerHoister.h"
#include "GrRecordReplaceDraw.h"
#include "GrRenderTarget.h"
@@ -168,13 +169,9 @@ void SkMultiPictureDraw::draw() {
GrLayerHoister::DrawLayers(context, needRendering);
- GrReplacements replacements;
-
- GrLayerHoister::ConvertLayersToReplacements(picture, needRendering, &replacements);
- GrLayerHoister::ConvertLayersToReplacements(picture, recycled, &replacements);
-
// Render the entire picture using new layers
- GrRecordReplaceDraw(picture, canvas, &replacements, initialMatrix, NULL);
+ GrRecordReplaceDraw(picture, canvas, context->getLayerCache(),
+ initialMatrix, NULL);
GrLayerHoister::UnlockLayers(context, needRendering);
GrLayerHoister::UnlockLayers(context, recycled);
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 4801f66713..47bafe3a2e 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -691,10 +691,10 @@ private:
// Store 'saveLayer ops from enclosing picture' + drawPict op + 'ops from sub-picture'
dst.fKeySize = fSaveLayerOpStack.count() + src.fKeySize + 1;
- dst.fKey = SkNEW_ARRAY(int, dst.fKeySize);
- memcpy(dst.fKey, fSaveLayerOpStack.begin(), fSaveLayerOpStack.count() * sizeof(int));
+ dst.fKey = SkNEW_ARRAY(unsigned, dst.fKeySize);
+ memcpy(dst.fKey, fSaveLayerOpStack.begin(), fSaveLayerOpStack.count() * sizeof(unsigned));
dst.fKey[fSaveLayerOpStack.count()] = fFillBounds.currentOp();
- memcpy(&dst.fKey[fSaveLayerOpStack.count()+1], src.fKey, src.fKeySize * sizeof(int));
+ memcpy(&dst.fKey[fSaveLayerOpStack.count()+1], src.fKey, src.fKeySize * sizeof(unsigned));
}
}
@@ -766,8 +766,8 @@ private:
block.fIsNested = fSaveLayersInStack > 0;
block.fKeySize = fSaveLayerOpStack.count();
- block.fKey = SkNEW_ARRAY(int, block.fKeySize);
- memcpy(block.fKey, fSaveLayerOpStack.begin(), block.fKeySize * sizeof(int));
+ block.fKey = SkNEW_ARRAY(unsigned, block.fKeySize);
+ memcpy(block.fKey, fSaveLayerOpStack.begin(), block.fKeySize * sizeof(unsigned));
fSaveLayerOpStack.pop();
}
@@ -776,7 +776,7 @@ private:
int fSaveLayersInStack;
SkTDArray<SaveLayerInfo> fSaveLayerStack;
// The op code indices of all the currently active saveLayers
- SkTDArray<int> fSaveLayerOpStack;
+ SkTDArray<unsigned> fSaveLayerOpStack;
SkLayerInfo* fAccelData;
const SkPicture::SnapshotArray* fPictList;
diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp
index c347512188..fc5be5fd05 100644
--- a/src/gpu/GrLayerCache.cpp
+++ b/src/gpu/GrLayerCache.cpp
@@ -125,7 +125,7 @@ GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID,
int start, int stop,
const SkIRect& bounds,
const SkMatrix& initialMat,
- const int* key,
+ const unsigned* key,
int keySize,
const SkPaint* paint) {
SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0);
@@ -137,7 +137,7 @@ GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID,
}
GrCachedLayer* GrLayerCache::findLayer(uint32_t pictureID, const SkMatrix& initialMat,
- const int* key, int keySize) {
+ const unsigned* key, int keySize) {
SkASSERT(pictureID != SK_InvalidGenID);
return fLayerHash.find(GrCachedLayer::Key(pictureID, initialMat, key, keySize));
}
@@ -146,7 +146,7 @@ GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID,
int start, int stop,
const SkIRect& bounds,
const SkMatrix& initialMat,
- const int* key,
+ const unsigned* key,
int keySize,
const SkPaint* paint) {
SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0);
@@ -209,9 +209,8 @@ bool GrLayerCache::tryToAtlas(GrCachedLayer* layer,
pictInfo->incPlotUsage(plot->id());
#endif
// The layer was successfully added to the atlas
- GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY,
- SkToS16(desc.fWidth),
- SkToS16(desc.fHeight));
+ const SkIRect bounds = SkIRect::MakeXYWH(loc.fX, loc.fY,
+ desc.fWidth, desc.fHeight);
layer->setTexture(fAtlas->getTexture(), bounds);
layer->setPlot(plot);
layer->setLocked(true);
@@ -250,7 +249,7 @@ bool GrLayerCache::lock(GrCachedLayer* layer, const GrSurfaceDesc& desc, bool* n
return false;
}
- layer->setTexture(tex, GrIRect16::MakeWH(SkToS16(desc.fWidth), SkToS16(desc.fHeight)));
+ layer->setTexture(tex, SkIRect::MakeWH(desc.fWidth, desc.fHeight));
layer->setLocked(true);
*needsRendering = true;
return true;
@@ -289,11 +288,11 @@ void GrLayerCache::unlock(GrCachedLayer* layer) {
}
layer->setPlot(NULL);
- layer->setTexture(NULL, GrIRect16::MakeEmpty());
+ layer->setTexture(NULL, SkIRect::MakeEmpty());
#endif
} else {
- layer->setTexture(NULL, GrIRect16::MakeEmpty());
+ layer->setTexture(NULL, SkIRect::MakeEmpty());
}
layer->setLocked(false);
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h
index 967503dff7..b9b59d06bc 100644
--- a/src/gpu/GrLayerCache.h
+++ b/src/gpu/GrLayerCache.h
@@ -77,7 +77,7 @@ public:
// For SkTDynamicHash
struct Key {
Key(uint32_t pictureID, const SkMatrix& initialMat,
- const int* key, int keySize, bool copyKey = false)
+ const unsigned* key, int keySize, bool copyKey = false)
: fKeySize(keySize)
, fFreeKey(copyKey) {
fIDMatrix.fPictureID = pictureID;
@@ -85,8 +85,8 @@ public:
fIDMatrix.fInitialMat.getType(); // force initialization of type so hashes match
if (copyKey) {
- int* tempKey = SkNEW_ARRAY(int, keySize);
- memcpy(tempKey, key, keySize*sizeof(int));
+ unsigned* tempKey = SkNEW_ARRAY(unsigned, keySize);
+ memcpy(tempKey, key, keySize*sizeof(unsigned));
fKey = tempKey;
} else {
fKey = key;
@@ -115,7 +115,7 @@ public:
uint32_t pictureID() const { return fIDMatrix.fPictureID; }
// TODO: remove these when GrCachedLayer & ReplacementInfo fuse
- const int* key() const { SkASSERT(fFreeKey); return fKey; }
+ const unsigned* key() const { SkASSERT(fFreeKey); return fKey; }
int keySize() const { SkASSERT(fFreeKey); return fKeySize; }
uint32_t hash() const {
@@ -133,18 +133,18 @@ public:
SkMatrix fInitialMat;
} fIDMatrix;
- const int* fKey;
- const int fKeySize;
- bool fFreeKey;
+ const unsigned* fKey;
+ const int fKeySize;
+ bool fFreeKey;
};
static const Key& GetKey(const GrCachedLayer& layer) { return layer.fKey; }
static uint32_t Hash(const Key& key) { return key.hash(); }
// GrCachedLayer proper
- GrCachedLayer(uint32_t pictureID, int start, int stop,
+ GrCachedLayer(uint32_t pictureID, unsigned start, unsigned stop,
const SkIRect& bounds, const SkMatrix& ctm,
- const int* key, int keySize,
+ const unsigned* key, int keySize,
const SkPaint* paint)
: fKey(pictureID, ctm, key, keySize, true)
, fStart(start)
@@ -152,11 +152,11 @@ public:
, fBounds(bounds)
, fPaint(paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL)
, fTexture(NULL)
- , fRect(GrIRect16::MakeEmpty())
+ , fRect(SkIRect::MakeEmpty())
, fPlot(NULL)
, fUses(0)
, fLocked(false) {
- SkASSERT(SK_InvalidGenID != pictureID && start >= 0 && stop >= 0);
+ SkASSERT(SK_InvalidGenID != pictureID);
}
~GrCachedLayer() {
@@ -166,20 +166,20 @@ public:
uint32_t pictureID() const { return fKey.pictureID(); }
// TODO: remove these when GrCachedLayer & ReplacementInfo fuse
- const int* key() const { return fKey.key(); }
+ const unsigned* key() const { return fKey.key(); }
int keySize() const { return fKey.keySize(); }
- int start() const { return fStart; }
+ unsigned start() const { return fStart; }
// TODO: make bound debug only
const SkIRect& bound() const { return fBounds; }
- int stop() const { return fStop; }
- void setTexture(GrTexture* texture, const GrIRect16& rect) {
+ unsigned stop() const { return fStop; }
+ void setTexture(GrTexture* texture, const SkIRect& rect) {
SkRefCnt_SafeAssign(fTexture, texture);
fRect = rect;
}
GrTexture* texture() { return fTexture; }
const SkPaint* paint() const { return fPaint; }
- const GrIRect16& rect() const { return fRect; }
+ const SkIRect& rect() const { return fRect; }
void setPlot(GrPlot* plot) {
SkASSERT(NULL == plot || NULL == fPlot);
@@ -199,9 +199,9 @@ private:
const Key fKey;
// The "saveLayer" operation index of the cached layer
- const int fStart;
+ const unsigned fStart;
// The final "restore" operation index of the cached layer
- const int fStop;
+ const unsigned fStop;
const SkIRect fBounds;
@@ -216,7 +216,7 @@ private:
// For both atlased and non-atlased layers 'fRect' contains the bound of
// the layer in whichever texture it resides. It is empty when 'fTexture'
// is NULL.
- GrIRect16 fRect;
+ SkIRect fRect;
// For atlased layers, fPlot stores the atlas plot in which the layer rests.
// It is always NULL for non-atlased layers.
@@ -259,11 +259,13 @@ public:
// elements by the GrContext
void freeAll();
+ GrCachedLayer* findLayer(uint32_t pictureID, const SkMatrix& ctm,
+ const unsigned* key, int keySize);
GrCachedLayer* findLayerOrCreate(uint32_t pictureID,
int start, int stop,
const SkIRect& bounds,
const SkMatrix& initialMat,
- const int* key, int keySize,
+ const unsigned* key, int keySize,
const SkPaint* paint);
// Attempt to place 'layer' in the atlas. Return true on success; false on failure.
@@ -346,7 +348,7 @@ private:
void initAtlas();
GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop,
const SkIRect& bounds, const SkMatrix& initialMat,
- const int* key, int keySize,
+ const unsigned* key, int keySize,
const SkPaint* paint);
// Remove all the layers (and unlock any resources) associated with 'pictureID'
@@ -367,8 +369,6 @@ private:
// for testing
friend class TestingAccess;
int numLayers() const { return fLayerHash.count(); }
- GrCachedLayer* findLayer(uint32_t pictureID, const SkMatrix& ctm,
- const int* key, int keySize);
};
#endif
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp
index 4e7836830c..a17c7ddf97 100644
--- a/src/gpu/GrLayerHoister.cpp
+++ b/src/gpu/GrLayerHoister.cpp
@@ -72,7 +72,6 @@ static void prepare_for_hoisting(GrLayerCache* layerCache,
layerCache->addUse(layer);
hl->fLayer = layer;
hl->fPicture = pict;
- hl->fOffset = SkIPoint::Make(layerRect.fLeft, layerRect.fTop);
hl->fLocalMat = info.fLocalMat;
hl->fInitialMat = initialMat;
hl->fPreMat = initialMat;
@@ -185,46 +184,6 @@ void GrLayerHoister::FindLayersToHoist(GrContext* context,
}
}
-static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* result) {
- SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
- result->setInfo(info);
- result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
-}
-
-void GrLayerHoister::ConvertLayersToReplacements(const SkPicture* topLevelPicture,
- const SkTDArray<GrHoistedLayer>& layers,
- GrReplacements* replacements) {
- // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer?
- for (int i = 0; i < layers.count(); ++i) {
- GrCachedLayer* layer = layers[i].fLayer;
-
- GrReplacements::ReplacementInfo* layerInfo =
- replacements->newReplacement(topLevelPicture->uniqueID(),
- layers[i].fInitialMat,
- layer->key(), layer->keySize());
- layerInfo->fStop = layer->stop();
- layerInfo->fPos = layers[i].fOffset;
-
- SkBitmap bm;
- wrap_texture(layers[i].fLayer->texture(),
- !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().width()
- : layers[i].fLayer->texture()->width(),
- !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().height()
- : layers[i].fLayer->texture()->height(),
- &bm);
- layerInfo->fImage = SkImage::NewTexture(bm);
-
- layerInfo->fPaint = layers[i].fLayer->paint()
- ? SkNEW_ARGS(SkPaint, (*layers[i].fLayer->paint()))
- : NULL;
-
- layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i].fLayer->rect().fLeft,
- layers[i].fLayer->rect().fTop,
- layers[i].fLayer->rect().width(),
- layers[i].fLayer->rect().height());
- }
-}
-
void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
const SkTDArray<GrHoistedLayer>& atlased) {
if (atlased.count() > 0) {
@@ -241,7 +200,7 @@ void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
for (int i = 0; i < atlased.count(); ++i) {
const GrCachedLayer* layer = atlased[i].fLayer;
const SkPicture* pict = atlased[i].fPicture;
- const SkIPoint offset = atlased[i].fOffset;
+ const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->bound().fTop);
SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
SkASSERT(!layerPaint || !layerPaint->getImageFilter());
@@ -250,10 +209,7 @@ void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
// Add a rect clip to make sure the rendering doesn't
// extend beyond the boundaries of the atlased sub-rect
- SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
- SkIntToScalar(layer->rect().fTop),
- SkIntToScalar(layer->rect().width()),
- SkIntToScalar(layer->rect().height()));
+ const SkRect bound = SkRect::Make(layer->rect());
atlasCanvas->clipRect(bound);
// Since 'clear' doesn't respect the clip we need to draw a rect
@@ -285,7 +241,7 @@ void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
for (int i = 0; i < layers.count(); ++i) {
GrCachedLayer* layer = layers[i].fLayer;
const SkPicture* pict = layers[i].fPicture;
- const SkIPoint& offset = layers[i].fOffset;
+ const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->bound().fTop);
// Each non-atlased layer has its own GrTexture
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
@@ -297,11 +253,7 @@ void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
// Add a rect clip to make sure the rendering doesn't
// extend beyond the boundaries of the layer
- SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
- SkIntToScalar(layer->rect().fTop),
- SkIntToScalar(layer->rect().width()),
- SkIntToScalar(layer->rect().height()));
-
+ const SkRect bound = SkRect::Make(layer->rect());
layerCanvas->clipRect(bound);
layerCanvas->clear(SK_ColorTRANSPARENT);
diff --git a/src/gpu/GrLayerHoister.h b/src/gpu/GrLayerHoister.h
index a28f887f61..2d68a94a88 100644
--- a/src/gpu/GrLayerHoister.h
+++ b/src/gpu/GrLayerHoister.h
@@ -20,7 +20,6 @@ public:
const SkPicture* fPicture; // the picture that actually contains the layer
// (not necessarily the top-most picture)
GrCachedLayer* fLayer;
- SkIPoint fOffset;
SkMatrix fInitialMat;
SkMatrix fPreMat;
SkMatrix fLocalMat;
diff --git a/src/gpu/GrRecordReplaceDraw.cpp b/src/gpu/GrRecordReplaceDraw.cpp
index 3701dda36e..852c51f418 100644
--- a/src/gpu/GrRecordReplaceDraw.cpp
+++ b/src/gpu/GrRecordReplaceDraw.cpp
@@ -5,50 +5,34 @@
* found in the LICENSE file.
*/
+#include "GrContext.h"
+#include "GrLayerCache.h"
#include "GrRecordReplaceDraw.h"
#include "SkCanvasPriv.h"
+#include "SkGrPixelRef.h"
#include "SkImage.h"
#include "SkRecordDraw.h"
#include "SkRecords.h"
-GrReplacements::ReplacementInfo* GrReplacements::newReplacement(uint32_t pictureID,
- const SkMatrix& initialMat,
- const int* key, int keySize) {
- ReplacementInfo* replacement = SkNEW_ARGS(ReplacementInfo, (pictureID, initialMat,
- key, keySize));
- fReplacementHash.add(replacement);
- return replacement;
+static inline void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* result) {
+ SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
+ result->setInfo(info);
+ result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
}
-void GrReplacements::freeAll() {
- SkTDynamicHash<ReplacementInfo, ReplacementInfo::Key>::Iter iter(&fReplacementHash);
+static inline void draw_replacement_bitmap(GrCachedLayer* layer, SkCanvas* canvas) {
+ const SkRect src = SkRect::Make(layer->rect());
+ const SkRect dst = SkRect::Make(layer->bound());
- for (; !iter.done(); ++iter) {
- ReplacementInfo* replacement = &(*iter);
- SkDELETE(replacement);
- }
-
- fReplacementHash.reset();
-}
-
-const GrReplacements::ReplacementInfo* GrReplacements::lookup(uint32_t pictureID,
- const SkMatrix& initialMat,
- const int* key,
- int keySize) const {
- return fReplacementHash.find(ReplacementInfo::Key(pictureID, initialMat, key, keySize));
-}
-
-static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo* ri,
- SkCanvas* canvas) {
- SkRect src = SkRect::Make(ri->fSrcRect);
- SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
- SkIntToScalar(ri->fPos.fY),
- SkIntToScalar(ri->fSrcRect.width()),
- SkIntToScalar(ri->fSrcRect.height()));
+ SkBitmap bm;
+ wrap_texture(layer->texture(),
+ !layer->isAtlased() ? layer->rect().width() : layer->texture()->width(),
+ !layer->isAtlased() ? layer->rect().height() : layer->texture()->height(),
+ &bm);
canvas->save();
canvas->setMatrix(SkMatrix::I());
- canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint);
+ canvas->drawBitmapRectToRect(bm, &src, dst, layer->paint());
canvas->restore();
}
@@ -56,19 +40,18 @@ static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo
// also draws them with replaced layers.
class ReplaceDraw : public SkRecords::Draw {
public:
- ReplaceDraw(SkCanvas* canvas,
+ ReplaceDraw(SkCanvas* canvas, GrLayerCache* layerCache,
SkPicture const* const drawablePicts[], int drawableCount,
const SkPicture* topLevelPicture,
const SkPicture* picture,
- const GrReplacements* replacements,
const SkMatrix& initialMatrix,
SkDrawPictureCallback* callback,
- const int* opIndices, int numIndices)
+ const unsigned* opIndices, int numIndices)
: INHERITED(canvas, drawablePicts, NULL, drawableCount)
, fCanvas(canvas)
+ , fLayerCache(layerCache)
, fTopLevelPicture(topLevelPicture)
, fPicture(picture)
- , fReplacements(replacements)
, fInitialMatrix(initialMatrix)
, fCallback(callback)
, fIndex(0)
@@ -137,8 +120,9 @@ public:
SkAutoCanvasMatrixPaint acmp(fCanvas, &dp.matrix, dp.paint, dp.picture->cullRect());
// Draw sub-pictures with the same replacement list but a different picture
- ReplaceDraw draw(fCanvas, this->drawablePicts(), this->drawableCount(),
- fTopLevelPicture, dp.picture, fReplacements, fInitialMatrix, fCallback,
+ ReplaceDraw draw(fCanvas, fLayerCache,
+ this->drawablePicts(), this->drawableCount(),
+ fTopLevelPicture, dp.picture, fInitialMatrix, fCallback,
fOpIndexStack.begin(), fOpIndexStack.count());
fNumReplaced += draw.draw();
@@ -158,23 +142,23 @@ public:
fOpIndexStack.push(startOffset);
- const GrReplacements::ReplacementInfo* ri = fReplacements->lookup(
- fTopLevelPicture->uniqueID(),
- fInitialMatrix,
- fOpIndexStack.begin(),
- fOpIndexStack.count());
+ GrCachedLayer* layer = fLayerCache->findLayer(fTopLevelPicture->uniqueID(),
+ fInitialMatrix,
+ fOpIndexStack.begin(),
+ fOpIndexStack.count());
- if (ri) {
+ if (layer) {
fNumReplaced++;
- draw_replacement_bitmap(ri, fCanvas);
+
+ draw_replacement_bitmap(layer, fCanvas);
if (fPicture->fBBH.get()) {
- while (fOps[fIndex] < ri->fStop) {
+ while (fOps[fIndex] < layer->stop()) {
++fIndex;
}
- SkASSERT(fOps[fIndex] == ri->fStop);
+ SkASSERT(fOps[fIndex] == layer->stop());
} else {
- fIndex = ri->fStop;
+ fIndex = layer->stop();
}
fOpIndexStack.pop();
return;
@@ -188,9 +172,9 @@ public:
private:
SkCanvas* fCanvas;
+ GrLayerCache* fLayerCache;
const SkPicture* fTopLevelPicture;
const SkPicture* fPicture;
- const GrReplacements* fReplacements;
const SkMatrix fInitialMatrix;
SkDrawPictureCallback* fCallback;
@@ -199,22 +183,21 @@ private:
int fNumReplaced;
// The op code indices of all the enclosing drawPicture and saveLayer calls
- SkTDArray<int> fOpIndexStack;
+ SkTDArray<unsigned> fOpIndexStack;
typedef Draw INHERITED;
};
int GrRecordReplaceDraw(const SkPicture* picture,
SkCanvas* canvas,
- const GrReplacements* replacements,
+ GrLayerCache* layerCache,
const SkMatrix& initialMatrix,
SkDrawPictureCallback* callback) {
SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
// TODO: drawablePicts?
- ReplaceDraw draw(canvas, NULL, 0,
+ ReplaceDraw draw(canvas, layerCache, NULL, 0,
picture, picture,
- replacements, initialMatrix, callback, NULL, 0);
-
+ initialMatrix, callback, NULL, 0);
return draw.draw();
}
diff --git a/src/gpu/GrRecordReplaceDraw.h b/src/gpu/GrRecordReplaceDraw.h
index 538661a7b4..c0dd0b6a32 100644
--- a/src/gpu/GrRecordReplaceDraw.h
+++ b/src/gpu/GrRecordReplaceDraw.h
@@ -8,124 +8,19 @@
#ifndef GrRecordReplaceDraw_DEFINED
#define GrRecordReplaceDraw_DEFINED
-#include "SkChecksum.h"
#include "SkDrawPictureCallback.h"
-#include "SkImage.h"
-#include "SkRect.h"
-#include "SkTDynamicHash.h"
-class SkBBoxHierarchy;
-class SkBitmap;
+class GrLayerCache;
class SkCanvas;
-class SkImage;
class SkMatrix;
-class SkPaint;
class SkPicture;
-class SkRecord;
-
-// GrReplacements collects op ranges that can be replaced with
-// a single drawBitmap call (using a precomputed bitmap).
-class GrReplacements {
-public:
- // All the operations between fStart and fStop (inclusive) will be replaced with
- // a single drawBitmap call using fPos, fImage and fPaint.
- class ReplacementInfo {
- public:
- struct Key {
- Key(uint32_t pictureID, const SkMatrix& initialMat,
- const int* key, int keySize, bool copyKey = false)
- : fKeySize(keySize)
- , fFreeKey(copyKey) {
- fIDMatrix.fPictureID = pictureID;
- fIDMatrix.fInitialMat = initialMat;
- fIDMatrix.fInitialMat.getType(); // force initialization of type so hashes match
-
- if (copyKey) {
- int* tempKey = SkNEW_ARRAY(int, keySize);
- memcpy(tempKey, key, keySize * sizeof(int));
- fKey = tempKey;
- } else {
- fKey = key;
- }
-
- // The pictureID/matrix portion needs to be tightly packed.
- GR_STATIC_ASSERT(sizeof(IDMatrix) == sizeof(uint32_t)+ // pictureID
- 9 * sizeof(SkScalar)+sizeof(uint32_t)); // matrix
- }
-
- ~Key() {
- if (fFreeKey) {
- SkDELETE_ARRAY(fKey);
- }
- }
- bool operator==(const Key& other) const {
- if (fKeySize != other.fKeySize) {
- return false;
- }
- return fIDMatrix.fPictureID == other.fIDMatrix.fPictureID &&
- fIDMatrix.fInitialMat.cheapEqualTo(other.fIDMatrix.fInitialMat) &&
- !memcmp(fKey, other.fKey, fKeySize * sizeof(int));
- }
-
- uint32_t hash() const {
- uint32_t hash = SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(fKey),
- fKeySize * sizeof(int));
- return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&fIDMatrix),
- sizeof(IDMatrix), hash);
- }
-
- private:
- struct IDMatrix {
- uint32_t fPictureID;
- SkMatrix fInitialMat;
- } fIDMatrix;
-
- const int* fKey;
- const int fKeySize;
- const bool fFreeKey;
- };
-
- static const Key& GetKey(const ReplacementInfo& layer) { return layer.fKey; }
- static uint32_t Hash(const Key& key) { return key.hash(); }
-
- ReplacementInfo(uint32_t pictureID, const SkMatrix& initialMat,
- const int* key, int keySize)
- : fKey(pictureID, initialMat, key, keySize, true)
- , fImage(NULL)
- , fPaint(NULL) {
- }
- ~ReplacementInfo() { fImage->unref(); SkDELETE(fPaint); }
-
- const Key fKey;
- unsigned fStop;
- SkIPoint fPos;
- SkImage* fImage; // Owns a ref
- const SkPaint* fPaint; // Owned by this object
-
- SkIRect fSrcRect;
- };
-
- ~GrReplacements() { this->freeAll(); }
-
- // Add a new replacement range.
- ReplacementInfo* newReplacement(uint32_t pictureID, const SkMatrix& initialMat,
- const int* key, int keySize);
-
- const ReplacementInfo* lookup(uint32_t pictureID, const SkMatrix& initalMat,
- const int* key, int keySize) const;
-
-private:
- SkTDynamicHash<ReplacementInfo, ReplacementInfo::Key> fReplacementHash;
-
- void freeAll();
-};
// Draw an SkPicture into an SkCanvas replacing saveLayer/restore blocks with
// drawBitmap calls. A convenience wrapper around SkRecords::Draw.
// It returns the number of saveLayer/restore blocks replaced with drawBitmap calls.
int GrRecordReplaceDraw(const SkPicture*,
SkCanvas*,
- const GrReplacements*,
+ GrLayerCache* layerCache,
const SkMatrix& initialMatrix,
SkDrawPictureCallback*);
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 3f08aa4def..407f36037d 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1863,13 +1863,9 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
GrLayerHoister::DrawLayers(fContext, needRendering);
- GrReplacements replacements;
-
- GrLayerHoister::ConvertLayersToReplacements(mainPicture, needRendering, &replacements);
- GrLayerHoister::ConvertLayersToReplacements(mainPicture, recycled, &replacements);
-
// Render the entire picture using new layers
- GrRecordReplaceDraw(mainPicture, mainCanvas, &replacements, initialMatrix, NULL);
+ GrRecordReplaceDraw(mainPicture, mainCanvas, fContext->getLayerCache(),
+ initialMatrix, NULL);
GrLayerHoister::UnlockLayers(fContext, needRendering);
GrLayerHoister::UnlockLayers(fContext, recycled);
diff --git a/tests/GpuLayerCacheTest.cpp b/tests/GpuLayerCacheTest.cpp
index 43a845b11d..cba331f8b4 100644
--- a/tests/GpuLayerCacheTest.cpp
+++ b/tests/GpuLayerCacheTest.cpp
@@ -15,7 +15,7 @@
class TestingAccess {
public:
- static int NumLayers(GrLayerCache* cache) {
+ static unsigned NumLayers(GrLayerCache* cache) {
return cache->numLayers();
}
static void Purge(GrLayerCache* cache, uint32_t pictureID) {
@@ -25,7 +25,8 @@ public:
return layer->uses();
}
static GrCachedLayer* Find(GrLayerCache* cache, uint32_t pictureID,
- const SkMatrix& initialMat, const int* key, int keySize) {
+ const SkMatrix& initialMat,
+ const unsigned* key, int keySize) {
return cache->findLayer(pictureID, initialMat, key, keySize);
}
};
@@ -34,11 +35,11 @@ public:
static void create_layers(skiatest::Reporter* reporter,
GrLayerCache* cache,
const SkPicture& picture,
- int numToAdd,
- int idOffset) {
+ unsigned numToAdd,
+ unsigned idOffset) {
- for (int i = 0; i < numToAdd; ++i) {
- int indices[1] = { idOffset+i+1 };
+ for (unsigned i = 0; i < numToAdd; ++i) {
+ unsigned indices[1] = { idOffset+i+1 };
GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(),
idOffset+i+1, idOffset+i+2,
SkIRect::MakeEmpty(),
@@ -116,8 +117,8 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
- for (int i = 0; i < kInitialNumLayers; ++i) {
- int indices[1] = { i + 1 };
+ for (unsigned i = 0; i < kInitialNumLayers; ++i) {
+ unsigned indices[1] = { i + 1 };
GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
indices, 1);
REPORTER_ASSERT(reporter, layer);
@@ -135,8 +136,8 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
}
// Unlock the textures
- for (int i = 0; i < kInitialNumLayers; ++i) {
- int indices[1] = { i+1 };
+ for (unsigned i = 0; i < kInitialNumLayers; ++i) {
+ unsigned indices[1] = { i+1 };
GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
indices, 1);
@@ -144,8 +145,8 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
cache.removeUse(layer);
}
- for (int i = 0; i < kInitialNumLayers; ++i) {
- int indices[1] = { i+1 };
+ for (unsigned i = 0; i < kInitialNumLayers; ++i) {
+ unsigned indices[1] = { i+1 };
GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
indices, 1);
@@ -172,7 +173,7 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
}
{
- int indices[1] = { kInitialNumLayers+1 };
+ unsigned indices[1] = { kInitialNumLayers+1 };
// Add an additional layer. Since all the layers are unlocked this
// will force out the first atlased layer
@@ -185,8 +186,8 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
cache.removeUse(layer);
}
- for (int i = 0; i < kInitialNumLayers+1; ++i) {
- int indices[1] = { i+1 };
+ for (unsigned i = 0; i < kInitialNumLayers+1; ++i) {
+ unsigned indices[1] = { i+1 };
GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
indices, 1);
diff --git a/tests/RecordReplaceDrawTest.cpp b/tests/RecordReplaceDrawTest.cpp
index 8fc824d8cc..edd4766c5f 100644
--- a/tests/RecordReplaceDrawTest.cpp
+++ b/tests/RecordReplaceDrawTest.cpp
@@ -9,6 +9,8 @@
#include "Test.h"
+#include "GrContextFactory.h"
+#include "GrLayerCache.h"
#include "GrRecordReplaceDraw.h"
#include "RecordTestUtils.h"
#include "SkBBHFactory.h"
@@ -47,9 +49,8 @@ DEF_TEST(RecordReplaceDraw_Abort, r) {
SkRecord rerecord;
SkRecorder canvas(&rerecord, kWidth, kHeight);
- GrReplacements replacements;
JustOneDraw callback;
- GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), &callback);
+ GrRecordReplaceDraw(pic, &canvas, NULL, SkMatrix::I(), &callback);
REPORTER_ASSERT(r, 3 == rerecord.count());
assert_type<SkRecords::Save>(r, rerecord, 0);
@@ -74,8 +75,7 @@ DEF_TEST(RecordReplaceDraw_Unbalanced, r) {
SkRecord rerecord;
SkRecorder canvas(&rerecord, kWidth, kHeight);
- GrReplacements replacements;
- GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), NULL/*callback*/);
+ GrRecordReplaceDraw(pic, &canvas, NULL, SkMatrix::I(), NULL/*callback*/);
REPORTER_ASSERT(r, 4 == rerecord.count());
assert_type<SkRecords::Save>(r, rerecord, 0);
@@ -84,20 +84,8 @@ DEF_TEST(RecordReplaceDraw_Unbalanced, r) {
assert_type<SkRecords::Restore>(r, rerecord, 3);
}
-static SkImage* make_image(SkColor color) {
- const SkPMColor pmcolor = SkPreMultiplyColor(color);
- const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
- const size_t rowBytes = info.minRowBytes();
- const size_t size = rowBytes * info.height();
-
- SkAutoMalloc addr(size);
- sk_memset32((SkPMColor*)addr.get(), pmcolor, SkToInt(size >> 2));
-
- return SkImage::NewRasterCopy(info, addr.get(), rowBytes);
-}
-
// Test out the layer replacement functionality with and w/o a BBH
-void test_replacements(skiatest::Reporter* r, bool useBBH) {
+void test_replacements(skiatest::Reporter* r, GrContext* context, bool useBBH) {
SkAutoTUnref<const SkPicture> pic;
{
@@ -115,34 +103,53 @@ void test_replacements(skiatest::Reporter* r, bool useBBH) {
pic.reset(recorder.endRecording());
}
- int key[1] = { 0 };
+ unsigned key[1] = { 0 };
- GrReplacements replacements;
- GrReplacements::ReplacementInfo* ri = replacements.newReplacement(pic->uniqueID(),
- SkMatrix::I(), key, 1);
- ri->fStop = 2;
- ri->fPos.set(0, 0);
- ri->fImage = make_image(SK_ColorRED);
- ri->fPaint = SkNEW(SkPaint);
- ri->fSrcRect = SkIRect::MakeWH(kWidth, kHeight);
+ GrLayerCache* layerCache = context->getLayerCache();
+ GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2,
+ SkIRect::MakeWH(kWidth, kHeight),
+ SkMatrix::I(), key, 1, SkNEW(SkPaint));
+
+ GrSurfaceDesc desc;
+ desc.fConfig = kSkia8888_GrPixelConfig;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
+ desc.fWidth = kWidth;
+ desc.fHeight = kHeight;
+ desc.fSampleCnt = 0;
+
+ SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
+ layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight));
SkAutoTUnref<SkBBoxHierarchy> bbh;
SkRecord rerecord;
SkRecorder canvas(&rerecord, kWidth, kHeight);
- GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), NULL/*callback*/);
+ GrRecordReplaceDraw(pic, &canvas, layerCache, SkMatrix::I(), NULL/*callback*/);
REPORTER_ASSERT(r, 7 == rerecord.count());
assert_type<SkRecords::Save>(r, rerecord, 0);
assert_type<SkRecords::Save>(r, rerecord, 1);
assert_type<SkRecords::SetMatrix>(r, rerecord, 2);
- assert_type<SkRecords::DrawImageRect>(r, rerecord, 3);
+ assert_type<SkRecords::DrawBitmapRectToRect>(r, rerecord, 3);
assert_type<SkRecords::Restore>(r, rerecord, 4);
assert_type<SkRecords::DrawRect>(r, rerecord, 5);
assert_type<SkRecords::Restore>(r, rerecord, 6);
}
-DEF_TEST(RecordReplaceDraw_Replace, r) { test_replacements(r, false); }
-DEF_TEST(RecordReplaceDraw_ReplaceWithBBH, r) { test_replacements(r, true); }
+DEF_GPUTEST(RecordReplaceDraw, r, factory) {
+ for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
+ GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
+ if (!GrContextFactory::IsRenderingGLContext(glType)) {
+ continue;
+ }
+ GrContext* context = factory->get(glType);
+ if (NULL == context) {
+ continue;
+ }
+
+ test_replacements(r, context, true);
+ test_replacements(r, context, false);
+ }
+}
#endif