Optimized hit testing feature, refactored into seperate function from canvas draw...
authorchudy@google.com <chudy@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 31 Jul 2012 19:55:32 +0000 (19:55 +0000)
committerchudy@google.com <chudy@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 31 Jul 2012 19:55:32 +0000 (19:55 +0000)
Review URL: https://codereview.appspot.com/6443068

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

debugger/QT/SkCanvasWidget.cpp
debugger/QT/SkGLWidget.cpp
debugger/QT/SkGLWidget.h
debugger/QT/SkRasterWidget.cpp
debugger/QT/SkRasterWidget.h
debugger/SkDebugCanvas.cpp
debugger/SkDebugCanvas.h
debugger/SkDrawCommand.h
debugger/SkHitBox.cpp [deleted file]
debugger/SkHitBox.h [deleted file]
gyp/debugger.gyp

index e4716af..c560aec 100644 (file)
@@ -33,9 +33,7 @@ SkCanvasWidget::SkCanvasWidget() : QWidget()
 }
 
 SkCanvasWidget::~SkCanvasWidget() {
-    if (fDebugCanvas) {
-        delete fDebugCanvas;
-    }
+    delete fDebugCanvas;
 }
 
 void SkCanvasWidget::drawTo(int index) {
@@ -78,13 +76,8 @@ void SkCanvasWidget::mouseMoveEvent(QMouseEvent* event) {
 
 void SkCanvasWidget::mousePressEvent(QMouseEvent* event) {
     fPreviousPoint.set(event->globalX(), event->globalY());
-    if (fDebugCanvas) {
-        fDebugCanvas->getBoxClass()->setHitPoint(event->x(), event->y());
-        fDebugCanvas->isCalculatingHits(true);
-        drawTo(fIndex);
-        emit hitChanged(fDebugCanvas->getHitBoxPoint());
-        fDebugCanvas->isCalculatingHits(false);
-    }
+    emit hitChanged(fDebugCanvas->getLayerAtPoint(event->x(), event->y(),
+            fIndex, fTransform, fScaleFactor));
 }
 
 void SkCanvasWidget::mouseDoubleClickEvent(QMouseEvent* event) {
index 74ed48e..e3c4161 100644 (file)
@@ -54,8 +54,7 @@ void SkGLWidget::paintGL() {
     } else if (fScaleFactor > 0) {
         canvas.scale(fScaleFactor, fScaleFactor);
     }
-    // TODO(chudy): Remove bitmap arguement.
-    fDebugCanvas->drawTo(&canvas, fIndex+1, NULL);
+    fDebugCanvas->drawTo(&canvas, fIndex);
     canvas.flush();
 }
 
index 5295f4c..76257be 100644 (file)
@@ -29,7 +29,7 @@ public:
 
     void setDebugCanvas(SkDebugCanvas* debugCanvas) {
         fDebugCanvas = debugCanvas;
-        fIndex = debugCanvas->getSize();
+        fIndex = debugCanvas->getSize() - 1;
         this->updateGL();
     }
 
index db89de7..2cf1f34 100644 (file)
@@ -28,12 +28,8 @@ SkRasterWidget::~SkRasterWidget() {
 void SkRasterWidget::resizeEvent(QResizeEvent* event) {
     fBitmap.setConfig(SkBitmap::kARGB_8888_Config, event->size().width(), event->size().height());
     fBitmap.allocPixels();
-    if (fDevice) {
-        delete fDevice;
-    }
-        fDevice = new SkDevice(fBitmap);
-
-
+    delete fDevice;
+    fDevice = new SkDevice(fBitmap);
     this->update();
 }
 
@@ -50,7 +46,7 @@ void SkRasterWidget::paintEvent(QPaintEvent* event) {
 
         fMatrix = canvas.getTotalMatrix();
         fClip = canvas.getTotalClip().getBounds();
-        fDebugCanvas->drawTo(&canvas, fIndex+1, &fBitmap);
+        fDebugCanvas->drawTo(&canvas, fIndex);
 
         QPainter painter(this);
         QStyleOption opt;
index af65792..1692800 100644 (file)
@@ -31,7 +31,7 @@ public:
 
     void setDebugCanvas(SkDebugCanvas* debugCanvas) {
         fDebugCanvas = debugCanvas;
-        fIndex = debugCanvas->getSize();
+        fIndex = debugCanvas->getSize() - 1;
         this->update();
     }
 
index 12d7127..9819858 100644 (file)
@@ -29,47 +29,62 @@ void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
 void SkDebugCanvas::draw(SkCanvas* canvas) {
     if(!commandVector.empty()) {
         for(it = commandVector.begin(); it != commandVector.end(); ++it) {
-            if ((*it)->getVisibility()) {
+            if ((*it)->isVisible()) {
                 (*it)->execute(canvas);
             }
         }
     }
 }
 
-void SkDebugCanvas::drawTo(SkCanvas* canvas, int index, SkBitmap* bitmap) {
+int SkDebugCanvas::getCommandAtPoint(int x, int y, int index,
+        SkIPoint transform, float scale) {
+    SkBitmap bitmap;
+    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
+    bitmap.allocPixels();
+
+    SkCanvas canvas(bitmap);
+    canvas.translate(transform.fX - x, transform.fY - y);
+    if (scale < 0) {
+        canvas.scale((1.0 / -scale), (1.0 / -scale));
+    } else if (scale > 0) {
+        canvas.scale(scale, scale);
+    }
+
+    int layer = 0;
+    int prev = bitmap.getColor(0,0);
+    for (int i = 0; i < index; i++) {
+        if (commandVector[i]->isVisible()) {
+            commandVector[i]->execute(&canvas);
+        }
+        if (prev != bitmap.getColor(0,0)) {
+            layer = i;
+        }
+        prev = bitmap.getColor(0,0);
+    }
+    return layer;
+}
+
+void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
     int counter = 0;
-    if(!commandVector.empty()) {
-        for(it = commandVector.begin(); it != commandVector.end(); ++it) {
-            if (counter != (index-1)) {
-                 if ((*it)->getVisibility()) {
-                     (*it)->execute(canvas);
-                 }
-             } else {
-                 if (fFilter) {
-                     SkPaint* p = new SkPaint();
-                     p->setColor(0xAAFFFFFF);
-                     canvas->save();
-                     canvas->resetMatrix();
-                     SkRect dump;
-                     // TODO(chudy): Replace with a call to QtWidget to get dimensions.
-                     dump.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(fWidth), SkIntToScalar(fHeight));
-                     canvas->clipRect(dump,  SkRegion::kReplace_Op, false );
-                     canvas->drawRectCoords(SkIntToScalar(0),SkIntToScalar(0),SkIntToScalar(fWidth),SkIntToScalar(fHeight), *p);
-                     canvas->restore();
-                 }
-                 if ((*it)->getVisibility()) {
-                     (*it)->execute(canvas);
-                 }
-             }
-            if (fCalculateHits == true && bitmap != NULL) {
-                fHitBox.updateHitPoint(bitmap, counter);
-            }
+    SkASSERT(!commandVector.empty());
+    SkASSERT(index < commandVector.size());
+    for (int i = 0; i <= index; i++) {
+        if (i == index && fFilter) {
+            SkPaint p;
+            p.setColor(0xAAFFFFFF);
+            canvas->save();
+            canvas->resetMatrix();
+            SkRect mask;
+            mask.set(SkIntToScalar(0), SkIntToScalar(0),
+                    SkIntToScalar(fWidth), SkIntToScalar(fHeight));
+            canvas->clipRect(mask, SkRegion::kReplace_Op, false);
+            canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
+                    SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
+            canvas->restore();
+        }
 
-            /* TODO(chudy): Implement a bitmap wide function that will take
-             *  ~50 out of each R,G,B. This will make everything but the last
-             *  command brighter.
-             */
-            if (++counter == index) return;
+        if (commandVector[i]->isVisible()) {
+            commandVector[i]->execute(canvas);
         }
     }
 }
@@ -86,7 +101,7 @@ std::vector<std::string>* SkDebugCanvas::getCommandInfoAt(int index) {
 
 bool SkDebugCanvas::getDrawCommandVisibilityAt(int index) {
     SkASSERT(index < commandVector.size());
-    return commandVector[index]->getVisibility();
+    return commandVector[index]->isVisible();
 }
 
 std::vector<SkDrawCommand*> SkDebugCanvas::getDrawCommands() {
@@ -252,5 +267,5 @@ bool SkDebugCanvas::translate(SkScalar dx, SkScalar dy) {
 
 void SkDebugCanvas::toggleCommand(int index, bool toggle) {
     SkASSERT(index < commandVector.size());
-    commandVector[index]->setVisibility(toggle);
+    commandVector[index]->setVisible(toggle);
 }
index fa2d757..c13ea10 100644 (file)
@@ -13,7 +13,6 @@
 #include "SkCanvas.h"
 #include "SkDrawCommand.h"
 #include "SkPicture.h"
-#include "SkHitBox.h"
 #include <vector>
 
 class SkDebugCanvas : public SkCanvas {
@@ -43,7 +42,13 @@ public:
         @param canvas  The canvas being drawn to
         @param index  The index of the final command being executed
      */
-    void drawTo(SkCanvas* canvas, int index, SkBitmap* bitmap);
+    void drawTo(SkCanvas* canvas, int index);
+
+    /**
+        Returns the index of the last draw command to write to the pixel at (x,y)
+     */
+    int getCommandAtPoint(int x, int y, int index,
+            SkIPoint transform, float scale);
 
     /**
         Returns the draw command at the given index.
@@ -74,31 +79,12 @@ public:
     std::vector<std::string>* getDrawCommandsAsStrings();
 
     /**
-        Returns the mapping of all pixels to a layer value.
-     */
-    int* getHitBox() {
-        return fHitBox.getHitBox();
-    }
-
-    SkHitBox* getBoxClass() {
-        return &fHitBox;
-    }
-
-    int getHitBoxPoint() {
-        return fHitBox.getPoint();
-    }
-
-    /**
         Returns length of draw command vector.
      */
     int getSize() {
         return commandVector.size();
     }
 
-    void isCalculatingHits(bool isEnabled) {
-        fCalculateHits = isEnabled;
-    }
-
     /**
         Toggles the visibility / execution of the draw command at index i with
         the value of toggle.
@@ -194,8 +180,6 @@ private:
     int fHeight;
     int fWidth;
     SkBitmap fBm;
-    SkHitBox fHitBox;
-    bool fCalculateHits;
     bool fFilter;
 
     /**
index 45d9dd6..f09dae9 100644 (file)
@@ -28,8 +28,13 @@ public:
         return GetCommandString(fDrawType);
     }
 
-    bool getVisibility() const { return fVisible; }
-    void setVisibility(bool toggle) {fVisible = toggle; }
+    bool isVisible() const {
+        return fVisible;
+    }
+
+    void setVisible(bool toggle) {
+        fVisible = toggle;
+    }
 
     std::vector<std::string>* Info() {return &fInfo; };
     virtual void execute(SkCanvas* canvas)=0;
diff --git a/debugger/SkHitBox.cpp b/debugger/SkHitBox.cpp
deleted file mode 100644 (file)
index a65fcc4..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#include "SkHitBox.h"
-
-SkHitBox::SkHitBox() {
-    fHitBox = NULL;
-    fX = -1;
-    fY = -1;
-    fLayer = -1;
-}
-
-SkHitBox::~SkHitBox() {}
-
-void SkHitBox::alloc(int width, int height) {
-    free(fHitBox);
-    int length = width * height;
-    fHitBox = (int*) malloc(length * sizeof(int));
-    for (int i = 0; i < length; i++) {
-        fHitBox[i] = 0;
-    }
-}
-
-void SkHitBox::updateHitBox(SkBitmap* newBitmap, int layer) {
-        int length = fPrev.width() * fPrev.height();
-        int* prevBase = (int*)fPrev.getPixels();
-        int* currBase = (int*)newBitmap->getPixels();
-
-        for (int i = 0; i < length; i++) {
-            if (SkUnPreMultiply::PMColorToColor(prevBase[i]) !=
-                    SkUnPreMultiply::PMColorToColor(currBase[i])) {
-                fHitBox[i] = layer;
-            }
-        }
-        if (fPrev.empty()) {
-            alloc(newBitmap->width(), newBitmap->height());
-            fPrev.setConfig(SkBitmap::kARGB_8888_Config, newBitmap->width(), newBitmap->height());
-            fPrev.allocPixels();
-        }
-        newBitmap->deepCopyTo(&fPrev, SkBitmap::kARGB_8888_Config);
-}
-
-void SkHitBox::updateHitPoint(SkBitmap* newBitmap, int layer) {
-    int* prevBase = (int*)fPrev.getPixels();
-    int* currBase = (int*)newBitmap->getPixels();
-    int pixel = fY * fPrev.width() + fX;
-
-    if (pointIsSet() && !fPrev.empty()) {
-        if (SkUnPreMultiply::PMColorToColor(prevBase[pixel]) !=
-                SkUnPreMultiply::PMColorToColor(currBase[pixel])) {
-            fLayer = layer;
-        }
-    }
-    if (fPrev.empty()) {
-        alloc(newBitmap->width(), newBitmap->height());
-        fPrev.setConfig(SkBitmap::kARGB_8888_Config, newBitmap->width(), newBitmap->height());
-        fPrev.allocPixels();
-    }
-    newBitmap->deepCopyTo(&fPrev, SkBitmap::kARGB_8888_Config);
-}
diff --git a/debugger/SkHitBox.h b/debugger/SkHitBox.h
deleted file mode 100644 (file)
index 19a65fd..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SKHITBOX_H_
-#define SKHITBOX_H_
-
-#include "SkBitmap.h"
-#include "SkUnPreMultiply.h"
-
-/* NOTE(chudy): It's possible that this class can be entirely static similar to
- * SkObjectParser. We will have to pass in the fHitBox void * every call.
- */
-class SkHitBox {
-public:
-    SkHitBox();
-    ~SkHitBox();
-
-    /**
-        Allocates enough space in memory for our hitbox pointer to contain
-        a layer value for every pixel. Initializes every value to 0.
-     */
-    void alloc(int width, int height);
-
-    /**
-        Compares the new SkBitmap compared to the SkBitmap from the last
-        call. Updates our hitbox with the draw command number if different.
-     */
-    void updateHitBox(SkBitmap* newBitmap, int layer);
-
-    /**
-        Compares point x,y in the new bitmap compared to the saved previous
-        one. Updates hitpoint with the draw command number if different.
-     */
-    void updateHitPoint(SkBitmap* newBitmap, int layer);
-
-    /**
-        Sets the target hitpoint we are attempting to find the layer of.
-     */
-    void setHitPoint(int x, int y) {
-        fX = x;
-        fY = y;
-        fLayer = 0;
-    }
-
-    /**
-        Returns a pointer to the start of the hitbox.
-     */
-    int* getHitBox() {
-        return fHitBox;
-    }
-
-    /**
-        Returns the layer numbr corresponding to the point (fX, fY) in this class.
-     */
-    int getPoint() {
-        return fLayer;
-    }
-
-    /**
-        Checks to see if a mouse click has been passed in.
-     */
-    bool pointIsSet() {
-        return !(fX == -1 && fY == -1);
-    }
-
-private:
-    SkBitmap fPrev;
-    int* fHitBox;
-    int fX;
-    int fY;
-    int fLayer;
-};
-
-
-#endif /* SKHITBOX_H_ */
index 5b18c5e..34ff403 100644 (file)
@@ -32,8 +32,6 @@
         '../debugger/SkObjectParser.cpp',
         '../debugger/QT/SkSettingsWidget.h',
         '../debugger/QT/SkSettingsWidget.cpp',
-        '../debugger/SkHitBox.h',
-        '../debugger/SkHitBox.cpp',
         '../debugger/QT/SkGLWidget.h',
         '../debugger/QT/SkGLWidget.cpp',
         '../debugger/QT/SkRasterWidget.h',