diff options
author | chudy@google.com <chudy@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-07-31 19:55:32 +0000 |
---|---|---|
committer | chudy@google.com <chudy@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-07-31 19:55:32 +0000 |
commit | 0b5bbb0f82e022c8acfbcb6312f0ed18e1ab90ce (patch) | |
tree | 1cffbd2be2432d18ccecbe0b9fec915cbcb486ca /debugger | |
parent | 622a17091b69df8d54d318c88f34851677a6d9c2 (diff) |
Optimized hit testing feature, refactored into seperate function from canvas draw calls
Review URL: https://codereview.appspot.com/6443068
git-svn-id: http://skia.googlecode.com/svn/trunk@4867 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'debugger')
-rw-r--r-- | debugger/QT/SkCanvasWidget.cpp | 13 | ||||
-rw-r--r-- | debugger/QT/SkGLWidget.cpp | 3 | ||||
-rw-r--r-- | debugger/QT/SkGLWidget.h | 2 | ||||
-rw-r--r-- | debugger/QT/SkRasterWidget.cpp | 10 | ||||
-rw-r--r-- | debugger/QT/SkRasterWidget.h | 2 | ||||
-rw-r--r-- | debugger/SkDebugCanvas.cpp | 85 | ||||
-rw-r--r-- | debugger/SkDebugCanvas.h | 30 | ||||
-rw-r--r-- | debugger/SkDrawCommand.h | 9 | ||||
-rw-r--r-- | debugger/SkHitBox.cpp | 66 | ||||
-rw-r--r-- | debugger/SkHitBox.h | 81 |
10 files changed, 73 insertions, 228 deletions
diff --git a/debugger/QT/SkCanvasWidget.cpp b/debugger/QT/SkCanvasWidget.cpp index e4716af439..c560aec3b5 100644 --- a/debugger/QT/SkCanvasWidget.cpp +++ b/debugger/QT/SkCanvasWidget.cpp @@ -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) { diff --git a/debugger/QT/SkGLWidget.cpp b/debugger/QT/SkGLWidget.cpp index 74ed48eb6e..e3c4161cb4 100644 --- a/debugger/QT/SkGLWidget.cpp +++ b/debugger/QT/SkGLWidget.cpp @@ -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(); } diff --git a/debugger/QT/SkGLWidget.h b/debugger/QT/SkGLWidget.h index 5295f4cd18..76257be3c9 100644 --- a/debugger/QT/SkGLWidget.h +++ b/debugger/QT/SkGLWidget.h @@ -29,7 +29,7 @@ public: void setDebugCanvas(SkDebugCanvas* debugCanvas) { fDebugCanvas = debugCanvas; - fIndex = debugCanvas->getSize(); + fIndex = debugCanvas->getSize() - 1; this->updateGL(); } diff --git a/debugger/QT/SkRasterWidget.cpp b/debugger/QT/SkRasterWidget.cpp index db89de70fe..2cf1f348d0 100644 --- a/debugger/QT/SkRasterWidget.cpp +++ b/debugger/QT/SkRasterWidget.cpp @@ -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; diff --git a/debugger/QT/SkRasterWidget.h b/debugger/QT/SkRasterWidget.h index af65792e77..16928007ad 100644 --- a/debugger/QT/SkRasterWidget.h +++ b/debugger/QT/SkRasterWidget.h @@ -31,7 +31,7 @@ public: void setDebugCanvas(SkDebugCanvas* debugCanvas) { fDebugCanvas = debugCanvas; - fIndex = debugCanvas->getSize(); + fIndex = debugCanvas->getSize() - 1; this->update(); } diff --git a/debugger/SkDebugCanvas.cpp b/debugger/SkDebugCanvas.cpp index 12d7127ff8..9819858e3f 100644 --- a/debugger/SkDebugCanvas.cpp +++ b/debugger/SkDebugCanvas.cpp @@ -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); } diff --git a/debugger/SkDebugCanvas.h b/debugger/SkDebugCanvas.h index fa2d7570be..c13ea10947 100644 --- a/debugger/SkDebugCanvas.h +++ b/debugger/SkDebugCanvas.h @@ -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; /** diff --git a/debugger/SkDrawCommand.h b/debugger/SkDrawCommand.h index 45d9dd6260..f09dae9d07 100644 --- a/debugger/SkDrawCommand.h +++ b/debugger/SkDrawCommand.h @@ -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 index a65fcc416d..0000000000 --- a/debugger/SkHitBox.cpp +++ /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 index 19a65fd5dd..0000000000 --- a/debugger/SkHitBox.h +++ /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_ */ |