SkHitBox added.
SkHitBox is a class that determines which draw command is associated with the pixel located at x,y. By calculating a single point instead of the entire bitmap at once there is no visible performance slowdown. Review URL: https://codereview.appspot.com/6350098 git-svn-id: http://skia.googlecode.com/svn/trunk@4565 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
e565de4fad
commit
e606d6e210
@ -11,7 +11,6 @@
|
||||
#include "SkStream.h"
|
||||
#include "SkCanvasWidget.h"
|
||||
#include "SkColor.h"
|
||||
#include <iostream>
|
||||
|
||||
SkCanvasWidget::SkCanvasWidget(QWidget *parent) :
|
||||
QWidget(parent) {
|
||||
@ -56,7 +55,7 @@ void SkCanvasWidget::resizeEvent(QResizeEvent* event) {
|
||||
fDevice = new SkDevice(fBitmap);
|
||||
fCanvas = new SkCanvas(fDevice);
|
||||
fDebugCanvas->setBounds(event->size().width(), event->size().height());
|
||||
fDebugCanvas->drawTo(fCanvas, fIndex);
|
||||
fDebugCanvas->drawTo(fCanvas, fIndex+1, &fBitmap);
|
||||
this->update();
|
||||
}
|
||||
|
||||
@ -72,7 +71,7 @@ void SkCanvasWidget::drawTo(int fIndex) {
|
||||
}
|
||||
|
||||
emit commandChanged(fIndex);
|
||||
fDebugCanvas->drawTo(fCanvas, fIndex+1);
|
||||
fDebugCanvas->drawTo(fCanvas, fIndex+1, &fBitmap);
|
||||
this->update();
|
||||
this->fIndex = fIndex;
|
||||
}
|
||||
@ -128,6 +127,11 @@ void SkCanvasWidget::mouseMoveEvent(QMouseEvent* event) {
|
||||
|
||||
void SkCanvasWidget::mousePressEvent(QMouseEvent* event) {
|
||||
fPreviousPoint.set(event->globalX(), event->globalY());
|
||||
fDebugCanvas->getBoxClass()->setHitPoint(event->x(), event->y());
|
||||
fDebugCanvas->isCalculatingHits(true);
|
||||
drawTo(fIndex);
|
||||
emit hitChanged(fDebugCanvas->getHitBoxPoint());
|
||||
fDebugCanvas->isCalculatingHits(false);
|
||||
}
|
||||
|
||||
void SkCanvasWidget::mouseDoubleClickEvent(QMouseEvent* event) {
|
||||
|
@ -132,6 +132,7 @@ public:
|
||||
signals:
|
||||
void scaleFactorChanged(float newScaleFactor);
|
||||
void commandChanged(int newCommand);
|
||||
void hitChanged(int hit);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -71,10 +71,12 @@ SkDebuggerGUI::SkDebuggerGUI(QWidget *parent) :
|
||||
SLOT(actionCommandFilter()));
|
||||
connect(&fCanvasWidget, SIGNAL(scaleFactorChanged(float)), this,
|
||||
SLOT(actionScale(float)));
|
||||
connect(fSettingsWidget.getCommandCheckBox(), SIGNAL(stateChanged(int)),
|
||||
connect(fSettingsWidget.getCommandCheckBox(), SIGNAL(toggled(bool)),
|
||||
this, SLOT(pauseDrawing(bool)));
|
||||
connect(&fCanvasWidget, SIGNAL(commandChanged(int)), &fSettingsWidget,
|
||||
SLOT(updateCommand(int)));
|
||||
connect(&fCanvasWidget, SIGNAL(hitChanged(int)), &fSettingsWidget,
|
||||
SLOT(updateHit(int)));
|
||||
}
|
||||
|
||||
SkDebuggerGUI::~SkDebuggerGUI() {
|
||||
@ -478,6 +480,7 @@ void SkDebuggerGUI::loadPicture(QString fileName) {
|
||||
fSettingsWidget.getVisibilityButton()->isChecked());
|
||||
setupListWidget(cv);
|
||||
setupComboBox(cv);
|
||||
fSettingsWidget.setDisabled(false);
|
||||
}
|
||||
|
||||
void SkDebuggerGUI::setupListWidget(std::vector<std::string>* cv) {
|
||||
|
@ -19,6 +19,7 @@ SkSettingsWidget::SkSettingsWidget(QWidget *parent) : QWidget(parent)
|
||||
, fVisibleOff(&fVisibleFrame)
|
||||
, fCommandLayout(&fCommandFrame)
|
||||
, fCurrentCommandBox(&fCommandFrame)
|
||||
, fCommandHitBox(&fCommandFrame)
|
||||
, fCommandCheckBox(&fCommandFrame)
|
||||
, fZoomBox(&fZoomFrame)
|
||||
, fZoomLayout(&fZoomFrame)
|
||||
@ -65,10 +66,24 @@ SkSettingsWidget::SkSettingsWidget(QWidget *parent) : QWidget(parent)
|
||||
fCurrentCommandLayout.addWidget(&fCurrentCommandLabel);
|
||||
fCurrentCommandLayout.addWidget(&fCurrentCommandBox);
|
||||
|
||||
fCommandHitLabel.setText("Command HitBox: ");
|
||||
fCommandHitLabel.setMinimumWidth(178);
|
||||
fCommandHitLabel.setMaximumWidth(178);
|
||||
fCommandHitBox.setText("0");
|
||||
fCommandHitBox.setMinimumSize(QSize(50,25));
|
||||
fCommandHitBox.setMaximumSize(QSize(50,25));
|
||||
fCommandHitBox.setAlignment(Qt::AlignRight);
|
||||
fCommandHitLayout.setSpacing(0);
|
||||
fCommandHitLayout.setContentsMargins(0,0,0,0);
|
||||
fCommandHitLayout.setAlignment(Qt::AlignLeft);
|
||||
fCommandHitLayout.addWidget(&fCommandHitLabel);
|
||||
fCommandHitLayout.addWidget(&fCommandHitBox);
|
||||
|
||||
fCommandCheckBox.setText("Pause");
|
||||
fCommandLayout.setSpacing(6);
|
||||
fCommandLayout.setContentsMargins(11,11,11,11);
|
||||
fCommandLayout.addLayout(&fCurrentCommandLayout);
|
||||
fCommandLayout.addLayout(&fCommandHitLayout);
|
||||
fCommandLayout.addWidget(&fCommandCheckBox);
|
||||
|
||||
// Zoom Info
|
||||
@ -93,7 +108,7 @@ SkSettingsWidget::SkSettingsWidget(QWidget *parent) : QWidget(parent)
|
||||
fVerticalLayout.addWidget(&fCommandFrame);
|
||||
fVerticalLayout.addWidget(&fZoomFrame);
|
||||
|
||||
//this->setDisabled(true);
|
||||
this->setDisabled(true);
|
||||
}
|
||||
|
||||
SkSettingsWidget::~SkSettingsWidget() {}
|
||||
@ -103,6 +118,10 @@ void SkSettingsWidget::updateCommand(int newCommand) {
|
||||
fCurrentCommandBox.setText(QString::number(newCommand));
|
||||
}
|
||||
|
||||
void SkSettingsWidget::updateHit(int newHit) {
|
||||
fCommandHitBox.setText(QString::number(newHit));
|
||||
}
|
||||
|
||||
QCheckBox* SkSettingsWidget::getCommandCheckBox() {
|
||||
return &fCommandCheckBox;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void updateCommand(int newCommand);
|
||||
void updateHit(int newHit);
|
||||
|
||||
signals:
|
||||
void scrollingPreferences(bool isStickyActivate);
|
||||
@ -64,10 +65,14 @@ private:
|
||||
QFrame fCommandFrame;
|
||||
QVBoxLayout fCommandLayout;
|
||||
|
||||
QLineEdit fCurrentCommandBox;
|
||||
QLabel fCurrentCommandLabel;
|
||||
QLineEdit fCurrentCommandBox;
|
||||
QHBoxLayout fCurrentCommandLayout;
|
||||
|
||||
QLabel fCommandHitLabel;
|
||||
QLineEdit fCommandHitBox;
|
||||
QHBoxLayout fCommandHitLayout;
|
||||
|
||||
QCheckBox fCommandCheckBox;
|
||||
|
||||
QLabel fZoomSetting;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
** Meta object code from reading C++ file 'SkCanvasWidget.h'
|
||||
**
|
||||
** Created: Mon Jul 9 13:45:07 2012
|
||||
** Created: Wed Jul 11 15:15:07 2012
|
||||
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost!
|
||||
@ -23,16 +23,17 @@ static const uint qt_meta_data_SkCanvasWidget[] = {
|
||||
4, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
2, 14, // methods
|
||||
3, 14, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
0, // flags
|
||||
2, // signalCount
|
||||
3, // signalCount
|
||||
|
||||
// signals: signature, parameters, type, tag, flags
|
||||
31, 16, 15, 15, 0x05,
|
||||
68, 57, 15, 15, 0x05,
|
||||
92, 88, 15, 15, 0x05,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
@ -40,7 +41,7 @@ static const uint qt_meta_data_SkCanvasWidget[] = {
|
||||
static const char qt_meta_stringdata_SkCanvasWidget[] = {
|
||||
"SkCanvasWidget\0\0newScaleFactor\0"
|
||||
"scaleFactorChanged(float)\0newCommand\0"
|
||||
"commandChanged(int)\0"
|
||||
"commandChanged(int)\0hit\0hitChanged(int)\0"
|
||||
};
|
||||
|
||||
const QMetaObject SkCanvasWidget::staticMetaObject = {
|
||||
@ -74,9 +75,10 @@ int SkCanvasWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
switch (_id) {
|
||||
case 0: scaleFactorChanged((*reinterpret_cast< float(*)>(_a[1]))); break;
|
||||
case 1: commandChanged((*reinterpret_cast< int(*)>(_a[1]))); break;
|
||||
case 2: hitChanged((*reinterpret_cast< int(*)>(_a[1]))); break;
|
||||
default: ;
|
||||
}
|
||||
_id -= 2;
|
||||
_id -= 3;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
@ -94,4 +96,11 @@ void SkCanvasWidget::commandChanged(int _t1)
|
||||
void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
|
||||
QMetaObject::activate(this, &staticMetaObject, 1, _a);
|
||||
}
|
||||
|
||||
// SIGNAL 2
|
||||
void SkCanvasWidget::hitChanged(int _t1)
|
||||
{
|
||||
void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
|
||||
QMetaObject::activate(this, &staticMetaObject, 2, _a);
|
||||
}
|
||||
QT_END_MOC_NAMESPACE
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
** Meta object code from reading C++ file 'SkSettingsWidget.h'
|
||||
**
|
||||
** Created: Mon Jul 9 13:45:07 2012
|
||||
** Created: Wed Jul 11 15:20:23 2012
|
||||
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost!
|
||||
@ -23,7 +23,7 @@ static const uint qt_meta_data_SkSettingsWidget[] = {
|
||||
4, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
4, 14, // methods
|
||||
5, 14, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
@ -37,6 +37,7 @@ static const uint qt_meta_data_SkSettingsWidget[] = {
|
||||
|
||||
// slots: signature, parameters, type, tag, flags
|
||||
138, 127, 17, 17, 0x08,
|
||||
164, 157, 17, 17, 0x08,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
@ -46,7 +47,7 @@ static const char qt_meta_stringdata_SkSettingsWidget[] = {
|
||||
"scrollingPreferences(bool)\0isSingleCommand\0"
|
||||
"showStyle(bool)\0isEnabled\0"
|
||||
"visibilityFilter(bool)\0newCommand\0"
|
||||
"updateCommand(int)\0"
|
||||
"updateCommand(int)\0newHit\0updateHit(int)\0"
|
||||
};
|
||||
|
||||
const QMetaObject SkSettingsWidget::staticMetaObject = {
|
||||
@ -82,9 +83,10 @@ int SkSettingsWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
case 1: showStyle((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
case 2: visibilityFilter((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
case 3: updateCommand((*reinterpret_cast< int(*)>(_a[1]))); break;
|
||||
case 4: updateHit((*reinterpret_cast< int(*)>(_a[1]))); break;
|
||||
default: ;
|
||||
}
|
||||
_id -= 4;
|
||||
_id -= 5;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
|
@ -34,12 +34,11 @@ void SkDebugCanvas::draw(SkCanvas* canvas) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
|
||||
void SkDebugCanvas::drawTo(SkCanvas* canvas, int index, SkBitmap* bitmap) {
|
||||
int counter = 0;
|
||||
if(!commandVector.empty()) {
|
||||
for(it = commandVector.begin(); it != commandVector.end(); ++it) {
|
||||
if (counter != (index-1)) {
|
||||
if (counter != (index-1)) {
|
||||
if ((*it)->getVisibility()) {
|
||||
(*it)->execute(canvas);
|
||||
}
|
||||
@ -56,11 +55,13 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
|
||||
canvas->drawRectCoords(SkIntToScalar(0),SkIntToScalar(0),SkIntToScalar(fWidth),SkIntToScalar(fHeight), *p);
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
if ((*it)->getVisibility()) {
|
||||
(*it)->execute(canvas);
|
||||
}
|
||||
}
|
||||
if (fCalculateHits == true) {
|
||||
fHitBox.updateHitPoint(bitmap, counter);
|
||||
}
|
||||
|
||||
/* TODO(chudy): Implement a bitmap wide function that will take
|
||||
* ~50 out of each R,G,B. This will make everything but the last
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkDrawCommand.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkHitBox.h"
|
||||
#include <vector>
|
||||
|
||||
class SkDebugCanvas : public SkCanvas {
|
||||
@ -45,7 +46,7 @@ public:
|
||||
@param canvas The canvas being drawn to
|
||||
@param index The index of the final command being executed
|
||||
*/
|
||||
void drawTo(SkCanvas* canvas, int index);
|
||||
void drawTo(SkCanvas* canvas, int index, SkBitmap* bitmap);
|
||||
|
||||
/**
|
||||
Returns the draw command at the given index.
|
||||
@ -69,6 +70,21 @@ 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.
|
||||
*/
|
||||
@ -76,6 +92,9 @@ public:
|
||||
return commandVector.size();
|
||||
}
|
||||
|
||||
void isCalculatingHits(bool isEnabled) {
|
||||
fCalculateHits = isEnabled;
|
||||
}
|
||||
/**
|
||||
Toggles the execution of the draw command at index i.
|
||||
*/
|
||||
@ -176,6 +195,8 @@ private:
|
||||
int fHeight;
|
||||
int fWidth;
|
||||
SkBitmap fBm;
|
||||
SkHitBox fHitBox;
|
||||
bool fCalculateHits;
|
||||
|
||||
/**
|
||||
Adds the command to the classes vector of commands.
|
||||
|
66
debugger/SkHitBox.cpp
Normal file
66
debugger/SkHitBox.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
81
debugger/SkHitBox.h
Normal file
81
debugger/SkHitBox.h
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
/*
|
||||
* 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_ */
|
@ -30,6 +30,8 @@
|
||||
'../debugger/SkObjectParser.cpp',
|
||||
'../debugger/QT/SkSettingsWidget.h',
|
||||
'../debugger/QT/SkSettingsWidget.cpp',
|
||||
'../debugger/SkHitBox.h',
|
||||
'../debugger/SkHitBox.cpp',
|
||||
|
||||
# To update this file edit SkIcons.qrc and rerun rcc to generate cpp
|
||||
'../debugger/QT/qrc_SkIcons.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user