diff options
Diffstat (limited to 'chromium/third_party/skia/platform_tools/nacl/src/nacl_debugger.cpp')
-rw-r--r-- | chromium/third_party/skia/platform_tools/nacl/src/nacl_debugger.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/chromium/third_party/skia/platform_tools/nacl/src/nacl_debugger.cpp b/chromium/third_party/skia/platform_tools/nacl/src/nacl_debugger.cpp new file mode 100644 index 00000000000..b80dde09384 --- /dev/null +++ b/chromium/third_party/skia/platform_tools/nacl/src/nacl_debugger.cpp @@ -0,0 +1,220 @@ + +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/graphics_2d.h" +#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 "SkColor.h" +#include "SkDebugger.h" +#include "SkGraphics.h" +#include "SkStream.h" +#include "SkString.h" + +class SkiaInstance; + +// Used by SkDebugf +SkiaInstance* gPluginInstance; + +void FlushCallback(void* data, int32_t result); + +// 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) + , fCanvas(NULL) + , fFlushLoopRunning(false) + , fFlushPending(false) + + { + gPluginInstance = this; + SkGraphics::Init(); + } + + virtual ~SkiaInstance() { + SkGraphics::Term(); + gPluginInstance = NULL; + } + + virtual void HandleMessage(const pp::Var& var_message) { + // Receive a message from javascript. + if (var_message.is_string()) { + SkString msg(var_message.AsString().c_str()); + if (msg.startsWith("init")) { + } 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); + SkPicture* picture = SkPicture::CreateFromStream(&pictureStream); + if (NULL == picture) { + SkDebugf("Failed to create SKP.\n"); + return; + } + fDebugger.loadPicture(picture); + picture->unref(); + + // Set up the command list. + SkTArray<SkString>* commands = fDebugger.getDrawCommandsAsStrings(); + PostMessage("ClearCommands"); + for (int i = 0; i < commands->count(); ++i) { + SkString addCommand("AddCommand:"); + addCommand.append((*commands)[i]); + PostMessage(addCommand.c_str()); + } + PostMessage("UpdateCommands"); + + // Set the overview text. + SkString overviewText; + fDebugger.getOverviewText(NULL, 0.0, &overviewText, 1); + overviewText.prepend("SetOverview:"); + PostMessage(overviewText.c_str()); + + // Draw the SKP. + 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); + const SkImageInfo info = SkImageInfo::MakeN32Premul(fWidth, fHeight); + fBitmap.installPixels(info, fImage.data(), info.minRowBytes()); + 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; + + 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() {} + virtual ~SkiaModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new SkiaInstance(instance); + } +}; + +namespace pp { +Module* CreateModule() { + return new SkiaModule(); +} +} // namespace pp |