| Index: nacl/src/nacl_debugger.cpp
|
| ===================================================================
|
| --- nacl/src/nacl_debugger.cpp (revision 7896)
|
| +++ nacl/src/nacl_debugger.cpp (working copy)
|
| @@ -6,75 +6,45 @@
|
| #include "ppapi/cpp/image_data.h"
|
| #include "ppapi/cpp/instance.h"
|
| #include "ppapi/cpp/module.h"
|
| +#include "ppapi/cpp/point.h"
|
| +#include "ppapi/cpp/rect.h"
|
| #include "ppapi/cpp/var.h"
|
|
|
| +#include "SkBase64.h"
|
| +#include "SkBitmap.h"
|
| #include "SkCanvas.h"
|
| -#include "SkBitmap.h"
|
| +#include "SkColor.h"
|
| +#include "SkDebugger.h"
|
| +#include "SkGraphics.h"
|
| +#include "SkStream.h"
|
| #include "SkString.h"
|
| -#include "SkThreadUtils.h"
|
|
|
| class SkiaInstance;
|
|
|
| // Used by SkDebugf
|
| SkiaInstance* gPluginInstance;
|
|
|
| -// Main entry point for the app we're linked into
|
| -extern int tool_main(int, char**);
|
| +void FlushCallback(void* data, int32_t result);
|
|
|
| -// Tokenize a command line and store it in argc and argv.
|
| -void SkStringToProgramArgs(const SkString commandLine, int* argc, char*** argv) {
|
| - int numBreaks = 0;
|
| - const char* commandChars = commandLine.c_str();
|
| - for (int i = 0; i < strlen(commandChars); i++) {
|
| - if (isspace(commandChars[i])) {
|
| - numBreaks++;
|
| - }
|
| - }
|
| - int numArgs;
|
| - if (strlen(commandChars) > 0) {
|
| - numArgs = numBreaks + 1;
|
| - } else {
|
| - numArgs = 0;
|
| - }
|
| - *argc = numArgs;
|
| - *argv = new char*[numArgs + 1];
|
| - (*argv)[numArgs] = NULL;
|
| - char* start = (char*) commandChars;
|
| - int length = 0;
|
| - int argIndex = 0;
|
| - for (int i = 0; i < strlen(commandChars) + 1; i++) {
|
| - if (isspace(commandChars[i]) || '\0' == commandChars[i]) {
|
| - if (length > 0) {
|
| - char* argument = new char[length + 1];
|
| - memcpy(argument, start, length);
|
| - argument[length] = '\0';
|
| - (*argv)[argIndex++] = argument;
|
| - }
|
| - start = (char*) commandChars + i + 1;
|
| - length = 0;
|
| - } else {
|
| - length++;
|
| - }
|
| - }
|
| -}
|
| -
|
| -// Run the program with the given command line.
|
| -void RunProgram(const SkString& commandLine) {
|
| - int argc;
|
| - char** argv;
|
| - SkStringToProgramArgs(commandLine, &argc, &argv);
|
| - tool_main(argc, argv);
|
| -}
|
| -
|
| -
|
| // Skia's subclass of pp::Instance, our interface with the browser.
|
| class SkiaInstance : public pp::Instance {
|
| public:
|
| - explicit SkiaInstance(PP_Instance instance) : pp::Instance(instance) {
|
| + explicit SkiaInstance(PP_Instance instance)
|
| + : pp::Instance(instance)
|
| + , fBitmap()
|
| + , fCanvas(NULL)
|
| + , fDebugger()
|
| + , fImage()
|
| + , fFlushLoopRunning(false)
|
| + , fFlushPending(false)
|
| + , fPicture(NULL)
|
| + {
|
| gPluginInstance = this;
|
| + SkGraphics::Init();
|
| }
|
|
|
| virtual ~SkiaInstance() {
|
| + SkGraphics::Term();
|
| gPluginInstance = NULL;
|
| }
|
|
|
| @@ -83,12 +53,143 @@
|
| if (var_message.is_string()) {
|
| SkString msg(var_message.AsString().c_str());
|
| if (msg.startsWith("init")) {
|
| - RunProgram(msg);
|
| + } else if (msg.startsWith("LoadSKP")) {
|
| + size_t startIndex = strlen("LoadSKP");
|
| + size_t dataSize = msg.size()/sizeof(char) - startIndex;
|
| + SkBase64 decodedData;
|
| + decodedData.decode(msg.c_str() + startIndex, dataSize);
|
| + size_t decodedSize = 3 * (dataSize / 4);
|
| + SkDebugf("Got size: %d\n", decodedSize);
|
| + if (!decodedData.getData()) {
|
| + SkDebugf("Failed to decode SKP\n");
|
| + return;
|
| + }
|
| + SkMemoryStream pictureStream(decodedData.getData(), decodedSize);
|
| + fPicture = new SkPicture(&pictureStream);
|
| + if (fPicture->width() == 0 || fPicture->height() == 0) {
|
| + SkDebugf("Failed to create SKP.\n");
|
| + return;
|
| + }
|
| + fDebugger.loadPicture(fPicture);
|
| + SkTArray<SkString>* commands = fDebugger.getDrawCommandsAsStrings();
|
| + PostMessage("ClearCommands");
|
| + for (int i = 0; i < commands->count(); ++i) {
|
| + SkString message("AddCommand:");
|
| + message.append((*commands)[i]);
|
| + PostMessage(message.c_str());
|
| + }
|
| + if (!fFlushLoopRunning) {
|
| + Paint();
|
| + }
|
| + } else if (msg.startsWith("CommandSelected:")) {
|
| + size_t startIndex = strlen("CommandSelected:");
|
| + int index = atoi(msg.c_str() + startIndex);
|
| + fDebugger.setIndex(index);
|
| + if (!fFlushLoopRunning) {
|
| + Paint();
|
| + }
|
| + } else if (msg.startsWith("Rewind")) {
|
| + fCanvas->clear(SK_ColorWHITE);
|
| + fDebugger.setIndex(0);
|
| + if (!fFlushLoopRunning) {
|
| + Paint();
|
| + }
|
| + } else if (msg.startsWith("StepBack")) {
|
| + fCanvas->clear(SK_ColorWHITE);
|
| + int currentIndex = fDebugger.index();
|
| + if (currentIndex > 1) {
|
| + fDebugger.setIndex(currentIndex - 1);
|
| + if (!fFlushLoopRunning) {
|
| + Paint();
|
| + }
|
| + }
|
| + } else if (msg.startsWith("Pause")) {
|
| + // TODO(borenet)
|
| + } else if (msg.startsWith("StepForward")) {
|
| + int currentIndex = fDebugger.index();
|
| + if (currentIndex < fDebugger.getSize() -1) {
|
| + fDebugger.setIndex(currentIndex + 1);
|
| + if (!fFlushLoopRunning) {
|
| + Paint();
|
| + }
|
| + }
|
| + } else if (msg.startsWith("Play")) {
|
| + fDebugger.setIndex(fDebugger.getSize() - 1);
|
| + if (!fFlushLoopRunning) {
|
| + Paint();
|
| + }
|
| }
|
| }
|
| }
|
| +
|
| + void Paint() {
|
| + if (!fImage.is_null()) {
|
| + fDebugger.draw(fCanvas);
|
| + fDeviceContext.PaintImageData(fImage, pp::Point(0, 0));
|
| + if (!fFlushPending) {
|
| + fFlushPending = true;
|
| + fDeviceContext.Flush(pp::CompletionCallback(&FlushCallback, this));
|
| + } else {
|
| + SkDebugf("A flush is pending... Skipping flush.\n");
|
| + }
|
| + } else {
|
| + SkDebugf("No pixels to write to!\n");
|
| + }
|
| + }
|
| +
|
| + virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
|
| + if (position.size().width() == fWidth &&
|
| + position.size().height() == fHeight) {
|
| + return; // We don't care about the position, only the size.
|
| + }
|
| + fWidth = position.size().width();
|
| + fHeight = position.size().height();
|
| +
|
| + fDeviceContext = pp::Graphics2D(this, pp::Size(fWidth, fHeight), false);
|
| + if (!BindGraphics(fDeviceContext)) {
|
| + SkDebugf("Couldn't bind the device context\n");
|
| + return;
|
| + }
|
| + fImage = pp::ImageData(this,
|
| + PP_IMAGEDATAFORMAT_BGRA_PREMUL,
|
| + pp::Size(fWidth, fHeight), false);
|
| + fBitmap.setConfig(SkBitmap::kARGB_8888_Config, fWidth, fHeight);
|
| + fBitmap.setPixels(fImage.data());
|
| + if (fCanvas) {
|
| + delete fCanvas;
|
| + }
|
| + fCanvas = new SkCanvas(fBitmap);
|
| + fCanvas->clear(SK_ColorWHITE);
|
| + if (!fFlushLoopRunning) {
|
| + Paint();
|
| + }
|
| + }
|
| +
|
| + void OnFlush() {
|
| + fFlushLoopRunning = true;
|
| + fFlushPending = false;
|
| + Paint();
|
| + }
|
| +
|
| +private:
|
| + pp::Graphics2D fDeviceContext;
|
| + pp::ImageData fImage;
|
| + int fWidth;
|
| + int fHeight;
|
| +
|
| + SkBitmap fBitmap;
|
| + SkCanvas* fCanvas;
|
| + SkDebugger fDebugger;
|
| + SkPicture* fPicture;
|
| +
|
| + bool fFlushLoopRunning;
|
| + bool fFlushPending;
|
| };
|
|
|
| +void FlushCallback(void* data, int32_t result) {
|
| + static_cast<SkiaInstance*>(data)->OnFlush();
|
| +}
|
| +
|
| class SkiaModule : public pp::Module {
|
| public:
|
| SkiaModule() : pp::Module() {}
|
| @@ -104,11 +205,3 @@
|
| return new SkiaModule();
|
| }
|
| } // namespace pp
|
| -
|
| -///////////////////////////////////////////
|
| -////////////// SkThread impl //////////////
|
| -///////////////////////////////////////////
|
| -
|
| -bool SkThread::setProcessorAffinity(unsigned int processor) {
|
| - return false;
|
| -}
|
|
|