Index: src/gpu/GrLayerCache.h |
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h |
index 75e913056027113ce0b94c885dbc4bece527d7e2..967503dff7fe8f72d5221e35409067e22d945370 100644 |
--- a/src/gpu/GrLayerCache.h |
+++ b/src/gpu/GrLayerCache.h |
@@ -76,53 +76,80 @@ struct GrCachedLayer { |
public: |
// For SkTDynamicHash |
struct Key { |
- Key(uint32_t pictureID, int start, const SkIRect& bounds, const SkMatrix& ctm) |
- : fPictureID(pictureID) |
- , fStart(start) |
- , fBounds(bounds) |
- , fCTM(ctm) { |
- fCTM.getType(); // force initialization of type so hashes match |
- |
- // Key needs to be tightly packed. |
- GR_STATIC_ASSERT(sizeof(Key) == sizeof(uint32_t) + // picture ID |
- sizeof(int) + // start index |
- 4 * sizeof(uint32_t) + // bounds |
- 9 * sizeof(SkScalar) + sizeof(uint32_t)); // matrix |
+ Key(uint32_t pictureID, const SkMatrix& initialMat, |
bsalomon
2014/12/01 16:40:47
Is the not copy optimization worth the risk of get
robertphillips
2014/12/01 16:59:08
The not-copy option is used in the lookup case in
|
+ 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 { |
- return fPictureID == other.fPictureID && |
- fStart == other.fStart && |
- fBounds == other.fBounds && |
- fCTM.cheapEqualTo(other.fCTM); |
+ 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 pictureID() const { return fPictureID; } |
- int start() const { return fStart; } |
- const SkIRect& bound() const { return fBounds; } |
+ uint32_t pictureID() const { return fIDMatrix.fPictureID; } |
+ |
+ // TODO: remove these when GrCachedLayer & ReplacementInfo fuse |
+ const int* key() const { SkASSERT(fFreeKey); return fKey; } |
+ int keySize() const { SkASSERT(fFreeKey); return fKeySize; } |
+ |
+ 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: |
- // ID of the picture of which this layer is a part |
- const uint32_t fPictureID; |
- // The the index of the saveLayer command in the picture |
- const int fStart; |
- // The bounds of the layer. The TL corner is its offset. |
- const SkIRect fBounds; |
- // The 2x2 portion of the CTM applied to this layer in the picture |
- SkMatrix fCTM; |
+ struct IDMatrix { |
+ // ID of the picture of which this layer is a part |
+ uint32_t fPictureID; |
+ // The initial matrix passed into drawPicture |
+ SkMatrix fInitialMat; |
+ } fIDMatrix; |
+ |
+ const int* fKey; |
+ const int fKeySize; |
+ bool fFreeKey; |
}; |
static const Key& GetKey(const GrCachedLayer& layer) { return layer.fKey; } |
- static uint32_t Hash(const Key& key) { |
- return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&key), sizeof(Key)); |
- } |
+ static uint32_t Hash(const Key& key) { return key.hash(); } |
// GrCachedLayer proper |
GrCachedLayer(uint32_t pictureID, int start, int stop, |
const SkIRect& bounds, const SkMatrix& ctm, |
+ const int* key, int keySize, |
const SkPaint* paint) |
- : fKey(pictureID, start, bounds, ctm) |
+ : fKey(pictureID, ctm, key, keySize, true) |
+ , fStart(start) |
, fStop(stop) |
+ , fBounds(bounds) |
, fPaint(paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL) |
, fTexture(NULL) |
, fRect(GrIRect16::MakeEmpty()) |
@@ -138,9 +165,13 @@ public: |
} |
uint32_t pictureID() const { return fKey.pictureID(); } |
- int start() const { return fKey.start(); } |
- const SkIRect& bound() const { return fKey.bound(); } |
+ // TODO: remove these when GrCachedLayer & ReplacementInfo fuse |
+ const int* key() const { return fKey.key(); } |
+ int keySize() const { return fKey.keySize(); } |
+ int 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) { |
SkRefCnt_SafeAssign(fTexture, texture); |
@@ -167,9 +198,13 @@ public: |
private: |
const Key fKey; |
+ // The "saveLayer" operation index of the cached layer |
+ const int fStart; |
// The final "restore" operation index of the cached layer |
const int fStop; |
+ const SkIRect fBounds; |
+ |
// The paint used when dropping the layer down into the owning canvas. |
// Can be NULL. This class makes a copy for itself. |
const SkPaint* fPaint; |
@@ -224,12 +259,11 @@ public: |
// elements by the GrContext |
void freeAll(); |
- GrCachedLayer* findLayer(uint32_t pictureID, int start, |
- const SkIRect& bounds, const SkMatrix& ctm); |
GrCachedLayer* findLayerOrCreate(uint32_t pictureID, |
int start, int stop, |
const SkIRect& bounds, |
- const SkMatrix& ctm, |
+ const SkMatrix& initialMat, |
+ const int* key, int keySize, |
const SkPaint* paint); |
// Attempt to place 'layer' in the atlas. Return true on success; false on failure. |
@@ -310,8 +344,9 @@ private: |
void unlock(GrCachedLayer* layer); |
void initAtlas(); |
- GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop, |
- const SkIRect& bounds, const SkMatrix& ctm, |
+ GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop, |
+ const SkIRect& bounds, const SkMatrix& initialMat, |
+ const int* key, int keySize, |
const SkPaint* paint); |
// Remove all the layers (and unlock any resources) associated with 'pictureID' |
@@ -332,6 +367,8 @@ 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 |