Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrRecordReplaceDraw.h
index 3ba43dc..9110ac8 100644 (file)
@@ -8,15 +8,19 @@
 #ifndef GrRecordReplaceDraw_DEFINED
 #define GrRecordReplaceDraw_DEFINED
 
+#include "SkChecksum.h"
 #include "SkDrawPictureCallback.h"
+#include "SkImage.h"
 #include "SkRect.h"
-#include "SkTDArray.h"
+#include "SkTDynamicHash.h"
 
 class SkBBoxHierarchy;
 class SkBitmap;
 class SkCanvas;
 class SkImage;
+class SkMatrix;
 class SkPaint;
+class SkPicture;
 class SkRecord;
 
 // GrReplacements collects op ranges that can be replaced with
@@ -24,9 +28,53 @@ class SkRecord;
 class GrReplacements {
 public:
     // All the operations between fStart and fStop (inclusive) will be replaced with
-    // a single drawBitmap call using fPos, fBM and fPaint.
-    struct ReplacementInfo {
-        unsigned        fStart;
+    // a single drawBitmap call using fPos, fImage and fPaint.
+    class ReplacementInfo {
+    public:
+        struct Key {
+            Key(uint32_t pictureID, unsigned int start, const SkMatrix& ctm)
+            : fPictureID(pictureID)
+            , fStart(start)
+            , 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
+                                                9 * sizeof(SkScalar)    // 3x3 from CTM
+                                                +sizeof(uint32_t));     // matrix's type
+            }
+
+            bool operator==(const Key& other) const { 
+                return fPictureID == other.fPictureID &&
+                       fStart == other.fStart &&
+                       fCTM.cheapEqualTo(other.fCTM); // TODO: should be fuzzy
+            }
+
+            uint32_t     pictureID() const { return fPictureID; }
+            unsigned int start() const { return fStart; }
+
+        private:
+            const uint32_t     fPictureID;
+            const unsigned int fStart;
+            const SkMatrix     fCTM;
+        };
+
+        static const Key& GetKey(const ReplacementInfo& layer) { return layer.fKey; }
+        static uint32_t Hash(const Key& key) {
+            return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&key), sizeof(Key));
+        }
+
+        ReplacementInfo(uint32_t pictureID, unsigned int start, const SkMatrix& ctm)
+            : fKey(pictureID, start, ctm)
+            , fImage(NULL)
+            , fPaint(NULL) {
+        }
+        ~ReplacementInfo() { fImage->unref(); SkDELETE(fPaint); }
+
+        unsigned int start() const { return fKey.start(); }
+
+        const Key       fKey;
         unsigned        fStop;
         SkIPoint        fPos;
         SkImage*        fImage;  // Owns a ref
@@ -37,33 +85,27 @@ public:
 
     ~GrReplacements() { this->freeAll(); }
 
-    // Add a new replacement range. The replacement ranges should be
-    // sorted in increasing order and non-overlapping (esp. no nested
-    // saveLayers).
-    ReplacementInfo* push();
+    // Add a new replacement range.
+    ReplacementInfo* newReplacement(uint32_t pictureID, unsigned int start, const SkMatrix& ctm);
 
-    // look up a replacement range by its start offset.
-    // lastLookedUp is an in/out parameter that is used to speed up the search.
-    // It should be initialized to 0 on the first call and then passed back in
-    // unmodified on subsequent calls.
-    const ReplacementInfo* lookupByStart(size_t start, int* lastLookedUp) const;
+    // look up a replacement range by its pictureID, start offset and the CTM
+    // TODO: also need to add clip to lookup
+    const ReplacementInfo* lookupByStart(uint32_t pictureID, size_t start, 
+                                         const SkMatrix& ctm) const;
 
 private:
-    SkTDArray<ReplacementInfo> fReplacements;
+    SkTDynamicHash<ReplacementInfo, ReplacementInfo::Key> fReplacementHash;
 
     void freeAll();
-
-#ifdef SK_DEBUG
-    void validate() const;
-#endif
 };
 
-// Draw an SkRecord into an SkCanvas replacing saveLayer/restore blocks with
+// Draw an SkPicture into an SkCanvas replacing saveLayer/restore blocks with
 // drawBitmap calls.  A convenience wrapper around SkRecords::Draw.
-void GrRecordReplaceDraw(const SkRecord&, 
-                         SkCanvas*,
-                         const SkBBoxHierarchy*,
-                         const GrReplacements*,
-                         SkDrawPictureCallback*);
+// It returns the number of saveLayer/restore blocks replaced with drawBitmap calls.
+int GrRecordReplaceDraw(const SkPicture*,
+                        SkCanvas*,
+                        const GrReplacements*,
+                        const SkMatrix& initialMatrix,
+                        SkDrawPictureCallback*);
 
 #endif // GrRecordReplaceDraw_DEFINED