Optimization: SkDebugCanvas is capable of pausing and drawing incrementally instead of redrawing all commands.
Review URL: https://codereview.appspot.com/6458056 git-svn-id: http://skia.googlecode.com/svn/trunk@4891 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
6385314686
commit
830b8793bb
@ -25,8 +25,8 @@ SkCanvasWidget::SkCanvasWidget() : QWidget()
|
||||
|
||||
fIndex = 0;
|
||||
fPreviousPoint.set(0,0);
|
||||
fTransform.set(0,0);
|
||||
fScaleFactor = 1.0;
|
||||
fUserOffset.set(0,0);
|
||||
fUserScaleFactor = 1.0;
|
||||
|
||||
setWidgetVisibility(kGPU_WidgetType, true);
|
||||
this->setDisabled(true);
|
||||
@ -58,42 +58,37 @@ void SkCanvasWidget::loadPicture(QString filename) {
|
||||
fDebugCanvas = new SkDebugCanvas(picture->width(), picture->height());
|
||||
|
||||
picture->draw(fDebugCanvas);
|
||||
fIndex = fDebugCanvas->getSize();
|
||||
fIndex = fDebugCanvas->getSize() - 1;
|
||||
fRasterWidget.setDebugCanvas(fDebugCanvas);
|
||||
fGLWidget.setDebugCanvas(fDebugCanvas);
|
||||
|
||||
// TODO(chudy): Remove bounds from debug canvas storage.
|
||||
fDebugCanvas->setBounds(this->width(), this->height());
|
||||
}
|
||||
|
||||
void SkCanvasWidget::mouseMoveEvent(QMouseEvent* event) {
|
||||
SkIPoint eventPoint = SkIPoint::Make(event->globalX(), event->globalY());
|
||||
fTransform += eventPoint - fPreviousPoint;
|
||||
fUserOffset += eventPoint - fPreviousPoint;
|
||||
fPreviousPoint = eventPoint;
|
||||
updateWidgetTransform(kTranslate);
|
||||
fDebugCanvas->setUserOffset(fUserOffset);
|
||||
drawTo(fIndex);
|
||||
}
|
||||
|
||||
void SkCanvasWidget::mousePressEvent(QMouseEvent* event) {
|
||||
fPreviousPoint.set(event->globalX(), event->globalY());
|
||||
emit hitChanged(fDebugCanvas->getCommandAtPoint(event->x(), event->y(),
|
||||
fIndex, fTransform, fScaleFactor));
|
||||
fIndex));
|
||||
}
|
||||
|
||||
void SkCanvasWidget::mouseDoubleClickEvent(QMouseEvent* event) {
|
||||
fTransform.set(0,0);
|
||||
fScaleFactor = 1.0;
|
||||
emit scaleFactorChanged(fScaleFactor);
|
||||
// TODO(chudy): Change to signal / slot mechanism.
|
||||
resetWidgetTransform();
|
||||
drawTo(fIndex);
|
||||
}
|
||||
|
||||
void SkCanvasWidget::resetWidgetTransform() {
|
||||
fTransform.set(0,0);
|
||||
fScaleFactor = 1.0;
|
||||
updateWidgetTransform(kTranslate);
|
||||
updateWidgetTransform(kScale);
|
||||
fUserOffset.set(0,0);
|
||||
fUserScaleFactor = 1.0;
|
||||
fDebugCanvas->setUserOffset(fUserOffset);
|
||||
fDebugCanvas->setUserScale(fUserScaleFactor);
|
||||
emit scaleFactorChanged(fUserScaleFactor);
|
||||
drawTo(fIndex);
|
||||
}
|
||||
|
||||
void SkCanvasWidget::setWidgetVisibility(WidgetType type, bool isHidden) {
|
||||
@ -104,27 +99,17 @@ void SkCanvasWidget::setWidgetVisibility(WidgetType type, bool isHidden) {
|
||||
}
|
||||
}
|
||||
|
||||
void SkCanvasWidget::updateWidgetTransform(TransformType type) {
|
||||
if (type == kTranslate) {
|
||||
fRasterWidget.setTranslate(fTransform);
|
||||
fGLWidget.setTranslate(fTransform);
|
||||
} else if (type == kScale) {
|
||||
fRasterWidget.setScale(fScaleFactor);
|
||||
fGLWidget.setScale(fScaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
void SkCanvasWidget::zoom(float zoomIncrement) {
|
||||
fScaleFactor += zoomIncrement;
|
||||
fUserScaleFactor += zoomIncrement;
|
||||
|
||||
/* The range of the fScaleFactor crosses over the range -1,0,1 frequently.
|
||||
/* The range of the fUserScaleFactor crosses over the range -1,0,1 frequently.
|
||||
* Based on the code below, -1 and 1 both scale the image to it's original
|
||||
* size we do the following to never have a registered wheel scroll
|
||||
* not effect the fScaleFactor. */
|
||||
if (fScaleFactor == 0) {
|
||||
fScaleFactor = 2 * zoomIncrement;
|
||||
* not effect the fUserScaleFactor. */
|
||||
if (fUserScaleFactor == 0) {
|
||||
fUserScaleFactor = 2 * zoomIncrement;
|
||||
}
|
||||
emit scaleFactorChanged(fScaleFactor);
|
||||
updateWidgetTransform(kScale);
|
||||
emit scaleFactorChanged(fUserScaleFactor);
|
||||
fDebugCanvas->setUserScale(fUserScaleFactor);
|
||||
drawTo(fIndex);
|
||||
}
|
||||
|
@ -118,19 +118,12 @@ private:
|
||||
SkGLWidget fGLWidget;
|
||||
SkDebugCanvas* fDebugCanvas;
|
||||
SkIPoint fPreviousPoint;
|
||||
SkIPoint fTransform;
|
||||
float fScaleFactor;
|
||||
SkIPoint fUserOffset;
|
||||
float fUserScaleFactor;
|
||||
int fIndex;
|
||||
|
||||
enum TransformType {
|
||||
kTranslate = 1 << 0,
|
||||
kScale = 1 << 1,
|
||||
};
|
||||
|
||||
void resetWidgetTransform();
|
||||
|
||||
void updateWidgetTransform(TransformType type);
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
|
@ -18,12 +18,14 @@ SkGLWidget::SkGLWidget() : QGLWidget() {
|
||||
fCurIntf = NULL;
|
||||
fCurContext = NULL;
|
||||
fGpuDevice = NULL;
|
||||
fCanvas = NULL;
|
||||
}
|
||||
|
||||
SkGLWidget::~SkGLWidget() {
|
||||
SkSafeUnref(fCurIntf);
|
||||
SkSafeUnref(fCurContext);
|
||||
SkSafeUnref(fGpuDevice);
|
||||
SkSafeUnref(fCanvas);
|
||||
}
|
||||
|
||||
void SkGLWidget::initializeGL() {
|
||||
@ -31,6 +33,7 @@ void SkGLWidget::initializeGL() {
|
||||
fCurContext = GrContext::Create(kOpenGL_Shaders_GrEngine, (GrPlatform3DContext) fCurIntf);
|
||||
GrRenderTarget* curRenderTarget = fCurContext->createPlatformRenderTarget(getDesc(this->width(), this->height()));
|
||||
fGpuDevice = new SkGpuDevice(fCurContext, curRenderTarget);
|
||||
fCanvas = new SkCanvas(fGpuDevice);
|
||||
curRenderTarget->unref();
|
||||
|
||||
glClearColor(1, 1, 1, 0);
|
||||
@ -41,21 +44,17 @@ void SkGLWidget::initializeGL() {
|
||||
void SkGLWidget::resizeGL(int w, int h) {
|
||||
GrRenderTarget* curRenderTarget = fCurContext->createPlatformRenderTarget(getDesc(w,h));
|
||||
SkSafeUnref(fGpuDevice);
|
||||
SkSafeUnref(fCanvas);
|
||||
fGpuDevice = new SkGpuDevice(fCurContext, curRenderTarget);
|
||||
fCanvas = new SkCanvas(fGpuDevice);
|
||||
drawTo(fIndex);
|
||||
}
|
||||
|
||||
void SkGLWidget::paintGL() {
|
||||
glClearColor(1, 1, 1, 0);
|
||||
SkCanvas canvas(fGpuDevice);
|
||||
canvas.translate(fTransform.fX, fTransform.fY);
|
||||
if(fScaleFactor < 0) {
|
||||
canvas.scale((1.0 / -fScaleFactor),(1.0 / -fScaleFactor));
|
||||
} else if (fScaleFactor > 0) {
|
||||
canvas.scale(fScaleFactor, fScaleFactor);
|
||||
}
|
||||
fDebugCanvas->drawTo(&canvas, fIndex);
|
||||
canvas.flush();
|
||||
fDebugCanvas->drawTo(fCanvas, fIndex);
|
||||
// TODO(chudy): Implement an optional flush button in Gui.
|
||||
fCanvas->flush();
|
||||
}
|
||||
|
||||
GrPlatformRenderTargetDesc SkGLWidget::getDesc(int w, int h) {
|
||||
|
@ -9,44 +9,40 @@
|
||||
|
||||
#include "SkRasterWidget.h"
|
||||
|
||||
SkRasterWidget::SkRasterWidget(QWidget* parent) : QWidget(parent) {
|
||||
SkRasterWidget::SkRasterWidget() : QWidget() {
|
||||
fBitmap.setConfig(SkBitmap::kARGB_8888_Config, 800, 800);
|
||||
fBitmap.allocPixels();
|
||||
fBitmap.eraseColor(0);
|
||||
fTransform.set(0,0);
|
||||
fScaleFactor = 1.0;
|
||||
fIndex = 0;
|
||||
fDevice = NULL;
|
||||
fDevice = new SkDevice(fBitmap);
|
||||
fDebugCanvas = NULL;
|
||||
fCanvas = new SkCanvas(fDevice);
|
||||
this->setStyleSheet("QWidget {background-color: white; border: 1px solid #cccccc;}");
|
||||
}
|
||||
|
||||
SkRasterWidget::~SkRasterWidget() {
|
||||
delete fDevice;
|
||||
SkSafeUnref(fCanvas);
|
||||
SkSafeUnref(fDevice);
|
||||
}
|
||||
|
||||
void SkRasterWidget::resizeEvent(QResizeEvent* event) {
|
||||
fBitmap.setConfig(SkBitmap::kARGB_8888_Config, event->size().width(), event->size().height());
|
||||
fBitmap.allocPixels();
|
||||
delete fDevice;
|
||||
SkSafeUnref(fCanvas);
|
||||
SkSafeUnref(fDevice);
|
||||
fDevice = new SkDevice(fBitmap);
|
||||
fCanvas = new SkCanvas(fDevice);
|
||||
this->update();
|
||||
}
|
||||
|
||||
void SkRasterWidget::paintEvent(QPaintEvent* event) {
|
||||
if (fDebugCanvas) {
|
||||
fBitmap.eraseColor(0);
|
||||
SkCanvas canvas(fDevice);
|
||||
canvas.translate(fTransform.fX, fTransform.fY);
|
||||
if (fScaleFactor < 0) {
|
||||
canvas.scale((1.0 / -fScaleFactor), (1.0 / -fScaleFactor));
|
||||
} else if (fScaleFactor > 0) {
|
||||
canvas.scale(fScaleFactor, fScaleFactor);
|
||||
}
|
||||
|
||||
fMatrix = canvas.getTotalMatrix();
|
||||
fClip = canvas.getTotalClip().getBounds();
|
||||
fDebugCanvas->drawTo(&canvas, fIndex);
|
||||
fDebugCanvas->drawTo(fCanvas, fIndex);
|
||||
// TODO(chudy): Refactor into SkDebugCanvas.
|
||||
fMatrix = fCanvas->getTotalMatrix();
|
||||
fClip = fCanvas->getTotalClip().getBounds();
|
||||
|
||||
QPainter painter(this);
|
||||
QStyleOption opt;
|
||||
|
@ -20,7 +20,7 @@
|
||||
class SkRasterWidget : public QWidget {
|
||||
|
||||
public:
|
||||
SkRasterWidget(QWidget* parent = NULL);
|
||||
SkRasterWidget();
|
||||
|
||||
~SkRasterWidget();
|
||||
|
||||
@ -67,6 +67,7 @@ protected:
|
||||
private:
|
||||
SkBitmap fBitmap;
|
||||
SkDebugCanvas* fDebugCanvas;
|
||||
SkCanvas* fCanvas;
|
||||
SkDevice* fDevice;
|
||||
|
||||
SkMatrix fMatrix;
|
||||
|
@ -18,6 +18,9 @@ SkDebugCanvas::SkDebugCanvas(int width, int height) {
|
||||
fBm.setConfig(SkBitmap::kNo_Config, fWidth, fHeight);
|
||||
this->setBitmapDevice(fBm);
|
||||
fFilter = false;
|
||||
fIndex = 0;
|
||||
fUserOffset.set(0,0);
|
||||
fUserScale = 1.0;
|
||||
}
|
||||
|
||||
SkDebugCanvas::~SkDebugCanvas() {}
|
||||
@ -34,21 +37,26 @@ void SkDebugCanvas::draw(SkCanvas* canvas) {
|
||||
}
|
||||
}
|
||||
}
|
||||
fIndex = commandVector.size() - 1;
|
||||
}
|
||||
|
||||
int SkDebugCanvas::getCommandAtPoint(int x, int y, int index,
|
||||
SkIPoint transform, float scale) {
|
||||
void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) {
|
||||
canvas->translate(fUserOffset.fX, fUserOffset.fY);
|
||||
if (fUserScale < 0) {
|
||||
canvas->scale((1.0 / -fUserScale), (1.0 / -fUserScale));
|
||||
} else if (fUserScale > 0) {
|
||||
canvas->scale(fUserScale, fUserScale);
|
||||
}
|
||||
}
|
||||
|
||||
int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) {
|
||||
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);
|
||||
}
|
||||
canvas.translate(-x, -y);
|
||||
applyUserTransform(&canvas);
|
||||
|
||||
int layer = 0;
|
||||
SkColor prev = bitmap.getColor(0,0);
|
||||
@ -68,7 +76,21 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
|
||||
int counter = 0;
|
||||
SkASSERT(!commandVector.empty());
|
||||
SkASSERT(index < (int)commandVector.size());
|
||||
for (int i = 0; i <= index; i++) {
|
||||
int i;
|
||||
|
||||
// This only works assuming the canvas and device are the same ones that
|
||||
// were previously drawn into because they need to preserve all saves
|
||||
// and restores.
|
||||
if (fIndex < index) {
|
||||
i = fIndex + 1;
|
||||
} else {
|
||||
i = 0;
|
||||
canvas->clear(0);
|
||||
canvas->resetMatrix();
|
||||
applyUserTransform(canvas);
|
||||
}
|
||||
|
||||
for (; i <= index; i++) {
|
||||
if (i == index && fFilter) {
|
||||
SkPaint p;
|
||||
p.setColor(0xAAFFFFFF);
|
||||
@ -87,6 +109,8 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
|
||||
commandVector[i]->execute(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
fIndex = index;
|
||||
}
|
||||
|
||||
SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
|
||||
|
@ -47,8 +47,7 @@ public:
|
||||
/**
|
||||
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);
|
||||
int getCommandAtPoint(int x, int y, int index);
|
||||
|
||||
/**
|
||||
Returns the draw command at the given index.
|
||||
@ -96,6 +95,14 @@ public:
|
||||
fHeight = height;
|
||||
}
|
||||
|
||||
void setUserOffset(SkIPoint offset) {
|
||||
fUserOffset = offset;
|
||||
}
|
||||
|
||||
void setUserScale(float scale) {
|
||||
fUserScale = scale;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Inherited from SkCanvas
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -181,12 +188,21 @@ private:
|
||||
int fWidth;
|
||||
SkBitmap fBm;
|
||||
bool fFilter;
|
||||
int fIndex;
|
||||
SkIPoint fUserOffset;
|
||||
float fUserScale;
|
||||
|
||||
/**
|
||||
Adds the command to the classes vector of commands.
|
||||
@param command The draw command for execution
|
||||
*/
|
||||
void addDrawCommand(SkDrawCommand* command);
|
||||
|
||||
/**
|
||||
Applies any panning and zooming the user has specified before
|
||||
drawing anything else into the canvas.
|
||||
*/
|
||||
void applyUserTransform(SkCanvas* canvas);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user