GL Widget Alpha

Review URL: https://codereview.appspot.com/6422060

git-svn-id: http://skia.googlecode.com/svn/trunk@4789 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/debugger/QT/SkCanvasWidget.cpp b/debugger/QT/SkCanvasWidget.cpp
index ca67914..8384fb1 100644
--- a/debugger/QT/SkCanvasWidget.cpp
+++ b/debugger/QT/SkCanvasWidget.cpp
@@ -7,122 +7,64 @@
  */
 
 
-#include "SkPicture.h"
-#include "SkStream.h"
 #include "SkCanvasWidget.h"
-#include "SkColor.h"
 
-SkCanvasWidget::SkCanvasWidget(QWidget *parent) :
-    QWidget(parent) {
+SkCanvasWidget::SkCanvasWidget(QWidget* parent) : QWidget(parent)
+    , fHorizontalLayout(this)
+    , fRasterWidget(this)
+    , fGLWidget(this)
+{
+    fHorizontalLayout.setSpacing(6);
+    fHorizontalLayout.setContentsMargins(0,0,0,0);
+    fRasterWidget.setSizePolicy(QSizePolicy::Expanding,
+            QSizePolicy::Expanding);
+    fGLWidget.setSizePolicy(QSizePolicy::Expanding,
+            QSizePolicy::Expanding);
 
-    /* TODO(chudy): The 800x800 is a default number. Change it to be
-     * set dynamically. Also need to pass size into debugCanvas for current
-     * command filter. */
-    fBitmap.setConfig(SkBitmap::kARGB_8888_Config, 800, 800);
-    fBitmap.allocPixels();
-    fBitmap.eraseColor(0);
-
-    /* TODO(chudy): Add fCanvas, fDevice to the stack. The bitmap being
-     * cleared does get rid of fDevices link to it. See if there's someway around
-     * it so that we don't have to delete both canvas and device to clear out
-     * the bitmap. */
-    fDevice = new SkDevice(fBitmap);
-    fCanvas = new SkCanvas(fDevice);
+    fHorizontalLayout.addWidget(&fRasterWidget);
+    fHorizontalLayout.addWidget(&fGLWidget);
     fDebugCanvas = new SkDebugCanvas();
 
-    fScaleFactor = 1.0;
     fIndex = 0;
     fPreviousPoint.set(0,0);
     fTransform.set(0,0);
+    fScaleFactor = 1.0;
 
-    this->setStyleSheet("QWidget {background-color: white; border: 1px solid #cccccc;}");
+    setWidgetVisibility(kGPU_WidgetType, true);
 }
 
-SkCanvasWidget::~SkCanvasWidget() {
-    delete fCanvas;
-    delete fDevice;
-    delete fDebugCanvas;
-}
-
-void SkCanvasWidget::resizeEvent(QResizeEvent* event) {
-    fBitmap.setConfig(SkBitmap::kARGB_8888_Config, event->size().width(), event->size().height());
-    fBitmap.allocPixels();
-    fBitmap.eraseColor(0);
-
-    delete fCanvas;
-    delete fDevice;
-
-    fDevice = new SkDevice(fBitmap);
-    fCanvas = new SkCanvas(fDevice);
-    fDebugCanvas->setBounds(event->size().width(), event->size().height());
-    fDebugCanvas->drawTo(fCanvas, fIndex+1, &fBitmap);
-    this->update();
-}
-
-void SkCanvasWidget::drawTo(int fIndex) {
-    delete fCanvas;
-    fCanvas = new SkCanvas(fDevice);
-    fBitmap.eraseColor(0);
-    fCanvas->translate(fTransform.fX, fTransform.fY);
-    if(fScaleFactor < 0) {
-        fCanvas->scale((1.0 / -fScaleFactor),(1.0 / -fScaleFactor));
-    } else if (fScaleFactor > 0) {
-        fCanvas->scale(fScaleFactor, fScaleFactor);
+void SkCanvasWidget::drawTo(int index) {
+    fIndex = index;
+    if (!fRasterWidget.isHidden()) {
+        fRasterWidget.drawTo(index);
     }
-
+    if (!fGLWidget.isHidden()) {
+        fGLWidget.drawTo(index);
+    }
     emit commandChanged(fIndex);
-    fDebugCanvas->drawTo(fCanvas, fIndex+1, &fBitmap);
-    this->update();
-    this->fIndex = fIndex;
 }
 
 void SkCanvasWidget::loadPicture(QString filename) {
-    SkStream *stream = new SkFILEStream(filename.toAscii());
-    SkPicture *picture = new SkPicture(stream);
+    SkStream* stream = new SkFILEStream(filename.toAscii());
+    SkPicture* picture = new SkPicture(stream);
 
+    /* TODO(chudy): Implement function that doesn't require new
+     * instantiation of debug canvas. */
     delete fDebugCanvas;
     fDebugCanvas = new SkDebugCanvas();
     fDebugCanvas->setBounds(this->width(), this->height());
-
     picture->draw(fDebugCanvas);
-    fDebugCanvas->draw(fCanvas);
-
     fIndex = fDebugCanvas->getSize();
-
-    SkColor color = fBitmap.getColor(fBitmap.width()-1,fBitmap.height()-1);
-
-    int r = SkColorGetR(color);
-    int g = SkColorGetG(color);
-    int b = SkColorGetB(color);
-
-    /* NOTE(chudy): This was a test to determine if the canvas size is accurately
-     * saved in the bounds of the recorded picture. It is not. Everyone of the
-     * sample GM images is 1000x1000. Even the one that claims it is
-     * 2048x2048.
-    std::cout << "Width: " << picture->width();
-    std::cout << " Height: " <<  picture->height() << std::endl; */
-
-    /* Updated style sheet without a background specified. If not removed
-     * QPainter paints the specified background color on top of our canvas. */
-
-    QString style("QWidget {border: 1px solid #cccccc; background-color: #");
-    style.append(QString::number(r, 16));
-    style.append(QString::number(g, 16));
-    style.append(QString::number(b, 16));
-    style.append(";}");
-    this->setStyleSheet(style);
-    this->update();
+    fRasterWidget.setDebugCanvas(fDebugCanvas);
+    fGLWidget.setDebugCanvas(fDebugCanvas);
 }
 
 void SkCanvasWidget::mouseMoveEvent(QMouseEvent* event) {
-
     SkIPoint eventPoint = SkIPoint::Make(event->globalX(), event->globalY());
     fTransform += eventPoint - fPreviousPoint;
     fPreviousPoint = eventPoint;
-
-    // TODO(chudy): Fix and remove +1 from drawTo calls.
+    updateWidgetTransform(kTranslate);
     drawTo(fIndex);
-    this->update();
 }
 
 void SkCanvasWidget::mousePressEvent(QMouseEvent* event) {
@@ -138,23 +80,34 @@
     fTransform.set(0,0);
     fScaleFactor = 1.0;
     emit scaleFactorChanged(fScaleFactor);
+    // TODO(chudy): Change to signal / slot mechanism.
+    resetWidgetTransform();
     drawTo(fIndex);
-    this->update();
 }
 
-void SkCanvasWidget::paintEvent(QPaintEvent *event) {
-    QPainter painter(this);
-    QStyleOption opt;
-    opt.init(this);
+void SkCanvasWidget::resetWidgetTransform() {
+    fTransform.set(0,0);
+    fScaleFactor = 1.0;
+    updateWidgetTransform(kTranslate);
+    updateWidgetTransform(kScale);
+}
 
-    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
+void SkCanvasWidget::setWidgetVisibility(WidgetType type, bool isHidden) {
+    if (type == kRaster_8888_WidgetType) {
+        fRasterWidget.setHidden(isHidden);
+    } else if (type == kGPU_WidgetType) {
+        fGLWidget.setHidden(isHidden);
+    }
+}
 
-    QPoint origin(0,0);
-    QImage image((uchar *)fBitmap.getPixels(), fBitmap.width(),
-            fBitmap.height(), QImage::Format_ARGB32_Premultiplied);
-
-    painter.drawImage(origin, image);
-    painter.end();
+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::wheelEvent(QWheelEvent* event) {
@@ -167,10 +120,7 @@
     if (fScaleFactor == 0) {
         fScaleFactor += (event->delta()/120) * 2;
     }
-
     emit scaleFactorChanged(fScaleFactor);
-
-    // TODO(chudy): Fix and remove +1 from drawTo calls.
+    updateWidgetTransform(kScale);
     drawTo(fIndex);
-    this->update();
 }
diff --git a/debugger/QT/SkCanvasWidget.h b/debugger/QT/SkCanvasWidget.h
index 94295bb..2ea7329 100644
--- a/debugger/QT/SkCanvasWidget.h
+++ b/debugger/QT/SkCanvasWidget.h
@@ -7,91 +7,27 @@
  */
 
 
-#ifndef SKCANVASWIDGET_H
-#define SKCANVASWIDGET_H
+#ifndef SKCANVASWIDGET_H_
+#define SKCANVASWIDGET_H_
 
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkDebugCanvas.h"
-#include "SkDevice.h"
-#include "SkPicture.h"
-#include <QApplication>
-#include <QtGui>
 #include <QWidget>
-#include <QWheelEvent>
+#include <QHBoxLayout>
+#include "SkStream.h"
+#include "SkRasterWidget.h"
+#include "SkGLWidget.h"
 
-/** \class SkCanvasWidget
-
-      The QtWidget encompasses all skia screen drawing elements. It initializes
-      an SkBitmap in memory that our SkCanvas draws to directly in memory.
-      Then using QImage and QPainter we draw those pixels on the screen in
-      this widget.
- */
 class SkCanvasWidget : public QWidget {
     Q_OBJECT
 
 public:
-    /**
-         Constructs a widget with the specified parent for layout purposes.
-        @param parent  The parent container of this widget
-     */
-    SkCanvasWidget(QWidget *parent);
+    SkCanvasWidget(QWidget* parent);
 
-    ~SkCanvasWidget();
+    ~SkCanvasWidget() {}
 
-    /**
-        Executes all saved draw commands up to the specified index.
-         @param index  The position of the command we draw up to.
-     */
-    void drawTo(int index);
-
-    /**
-        Returns the height of the bitmap.
-     */
-    int getBitmapHeight() { return fBitmap.height(); }
-
-
-    /*
-        Returns the width of the bitmap.
-     */
-    int getBitmapWidth() { return fBitmap.width(); }
-
-    /**
-        Returns an array of values of the current matrix.
-     */
-    const SkMatrix& getCurrentMatrix() {
-        return fCanvas->getTotalMatrix();
-    }
-
-    /**
-        Returns an array of values of the current bounding clip.
-     */
-    const SkIRect& getCurrentClip() {
-        return fCanvas->getTotalClip().getBounds();
-    }
-
-    /**
-        TODO(chudy): Refactor into a struct of char**
-        Returns parameter information about the ith draw command.
-        @param: i  The index of the draw command we are accessing
-     */
-    std::vector<std::string>* getCurrentCommandInfo(int i) {
-        return fDebugCanvas->getCommandInfoAt(i);
-    }
-
-    /**
-          Returns a vector of strings with all the current canvas draw
-          commands.
-     */
-    std::vector<std::string>* getDrawCommands() {
-        return fDebugCanvas->getDrawCommandsAsStrings();
-    }
-
-    /**
-        Loads a skia picture located at filename.
-        @param filename  The name of the file we are loading.
-     */
-    void loadPicture(QString filename);
+    enum WidgetType {
+        kRaster_8888_WidgetType = 1 << 0,
+        kGPU_WidgetType         = 1 << 1,
+    };
 
     /**
         Returns the visibility of the command at the specified index.
@@ -110,6 +46,22 @@
     }
 
     /**
+          Returns a vector of strings with all the current canvas draw
+          commands.
+     */
+    std::vector<std::string>* getDrawCommands() {
+        return fDebugCanvas->getDrawCommandsAsStrings();
+    }
+
+    SkDebugCanvas* getCurrentDebugCanvas() {
+        return fDebugCanvas;
+    }
+
+    void drawTo(int index);
+
+    void setWidgetVisibility(WidgetType type, bool isHidden);
+
+    /**
         Toggles drawing filter on all drawing commands previous to current.
      */
     void toggleCurrentCommandFilter(bool toggle) {
@@ -117,42 +69,71 @@
     }
 
     /**
-        Captures mouse clicks
-        @param event  The event intercepted by Qt
+        TODO(chudy): Refactor into a struct of char**
+        Returns parameter information about the ith draw command.
+        @param: i  The index of the draw command we are accessing
      */
-    void mouseMoveEvent(QMouseEvent* event);
+    std::vector<std::string>* getCurrentCommandInfo(int i) {
+        return fDebugCanvas->getCommandInfoAt(i);
+    }
 
-    void mousePressEvent(QMouseEvent* event);
+    const SkMatrix& getCurrentMatrix() {
+        return fRasterWidget.getCurrentMatrix();
+    }
 
-    void mouseDoubleClickEvent(QMouseEvent* event);
+    const SkIRect& getCurrentClip() {
+        return fRasterWidget.getCurrentClip();
+    }
 
-    void resizeEvent(QResizeEvent* event);
+    void loadPicture(QString filename);
 
-    void wheelEvent(QWheelEvent* event);
+    // TODO(chudy): Not full proof since fRasterWidget isn't always drawn to.
+    int getBitmapHeight() {
+        return fRasterWidget.getBitmapHeight();
+    }
+
+    int getBitmapWidth() {
+        return fRasterWidget.getBitmapWidth();
+    }
+
+    SkRasterWidget* getRasterWidget() {
+        return &fRasterWidget;
+    }
+
+
 
 signals:
     void scaleFactorChanged(float newScaleFactor);
     void commandChanged(int newCommand);
     void hitChanged(int hit);
 
-protected:
-    /**
-        Draws the current state of the widget.
-        @param event  The event intercepted by Qt
-     */
-    void paintEvent(QPaintEvent *event);
-
 private:
-    SkBitmap fBitmap;
-    SkCanvas* fCanvas;
+    QHBoxLayout fHorizontalLayout;
+    SkRasterWidget fRasterWidget;
+    SkGLWidget fGLWidget;
     SkDebugCanvas* fDebugCanvas;
-    SkDevice* fDevice;
-
     SkIPoint fPreviousPoint;
     SkIPoint fTransform;
-
-    int fIndex;
     float fScaleFactor;
+    int fIndex;
+
+    enum TransformType {
+        kTranslate 	= 1 << 0,
+        kScale 		= 1 << 1,
+    };
+
+    void resetWidgetTransform();
+
+    void updateWidgetTransform(TransformType type);
+
+    void mouseMoveEvent(QMouseEvent* event);
+
+    void mousePressEvent(QMouseEvent* event);
+
+    void mouseDoubleClickEvent(QMouseEvent* event);
+
+    void wheelEvent(QWheelEvent* event);
 };
 
-#endif
+
+#endif /* SKCANVASWIDGET_H_ */
diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp
index 223e76a..131386c 100644
--- a/debugger/QT/SkDebuggerGUI.cpp
+++ b/debugger/QT/SkDebuggerGUI.cpp
@@ -47,48 +47,34 @@
     , fLoading(false)
 {
     setupUi(this);
-    connect(&fListWidget, SIGNAL(currentItemChanged(QListWidgetItem*,
-                    QListWidgetItem*)), this,
-            SLOT(registerListClick(QListWidgetItem *)));
+    connect(&fListWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(registerListClick(QListWidgetItem *)));
     connect(&fActionOpen, SIGNAL(triggered()), this, SLOT(openFile()));
-    connect(&fActionDirectory, SIGNAL(triggered()), this,
-            SLOT(toggleDirectory()));
-    connect(&fDirectoryWidget, SIGNAL(currentItemChanged(QListWidgetItem*,
-                    QListWidgetItem*)), this,
-            SLOT(loadFile(QListWidgetItem *)));
+    connect(&fActionDirectory, SIGNAL(triggered()), this, SLOT(toggleDirectory()));
+    connect(&fDirectoryWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(loadFile(QListWidgetItem *)));
     connect(&fActionDelete, SIGNAL(triggered()), this, SLOT(actionDelete()));
-    connect(&fListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this,
-            SLOT(toggleBreakpoint()));
+    connect(&fListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(toggleBreakpoint()));
     connect(&fActionRewind, SIGNAL(triggered()), this, SLOT(actionRewind()));
     connect(&fActionPlay, SIGNAL(triggered()), this, SLOT(actionPlay()));
     connect(&fActionStepBack, SIGNAL(triggered()), this, SLOT(actionStepBack()));
-    connect(&fActionStepForward, SIGNAL(triggered()), this,
-            SLOT(actionStepForward()));
-    connect(&fActionBreakpoint, SIGNAL(triggered()), this,
-            SLOT(actionBreakpoints()));
-    connect(&fActionInspector, SIGNAL(triggered()), this,
-            SLOT(actionInspector()));
-    connect(&fActionInspector, SIGNAL(triggered()), this,
-            SLOT(actionSettings()));
-    connect(&fFilter, SIGNAL(activated(QString)), this,
-            SLOT(toggleFilter(QString)));
+    connect(&fActionStepForward, SIGNAL(triggered()), this, SLOT(actionStepForward()));
+    connect(&fActionBreakpoint, SIGNAL(triggered()), this, SLOT(actionBreakpoints()));
+    connect(&fActionInspector, SIGNAL(triggered()), this, SLOT(actionInspector()));
+    connect(&fActionInspector, SIGNAL(triggered()), this, SLOT(actionSettings()));
+    connect(&fFilter, SIGNAL(activated(QString)), this, SLOT(toggleFilter(QString)));
     connect(&fActionCancel, SIGNAL(triggered()), this, SLOT(actionCancel()));
     connect(&fActionClearBreakpoints, SIGNAL(triggered()), this, SLOT(actionClearBreakpoints()));
     connect(&fActionClearDeletes, SIGNAL(triggered()), this, SLOT(actionClearDeletes()));
     connect(&fActionClose, SIGNAL(triggered()), this, SLOT(actionClose()));
-    connect(fSettingsWidget.getVisibilityButton(), SIGNAL(toggled(bool)), this,
-            SLOT(actionCommandFilter()));
-    connect(&fCanvasWidget, SIGNAL(scaleFactorChanged(float)), this,
-            SLOT(actionScale(float)));
-    connect(&fActionPause, SIGNAL(toggled(bool)),
-            this, SLOT(pauseDrawing(bool)));
-    connect(&fCanvasWidget, SIGNAL(commandChanged(int)), &fSettingsWidget,
-            SLOT(updateCommand(int)));
-    connect(&fCanvasWidget, SIGNAL(hitChanged(int)), this, SLOT(selectCommand(int)));
-    connect(&fCanvasWidget, SIGNAL(hitChanged(int)), &fSettingsWidget,
-            SLOT(updateHit(int)));
+    connect(fSettingsWidget.getVisibilityButton(), SIGNAL(toggled(bool)), this, SLOT(actionCommandFilter()));
+    connect(fSettingsWidget.getGLCheckBox(), SIGNAL(toggled(bool)), this, SLOT(actionGLWidget(bool)));
+    connect(fSettingsWidget.getRasterCheckBox(), SIGNAL(toggled(bool)), this, SLOT(actionRasterWidget(bool)));
+    connect(&fActionPause, SIGNAL(toggled(bool)), this, SLOT(pauseDrawing(bool)));
     connect(&fActionCreateBreakpoint, SIGNAL(activated()), this, SLOT(toggleBreakpoint()));
     connect(&fActionShowDeletes, SIGNAL(triggered()), this, SLOT(showDeletes()));
+    connect(&fCanvasWidget, SIGNAL(hitChanged(int)), this, SLOT(selectCommand(int)));
+    connect(&fCanvasWidget, SIGNAL(hitChanged(int)), &fSettingsWidget, SLOT(updateHit(int)));
+    connect(&fCanvasWidget, SIGNAL(scaleFactorChanged(float)), this, SLOT(actionScale(float)));
+    connect(&fCanvasWidget, SIGNAL(commandChanged(int)), &fSettingsWidget, SLOT(updateCommand(int)));
 
     fInspectorWidget.setDisabled(true);
     fMenuEdit.setDisabled(true);
@@ -174,6 +160,10 @@
     }
 }
 
+void SkDebuggerGUI::actionGLWidget(bool isToggled) {
+    fCanvasWidget.setWidgetVisibility(SkCanvasWidget::kGPU_WidgetType, !isToggled);
+}
+
 void SkDebuggerGUI::actionInspector() {
     if (fInspectorWidget.isHidden()) {
         fInspectorWidget.setHidden(false);
@@ -194,6 +184,10 @@
     fListWidget.setCurrentRow(fListWidget.count() - 1);
 }
 
+void SkDebuggerGUI::actionRasterWidget(bool isToggled) {
+    fCanvasWidget.setWidgetVisibility(SkCanvasWidget::kRaster_8888_WidgetType, !isToggled);
+}
+
 void SkDebuggerGUI::actionRewind() {
     fListWidget.setCurrentRow(0);
 }
@@ -263,28 +257,32 @@
 void SkDebuggerGUI::registerListClick(QListWidgetItem *item) {
     if(!fLoading) {
         int currentRow = fListWidget.currentRow();
-        if (!fPause) {
-            fCanvasWidget.drawTo(currentRow);
-        }
-        std::vector<std::string> *v = fCanvasWidget.getCurrentCommandInfo(
-                currentRow);
 
-        /* TODO(chudy): Add command type before parameters. Rename v
-         * to something more informative. */
-        if (v) {
-            std::vector<std::string>::iterator it;
-
-            QString info;
-            info.append("<b>Parameters: </b><br/>");
-            for (it = v->begin(); it != v->end(); ++it) {
-                info.append(QString((*it).c_str()));
-                info.append("<br/>");
+        if (currentRow != -1) {
+            if (!fPause) {
+                fCanvasWidget.drawTo(currentRow);
             }
-            fInspectorWidget.setDetailText(info);
-            fInspectorWidget.setDisabled(false);
-            fInspectorWidget.setMatrix(fCanvasWidget.getCurrentMatrix());
-            fInspectorWidget.setClip(fCanvasWidget.getCurrentClip());
+            std::vector<std::string> *cuffInfo = fCanvasWidget.getCurrentCommandInfo(
+                    currentRow);
+
+            /* TODO(chudy): Add command type before parameters. Rename v
+             * to something more informative. */
+            if (cuffInfo) {
+                std::vector<std::string>::iterator it;
+
+                QString info;
+                info.append("<b>Parameters: </b><br/>");
+                for (it = cuffInfo->begin(); it != cuffInfo->end(); ++it) {
+                    info.append(QString((*it).c_str()));
+                    info.append("<br/>");
+                }
+                fInspectorWidget.setDetailText(info);
+                fInspectorWidget.setDisabled(false);
+                fInspectorWidget.setMatrix(fCanvasWidget.getCurrentMatrix());
+                fInspectorWidget.setClip(fCanvasWidget.getCurrentClip());
+            }
         }
+
     }
 }
 
@@ -476,7 +474,7 @@
 
     // TODO(chudy): Remove static call.
     fDirectoryWidgetActive = false;
-    fPath = "/usr/local/google/home/chudy/trunk-linux/debugger/skp";
+    fPath = "/usr/local/google/home/chudy/trunk-git/trunk/skp";
     setupDirectoryWidget();
     fDirectoryWidgetActive = true;
 
diff --git a/debugger/QT/SkDebuggerGUI.h b/debugger/QT/SkDebuggerGUI.h
index 0621d7c..072e58b 100644
--- a/debugger/QT/SkDebuggerGUI.h
+++ b/debugger/QT/SkDebuggerGUI.h
@@ -11,10 +11,12 @@
 
 
 #include "SkCanvas.h"
+#include "SkCanvasWidget.h"
 #include "SkDebugCanvas.h"
+#include "SkGLWidget.h"
 #include "SkListWidget.h"
 #include "SkInspectorWidget.h"
-#include "SkCanvasWidget.h"
+#include "SkRasterWidget.h"
 #include "SkSettingsWidget.h"
 #include <QtCore/QVariant>
 #include <QtGui/QAction>
@@ -89,6 +91,11 @@
     void actionDelete();
 
     /**
+        Toggles the visibility of the GL canvas widget.
+     */
+    void actionGLWidget(bool isToggled);
+
+    /**
         Toggles the visibility of the inspector widget.
      */
     void actionInspector();
@@ -100,6 +107,11 @@
     void actionPlay();
 
     /**
+        Toggles the visibility of the raster canvas widget.
+     */
+    void actionRasterWidget(bool isToggled);
+
+    /**
         Rewinds from the current step back to the start of the commands.
      */
     void actionRewind();
diff --git a/debugger/QT/SkGLWidget.cpp b/debugger/QT/SkGLWidget.cpp
new file mode 100644
index 0000000..395cf44
--- /dev/null
+++ b/debugger/QT/SkGLWidget.cpp
@@ -0,0 +1,71 @@
+
+/*
+ * 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 "SkGLWidget.h"
+
+SkGLWidget::SkGLWidget(QWidget* parent) : QGLWidget(parent) {
+    this->setStyleSheet("QWidget {background-color: white; border: 1px solid #cccccc;}");
+    fTransform.set(0,0);
+    fScaleFactor = 1.0;
+    fIndex = 0;
+    fDebugCanvas = NULL;
+}
+
+SkGLWidget::~SkGLWidget() {
+    SkSafeUnref(fCurIntf);
+    SkSafeUnref(fCurContext);
+    SkSafeUnref(fGpuDevice);
+}
+
+void SkGLWidget::initializeGL() {
+    fCurIntf = GrGLCreateNativeInterface();
+    fCurContext = GrContext::Create(kOpenGL_Shaders_GrEngine, (GrPlatform3DContext) fCurIntf);
+    GrRenderTarget* curRenderTarget = fCurContext->createPlatformRenderTarget(getDesc(this->width(), this->height()));
+    fGpuDevice = new SkGpuDevice(fCurContext, curRenderTarget);
+    curRenderTarget->unref();
+
+    glClearColor(1, 1, 1, 0);
+    glClearStencil(0);
+    glClear(GL_STENCIL_BUFFER_BIT);
+}
+
+void SkGLWidget::resizeGL(int w, int h) {
+    GrRenderTarget* curRenderTarget = fCurContext->createPlatformRenderTarget(getDesc(w,h));
+    SkSafeUnref(fGpuDevice);
+    fGpuDevice = new SkGpuDevice(fCurContext, curRenderTarget);
+    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);
+    }
+    // TODO(chudy): Remove bitmap arguement.
+    fDebugCanvas->drawTo(&canvas, fIndex+1, NULL);
+    canvas.flush();
+}
+
+GrPlatformRenderTargetDesc SkGLWidget::getDesc(int w, int h) {
+    GrPlatformRenderTargetDesc desc;
+    desc.fWidth = SkScalarRound(this->width());
+    desc.fHeight = SkScalarRound(this->height());
+    desc.fConfig = kSkia8888_PM_GrPixelConfig;
+    GR_GL_GetIntegerv(fCurIntf, GR_GL_SAMPLES, &desc.fSampleCnt);
+    GR_GL_GetIntegerv(fCurIntf, GR_GL_STENCIL_BITS, &desc.fStencilBits);
+    GrGLint buffer;
+    GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer);
+    desc.fRenderTargetHandle = buffer;
+
+    return desc;
+}
diff --git a/debugger/QT/SkGLWidget.h b/debugger/QT/SkGLWidget.h
new file mode 100644
index 0000000..4a036aa
--- /dev/null
+++ b/debugger/QT/SkGLWidget.h
@@ -0,0 +1,68 @@
+
+/*
+ * 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 SKGLWIDGET_H_
+#define SKGLWIDGET_H_
+
+#include <QtOpenGL/QGLWidget>
+#include "SkDebugCanvas.h"
+#include "SkDevice.h"
+#include "SkGpuDevice.h"
+
+#include "GrContext.h"
+#include "gl/GrGLInterface.h"
+#include "gl/GrGLUtil.h"
+#include "GrRenderTarget.h"
+
+class SkGLWidget : public QGLWidget {
+
+public:
+    SkGLWidget(QWidget* parent = NULL);
+
+    ~SkGLWidget();
+
+    void setDebugCanvas(SkDebugCanvas* debugCanvas) {
+        fDebugCanvas = debugCanvas;
+        fIndex = debugCanvas->getSize();
+        this->updateGL();
+    }
+
+    void drawTo(int index) {
+        fIndex = index;
+        this->updateGL();
+    }
+
+    void setTranslate(SkIPoint translate) {
+        fTransform = translate;
+    }
+
+    void setScale(float scale) {
+        fScaleFactor = scale;
+    }
+
+protected:
+    void initializeGL();
+    void resizeGL(int w, int h);
+    void paintGL();
+
+
+private:
+    const GrGLInterface* fCurIntf;
+    GrContext* fCurContext;
+    SkGpuDevice* fGpuDevice;
+    SkCanvas* fCanvas;
+    SkDebugCanvas* fDebugCanvas;
+    int fIndex;
+    SkIPoint fTransform;
+    float fScaleFactor;
+
+    GrPlatformRenderTargetDesc getDesc(int w, int h);
+};
+
+#endif /* SKGLWIDGET_H_ */
diff --git a/debugger/QT/SkSettingsWidget.cpp b/debugger/QT/SkSettingsWidget.cpp
index 8ef4e9a..bc37a12 100644
--- a/debugger/QT/SkSettingsWidget.cpp
+++ b/debugger/QT/SkSettingsWidget.cpp
@@ -11,6 +11,7 @@
 #include <iostream>
 #include <math.h>
 
+// TODO(chudy): See if the layout can't be attached to the frame post construction.
 SkSettingsWidget::SkSettingsWidget(QWidget *parent) : QWidget(parent)
     , mainFrameLayout(this)
     , fVerticalLayout(&mainFrame)
@@ -20,6 +21,7 @@
     , fCommandLayout(&fCommandFrame)
     , fCurrentCommandBox(&fCommandFrame)
     , fCommandHitBox(&fCommandFrame)
+    , fCanvasLayout(&fCanvasFrame)
     , fZoomBox(&fZoomFrame)
     , fZoomLayout(&fZoomFrame)
 {
@@ -46,6 +48,33 @@
     fVisibleFrameLayout.addWidget(&fVisibleOn);
     fVisibleFrameLayout.addWidget(&fVisibleOff);
 
+    // Canvas
+    fCanvasToggle.setText("Render Targets");
+    fCanvasFrame.setFrameShape(QFrame::StyledPanel);
+    fCanvasFrame.setFrameShadow(QFrame::Raised);
+
+    fRasterLabel.setText("Raster: ");
+    fRasterLabel.setMinimumWidth(178);
+    fRasterLabel.setMaximumWidth(178);
+
+    fRasterCheckBox.setChecked(true);
+
+    fGLLabel.setText("OpenGL: ");
+    fGLLabel.setMinimumWidth(178);
+    fGLLabel.setMaximumWidth(178);
+
+    fRasterLayout.addWidget(&fRasterLabel);
+    fRasterLayout.addWidget(&fRasterCheckBox);
+
+    fGLLayout.addWidget(&fGLLabel);
+    fGLLayout.addWidget(&fGLCheckBox);
+
+    fCanvasLayout.setSpacing(6);
+    fCanvasLayout.setContentsMargins(11,11,11,11);
+    fCanvasLayout.addWidget(&fCanvasToggle);
+    fCanvasLayout.addLayout(&fRasterLayout);
+    fCanvasLayout.addLayout(&fGLLayout);
+
     // Command Toggle
     fCommandToggle.setText("Command Scrolling Preferences");
     fCommandFrame.setFrameShape(QFrame::StyledPanel);
@@ -103,6 +132,8 @@
     fVerticalLayout.addWidget(&fVisibleFrame);
     fVerticalLayout.addWidget(&fCommandToggle);
     fVerticalLayout.addWidget(&fCommandFrame);
+    fVerticalLayout.addWidget(&fCanvasToggle);
+    fVerticalLayout.addWidget(&fCanvasFrame);
     fVerticalLayout.addWidget(&fZoomFrame);
 
     this->setDisabled(true);
diff --git a/debugger/QT/SkSettingsWidget.h b/debugger/QT/SkSettingsWidget.h
index 950ea16..1afb93e 100644
--- a/debugger/QT/SkSettingsWidget.h
+++ b/debugger/QT/SkSettingsWidget.h
@@ -39,6 +39,14 @@
 
     QRadioButton* getVisibilityButton();
 
+    QCheckBox* getGLCheckBox() {
+        return &fGLCheckBox;
+    }
+
+    QCheckBox* getRasterCheckBox() {
+        return &fRasterCheckBox;
+    }
+
 private slots:
     void updateCommand(int newCommand);
     void updateHit(int newHit);
@@ -71,6 +79,18 @@
     QLineEdit fCommandHitBox;
     QHBoxLayout fCommandHitLayout;
 
+    QLabel fCanvasToggle;
+    QFrame fCanvasFrame;
+    QVBoxLayout fCanvasLayout;
+
+    QHBoxLayout fRasterLayout;
+    QLabel fRasterLabel;
+    QCheckBox fRasterCheckBox;
+
+    QHBoxLayout fGLLayout;
+    QLabel fGLLabel;
+    QCheckBox fGLCheckBox;
+
     QLabel fZoomSetting;
     QFrame fZoomFrame;
     QLineEdit fZoomBox;
diff --git a/debugger/QT/moc_SkDebuggerGUI.cpp b/debugger/QT/moc_SkDebuggerGUI.cpp
index 3f11cb1..cb1e571 100644
--- a/debugger/QT/moc_SkDebuggerGUI.cpp
+++ b/debugger/QT/moc_SkDebuggerGUI.cpp
@@ -1,7 +1,7 @@
 /****************************************************************************
 ** Meta object code from reading C++ file 'SkDebuggerGUI.h'
 **
-** Created: Mon Jul 16 16:36:08 2012
+** Created: Wed Jul 25 15:04:14 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 @@
        4,       // revision
        0,       // classname
        0,    0, // classinfo
-      25,   14, // methods
+      27,   14, // methods
        0,    0, // properties
        0,    0, // enums/sets
        0,    0, // constructors
@@ -41,23 +41,25 @@
      124,   14,   14,   14, 0x08,
      146,   14,   14,   14, 0x08,
      160,   14,   14,   14, 0x08,
-     175,   14,   14,   14, 0x08,
-     193,   14,   14,   14, 0x08,
+     185,  175,   14,   14, 0x08,
      206,   14,   14,   14, 0x08,
-     233,  221,   14,   14, 0x08,
-     252,   14,   14,   14, 0x08,
-     269,   14,   14,   14, 0x08,
-     286,   14,   14,   14, 0x08,
-     311,  306,   14,   14, 0x08,
-     338,   14,   14,   14, 0x08,
-     358,  349,   14,   14, 0x08,
-     377,   14,   14,   14, 0x28,
-     392,  306,   14,   14, 0x08,
-     428,   15,   14,   14, 0x08,
-     447,   14,   14,   14, 0x08,
-     461,   14,   14,   14, 0x08,
-     480,   14,   14,   14, 0x08,
-     505,  498,   14,   14, 0x08,
+     224,   14,   14,   14, 0x08,
+     237,  175,   14,   14, 0x08,
+     262,   14,   14,   14, 0x08,
+     289,  277,   14,   14, 0x08,
+     308,   14,   14,   14, 0x08,
+     325,   14,   14,   14, 0x08,
+     342,   14,   14,   14, 0x08,
+     367,  362,   14,   14, 0x08,
+     394,   14,   14,   14, 0x08,
+     414,  405,   14,   14, 0x08,
+     433,   14,   14,   14, 0x28,
+     448,  362,   14,   14, 0x08,
+     484,   15,   14,   14, 0x08,
+     503,   14,   14,   14, 0x08,
+     517,   14,   14,   14, 0x08,
+     536,   14,   14,   14, 0x08,
+     561,  554,   14,   14, 0x08,
 
        0        // eod
 };
@@ -67,13 +69,15 @@
     "actionBreakpoints()\0actionCancel()\0"
     "actionClearBreakpoints()\0actionClearDeletes()\0"
     "actionCommandFilter()\0actionClose()\0"
-    "actionDelete()\0actionInspector()\0"
-    "actionPlay()\0actionRewind()\0scaleFactor\0"
-    "actionScale(float)\0actionSettings()\0"
-    "actionStepBack()\0actionStepForward()\0"
-    "item\0loadFile(QListWidgetItem*)\0"
-    "openFile()\0isPaused\0pauseDrawing(bool)\0"
-    "pauseDrawing()\0registerListClick(QListWidgetItem*)\0"
+    "actionDelete()\0setHidden\0actionGLWidget(bool)\0"
+    "actionInspector()\0actionPlay()\0"
+    "actionRasterWidget(bool)\0actionRewind()\0"
+    "scaleFactor\0actionScale(float)\0"
+    "actionSettings()\0actionStepBack()\0"
+    "actionStepForward()\0item\0"
+    "loadFile(QListWidgetItem*)\0openFile()\0"
+    "isPaused\0pauseDrawing(bool)\0pauseDrawing()\0"
+    "registerListClick(QListWidgetItem*)\0"
     "selectCommand(int)\0showDeletes()\0"
     "toggleBreakpoint()\0toggleDirectory()\0"
     "string\0toggleFilter(QString)\0"
@@ -116,26 +120,28 @@
         case 5: actionCommandFilter(); break;
         case 6: actionClose(); break;
         case 7: actionDelete(); break;
-        case 8: actionInspector(); break;
-        case 9: actionPlay(); break;
-        case 10: actionRewind(); break;
-        case 11: actionScale((*reinterpret_cast< float(*)>(_a[1]))); break;
-        case 12: actionSettings(); break;
-        case 13: actionStepBack(); break;
-        case 14: actionStepForward(); break;
-        case 15: loadFile((*reinterpret_cast< QListWidgetItem*(*)>(_a[1]))); break;
-        case 16: openFile(); break;
-        case 17: pauseDrawing((*reinterpret_cast< bool(*)>(_a[1]))); break;
-        case 18: pauseDrawing(); break;
-        case 19: registerListClick((*reinterpret_cast< QListWidgetItem*(*)>(_a[1]))); break;
-        case 20: selectCommand((*reinterpret_cast< int(*)>(_a[1]))); break;
-        case 21: showDeletes(); break;
-        case 22: toggleBreakpoint(); break;
-        case 23: toggleDirectory(); break;
-        case 24: toggleFilter((*reinterpret_cast< QString(*)>(_a[1]))); break;
+        case 8: actionGLWidget((*reinterpret_cast< bool(*)>(_a[1]))); break;
+        case 9: actionInspector(); break;
+        case 10: actionPlay(); break;
+        case 11: actionRasterWidget((*reinterpret_cast< bool(*)>(_a[1]))); break;
+        case 12: actionRewind(); break;
+        case 13: actionScale((*reinterpret_cast< float(*)>(_a[1]))); break;
+        case 14: actionSettings(); break;
+        case 15: actionStepBack(); break;
+        case 16: actionStepForward(); break;
+        case 17: loadFile((*reinterpret_cast< QListWidgetItem*(*)>(_a[1]))); break;
+        case 18: openFile(); break;
+        case 19: pauseDrawing((*reinterpret_cast< bool(*)>(_a[1]))); break;
+        case 20: pauseDrawing(); break;
+        case 21: registerListClick((*reinterpret_cast< QListWidgetItem*(*)>(_a[1]))); break;
+        case 22: selectCommand((*reinterpret_cast< int(*)>(_a[1]))); break;
+        case 23: showDeletes(); break;
+        case 24: toggleBreakpoint(); break;
+        case 25: toggleDirectory(); break;
+        case 26: toggleFilter((*reinterpret_cast< QString(*)>(_a[1]))); break;
         default: ;
         }
-        _id -= 25;
+        _id -= 27;
     }
     return _id;
 }
diff --git a/debugger/SkDebugCanvas.cpp b/debugger/SkDebugCanvas.cpp
index c811a05..c5f0c2d 100644
--- a/debugger/SkDebugCanvas.cpp
+++ b/debugger/SkDebugCanvas.cpp
@@ -59,7 +59,7 @@
                      (*it)->execute(canvas);
                  }
              }
-            if (fCalculateHits == true) {
+            if (fCalculateHits == true && bitmap != NULL) {
                 fHitBox.updateHitPoint(bitmap, counter);
             }
 
diff --git a/debugger/moc.sh b/debugger/moc.sh
index 2d86fc6..86cb5e7 100755
--- a/debugger/moc.sh
+++ b/debugger/moc.sh
@@ -6,7 +6,7 @@
 #MOC="/usr/local/google/home/chudy/tools/Qt/Desktop/Qt/4.8.1/gcc/bin/moc"
 SRC_DIR=$SCRIPT_DIR/QT
 
-$MOC $SRC_DIR/SkDebuggerGUI.h -o $SRC_DIR/moc_SkDebuggerGUI.cpp
 $MOC $SRC_DIR/SkCanvasWidget.h -o $SRC_DIR/moc_SkCanvasWidget.cpp
+$MOC $SRC_DIR/SkDebuggerGUI.h -o $SRC_DIR/moc_SkDebuggerGUI.cpp
 $MOC $SRC_DIR/SkInspectorWidget.h -o $SRC_DIR/moc_SkInspectorWidget.cpp
 $MOC $SRC_DIR/SkSettingsWidget.h -o $SRC_DIR/moc_SkSettingsWidget.cpp
diff --git a/gyp/debugger.gyp b/gyp/debugger.gyp
index a98e809..5b18c5e 100644
--- a/gyp/debugger.gyp
+++ b/gyp/debugger.gyp
@@ -7,6 +7,8 @@
         '../src/core',
         '../debugger', # To pull SkDebugger.h
         '../debugger/QT', # For all the QT UI Goodies
+        '../include/gpu/',
+        '../src/gpu', # To pull gl/GrGLUtil.h
       ],
       'sources': [
         '../debugger/SkDebugCanvas.h',
@@ -14,8 +16,8 @@
         '../debugger/SkDebugger.cpp',
         '../debugger/SkDrawCommand.h',
         '../debugger/SkDrawCommand.cpp',
-        '../debugger/QT/moc_SkDebuggerGUI.cpp',
         '../debugger/QT/moc_SkCanvasWidget.cpp',
+        '../debugger/QT/moc_SkDebuggerGUI.cpp',
         '../debugger/QT/moc_SkInspectorWidget.cpp',
         '../debugger/QT/moc_SkSettingsWidget.cpp',
         '../debugger/QT/SkDebuggerGUI.cpp',
@@ -32,6 +34,10 @@
         '../debugger/QT/SkSettingsWidget.cpp',
         '../debugger/SkHitBox.h',
         '../debugger/SkHitBox.cpp',
+        '../debugger/QT/SkGLWidget.h',
+        '../debugger/QT/SkGLWidget.cpp',
+        '../debugger/QT/SkRasterWidget.h',
+        '../debugger/QT/SkRasterWidget.cpp',
 
         # To update this file edit SkIcons.qrc and rerun rcc to generate cpp
         '../debugger/QT/qrc_SkIcons.cpp',
@@ -41,6 +47,8 @@
         'images.gyp:images',
         'ports.gyp:ports',
         'effects.gyp:effects',
+        'gpu.gyp:gr',
+        'gpu.gyp:skgr',
       ],
       'conditions': [
         [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris"]', {
@@ -48,11 +56,13 @@
             '/usr/include/qt4',
             '/usr/include/qt4/QtCore',
             '/usr/include/qt4/QtGui',
+            '/usr/include/qt4/QtOpenGL',
           ],
           'link_settings': {
             'libraries' : [
               '-lQtCore',
               '-lQtGui',
+              '-lQtOpenGL'
             ],
           },
         }],
@@ -64,11 +74,13 @@
           'include_dirs': [
             '/Library/Frameworks/QtCore.framework/Headers/',
             '/Library/Frameworks/QtGui.framework/Headers/',
+            '/Library/Frameworks/QtOpenGL.framework/Headers/',
           ],
           'link_settings': {
             'libraries': [
               '/Library/Frameworks/QtCore.framework',
               '/Library/Frameworks/QtGui.framework',
+              '/Library/Frameworks/QtOpenGL.framework',
             ],
           },
         }],
@@ -78,11 +90,13 @@
             'C:/Qt/4.6.4/include',
             'C:/Qt/4.6.4/include/QtCore',
             'C:/Qt/4.6.4/include/QtGui',
+            'C:/Qt/4.6.4/include/QtOpenGL',
           ],
           'link_settings': {
             'libraries': [
               'C:/Qt/4.6.4/lib/QtCore4.lib',
               'C:/Qt/4.6.4/lib/QtGui4.lib',
+              'C:/Qt/4.6.4/lib/QtOpenGL.lib',
             ],
           },
         }],