Add misc. optimizations to filter tool
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 11 Mar 2013 22:53:11 +0000 (22:53 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 11 Mar 2013 22:53:11 +0000 (22:53 +0000)
https://codereview.appspot.com/7705043/

git-svn-id: http://skia.googlecode.com/svn/trunk@8087 2bbb7eff-a529-9590-31e7-b0007b416f81

debugger/SkDebugCanvas.cpp
debugger/SkDebugCanvas.h
debugger/SkDrawCommand.cpp
debugger/SkDrawCommand.h
tools/filtermain.cpp

index 4e71bc3..e8589f3 100644 (file)
@@ -226,6 +226,10 @@ const SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() const {
     return fCommandVector;
 }
 
+SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() {
+    return fCommandVector;
+}
+
 // TODO(chudy): Free command string memory.
 SkTArray<SkString>* SkDebugCanvas::getDrawCommandsAsStrings() const {
     SkTArray<SkString>* commandString = new SkTArray<SkString>(fCommandVector.count());
index a29fe6a..5afc7fc 100644 (file)
@@ -91,6 +91,12 @@ public:
         Returns the vector of draw commands
      */
     const SkTDArray<SkDrawCommand*>& getDrawCommands() const;
+    
+    /**
+        Returns the vector of draw commands. Do not use this entry
+        point - it is going away!
+     */
+    SkTDArray<SkDrawCommand*>& getDrawCommands();
 
     /**
      * Returns the string vector of draw commands
index 8ffcb4b..c85d8c9 100644 (file)
@@ -394,7 +394,7 @@ void DrawRectC::execute(SkCanvas* canvas) {
 
 DrawRRect::DrawRRect(const SkRRect& rrect, const SkPaint& paint) {
     this->fRRect = rrect;
-    this->fPaint = &paint;
+    this->fPaint = paint;
     this->fDrawType = DRAW_RRECT;
 
     this->fInfo.push(SkObjectParser::RRectToString(rrect));
@@ -402,7 +402,7 @@ DrawRRect::DrawRRect(const SkRRect& rrect, const SkPaint& paint) {
 }
 
 void DrawRRect::execute(SkCanvas* canvas) {
-    canvas->drawRRect(this->fRRect, *this->fPaint);
+    canvas->drawRRect(fRRect, fPaint);
 }
 
 DrawSprite::DrawSprite(const SkBitmap& bitmap, int left, int top,
index c0c59e6..d06e7fe 100644 (file)
@@ -92,6 +92,11 @@ class ClipRect : public SkDrawCommand {
 public:
     ClipRect(const SkRect& rect, SkRegion::Op op, bool doAA);
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
+
+    const SkRect& rect() const { return *fRect; }
+    SkRegion::Op op() const { return fOp; }
+    bool doAA() const { return fDoAA; }
+
 private:
     const SkRect* fRect;
     SkRegion::Op fOp;
@@ -102,6 +107,11 @@ class ClipRRect : public SkDrawCommand {
 public:
     ClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA);
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
+
+    const SkRRect& rrect() const { return fRRect; }
+    SkRegion::Op op() const { return fOp; }
+    bool doAA() const { return fDoAA; }
+
 private:
     SkRRect fRRect;
     SkRegion::Op fOp;
@@ -173,6 +183,8 @@ public:
 
     void setPaint(const SkPaint& paint) { fPaint = paint; fPaintPtr = &fPaint; }
 
+    const SkRect& dstRect() { return *fDst; }
+
 private:
     const SkRect* fSrc;
     SkPaint fPaint;
@@ -298,6 +310,9 @@ class DrawRectC : public SkDrawCommand {
 public:
     DrawRectC(const SkRect& rect, const SkPaint& paint);
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
+
+    const SkRect& rect() const { return *fRect; }
+    const SkPaint* paint() const { return fPaint; }
 private:
     const SkRect* fRect;
     const SkPaint* fPaint;
@@ -309,7 +324,7 @@ public:
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
 private:
     SkRRect fRRect;
-    const SkPaint* fPaint;
+    SkPaint fPaint;
 };
 
 class DrawSprite : public SkDrawCommand {
index e0ab835..74cf427 100644 (file)
@@ -75,7 +75,7 @@ static bool check_0(const SkTDArray<SkDrawCommand*>& commands, int curCommand) {
 
 // Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer
 // and restore
-static void apply_0(const SkTDArray<SkDrawCommand*>& commands, int curCommand) {
+static void apply_0(SkTDArray<SkDrawCommand*>& commands, int curCommand) {
     SaveLayer* saveLayer = (SaveLayer*) commands[curCommand];
     DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+1];
     Restore* restore = (Restore*) commands[curCommand+2];
@@ -140,7 +140,7 @@ static bool check_1(const SkTDArray<SkDrawCommand*>& commands, int curCommand) {
 
 // Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer
 // and restore
-static void apply_1(const SkTDArray<SkDrawCommand*>& commands, int curCommand) {
+static void apply_1(SkTDArray<SkDrawCommand*>& commands, int curCommand) {
     SaveLayer* saveLayer = (SaveLayer*) commands[curCommand];
     DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+3];
     Restore* restore = (Restore*) commands[curCommand+5];
@@ -164,8 +164,124 @@ static void apply_1(const SkTDArray<SkDrawCommand*>& commands, int curCommand) {
     }
 }
 
+// Check for:
+//    SAVE
+//        CLIP_RECT
+//        DRAW_RECT
+//    RESTORE
+// where the rect is entirely within the clip and the clip is an intersect
+static bool check_2(const SkTDArray<SkDrawCommand*>& commands, int curCommand) {
+    if (SAVE != commands[curCommand]->getType() ||
+        commands.count() <= curCommand+4 ||
+        CLIP_RECT != commands[curCommand+1]->getType() ||
+        DRAW_RECT != commands[curCommand+2]->getType() ||
+        RESTORE != commands[curCommand+3]->getType())
+        return false;
+
+    ClipRect* cr = (ClipRect*) commands[curCommand+1];
+    DrawRectC* dr = (DrawRectC*) commands[curCommand+2];
+
+    if (SkRegion::kIntersect_Op != cr->op()) {
+        return false;
+    }
+
+    return cr->rect().contains(dr->rect());
+}
+
+// Remove everything but the drawRect
+static void apply_2(SkTDArray<SkDrawCommand*>& commands, int curCommand) {
+    Save* save = (Save*) commands[curCommand];
+    ClipRect* cr = (ClipRect*) commands[curCommand+1];
+    Restore* restore = (Restore*) commands[curCommand+3];
+
+    save->setVisible(false);
+    cr->setVisible(false);
+    // leave the drawRect alone
+    restore->setVisible(false);
+}
+
+// Check for:
+//    SAVE
+//        CLIP_RRECT
+//        DRAW_RECT
+//    RESTORE
+// where the rect entirely encloses the clip
+static bool check_3(const SkTDArray<SkDrawCommand*>& commands, int curCommand) {
+    if (SAVE != commands[curCommand]->getType() ||
+        commands.count() <= curCommand+4 ||
+        CLIP_RRECT != commands[curCommand+1]->getType() ||
+        DRAW_RECT != commands[curCommand+2]->getType() ||
+        RESTORE != commands[curCommand+3]->getType())
+        return false;
+
+    ClipRRect* crr = (ClipRRect*) commands[curCommand+1];
+    DrawRectC* dr  = (DrawRectC*) commands[curCommand+2];
+
+    if (SkRegion::kIntersect_Op != crr->op()) {
+        return false;
+    }
+
+    return dr->rect().contains(crr->rrect().rect());
+}
+
+// Replace everything with a drawRRect with the paint from the drawRect
+// and the AA settings from the clipRRect
+static void apply_3(SkTDArray<SkDrawCommand*>& commands, int curCommand) {
+    Save* save = (Save*) commands[curCommand];
+    ClipRRect* crr = (ClipRRect*) commands[curCommand+1];
+    DrawRectC* dr = (DrawRectC*) commands[curCommand+2];
+    Restore* restore = (Restore*) commands[curCommand+3];
+
+    save->setVisible(false);
+    crr->setVisible(false);
+    dr->setVisible(false);
+    restore->setVisible(false);
+
+    // TODO: could skip paint re-creation if the AA settings already match
+    SkPaint newPaint = *dr->paint();
+    newPaint.setAntiAlias(crr->doAA());
+    DrawRRect* drr = new DrawRRect(crr->rrect(), newPaint);
+    commands[curCommand+2] = drr;
+}
+
+// Check for:
+//    SAVE
+//        CLIP_RECT
+//        DRAW_BITMAP_RECT_TO_RECT
+//    RESTORE
+// where the rect and drawBitmapRect dst exactly match
+static bool check_4(const SkTDArray<SkDrawCommand*>& commands, int curCommand) {
+    if (SAVE != commands[curCommand]->getType() ||
+        commands.count() <= curCommand+4 ||
+        CLIP_RECT != commands[curCommand+1]->getType() ||
+        DRAW_BITMAP_RECT_TO_RECT != commands[curCommand+2]->getType() ||
+        RESTORE != commands[curCommand+3]->getType())
+        return false;
+
+    ClipRect* cr = (ClipRect*) commands[curCommand+1];
+    DrawBitmapRect* dbmr  = (DrawBitmapRect*) commands[curCommand+2];
+
+    if (SkRegion::kIntersect_Op != cr->op()) {
+        return false;
+    }
+
+    return dbmr->dstRect() == cr->rect();
+}
+
+// Remove everything but the drawBitmapRect
+static void apply_4(SkTDArray<SkDrawCommand*>& commands, int curCommand) {
+    Save* save = (Save*) commands[curCommand];
+    ClipRect* cr = (ClipRect*) commands[curCommand+1];
+    Restore* restore = (Restore*) commands[curCommand+3];
+
+    save->setVisible(false);
+    cr->setVisible(false);
+    // leave drawBitmapRect alone
+    restore->setVisible(false);
+}
+
 typedef bool (*PFCheck)(const SkTDArray<SkDrawCommand*>& commands, int curCommand);
-typedef void (*PFApply)(const SkTDArray<SkDrawCommand*>& commands, int curCommand);
+typedef void (*PFApply)(SkTDArray<SkDrawCommand*>& commands, int curCommand);
 
 struct OptTableEntry {
     PFCheck fCheck;
@@ -174,6 +290,9 @@ struct OptTableEntry {
 } gOptTable[] = {
     { check_0, apply_0, 0 },
     { check_1, apply_1, 0 },
+    { check_2, apply_2, 0 },
+    { check_3, apply_3, 0 },
+    { check_4, apply_4, 0 },
 };
 
 static int filter_picture(const SkString& inFile, const SkString& outFile) {
@@ -197,7 +316,7 @@ static int filter_picture(const SkString& inFile, const SkString& outFile) {
     debugCanvas.setBounds(inPicture->width(), inPicture->height());
     inPicture->draw(&debugCanvas);
 
-    const SkTDArray<SkDrawCommand*>& commands = debugCanvas.getDrawCommands();
+    SkTDArray<SkDrawCommand*>& commands = debugCanvas.getDrawCommands();
 
     // hide the initial save and restore since replaying the commands will
     // re-add them