Add clip to layer cache
This CL adds the clip region to the GPU layer hoisting image cache. It also switches back to the old caching behavior of using the entire CTM in the cache key rather then just the upper 2x2. This latter change is to focus more on hoisting rather then caching.
It also includes 2 smaller fixes:
a) layer's that have an image filter are no longer atlased (b.c. doing so complicates applying the image filter)
b) the result of clipping the layer's bounds to the current clip is used as the hoisted layer's size. This reduces the amount of pixels drawn to match a normal (non-hoisted) draw pass.
Review URL: https://codereview.chromium.org/640773004
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h
index d8c5ad9..aa0d325 100644
--- a/src/gpu/GrLayerCache.h
+++ b/src/gpu/GrLayerCache.h
@@ -51,36 +51,41 @@
public:
// For SkTDynamicHash
struct Key {
- // TODO: the key needs to include the clip
- Key(uint32_t pictureID, int start, const SkMatrix& ctm)
+ Key(uint32_t pictureID, int start, const SkIRect& bounds, const SkMatrix& ctm)
: fPictureID(pictureID)
- , fStart(start) {
- fCTM[0] = ctm.getScaleX();
- fCTM[1] = ctm.getSkewX();
- fCTM[2] = ctm.getSkewY();
- fCTM[3] = ctm.getScaleY();
+ , 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(SkScalar)); // 2x2 from CTM
+ 4 * sizeof(uint32_t) + // bounds
+ 9 * sizeof(SkScalar) + sizeof(uint32_t)); // matrix
}
bool operator==(const Key& other) const {
return fPictureID == other.fPictureID &&
fStart == other.fStart &&
- 0 == memcmp(fCTM, other.fCTM, sizeof(fCTM));
+ fBounds == other.fBounds &&
+ fCTM.cheapEqualTo(other.fCTM);
}
uint32_t pictureID() const { return fPictureID; }
int start() const { return fStart; }
+ const SkIRect& bound() const { return fBounds; }
+ const SkMatrix& ctm() const { return fCTM; }
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
- SkScalar fCTM[4];
+ SkMatrix fCTM;
};
static const Key& GetKey(const GrCachedLayer& layer) { return layer.fKey; }
@@ -90,8 +95,9 @@
// GrCachedLayer proper
GrCachedLayer(uint32_t pictureID, int start, int stop,
- const SkMatrix& ctm, const SkPaint* paint)
- : fKey(pictureID, start, ctm)
+ const SkIRect& bounds, const SkMatrix& ctm,
+ const SkPaint* paint)
+ : fKey(pictureID, start, bounds, ctm)
, fStop(stop)
, fPaint(paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL)
, fTexture(NULL)
@@ -109,6 +115,7 @@
uint32_t pictureID() const { return fKey.pictureID(); }
int start() const { return fKey.start(); }
+ const SkIRect& bound() const { return fKey.bound(); }
int stop() const { return fStop; }
void setTexture(GrTexture* texture, const GrIRect16& rect) {
@@ -193,9 +200,11 @@
// elements by the GrContext
void freeAll();
- GrCachedLayer* findLayer(uint32_t pictureID, int start, const SkMatrix& ctm);
+ 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 SkPaint* paint);
@@ -265,7 +274,8 @@
void initAtlas();
GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop,
- const SkMatrix& ctm, const SkPaint* paint);
+ const SkIRect& bounds, const SkMatrix& ctm,
+ const SkPaint* paint);
void purgeAll();