diff options
author | borenet@google.com <borenet@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-06 12:50:00 +0000 |
---|---|---|
committer | borenet@google.com <borenet@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-06 12:50:00 +0000 |
commit | 6a98b8c0b5ffe1a23902cdf7e692f702b703eaeb (patch) | |
tree | 7c5b356f6fa4fb71876465f372eedc3d3ee25801 /platform_tools/nacl/src | |
parent | f073b3332d7c9f7dba6bcf7eb93708593a90036c (diff) |
Copy NaCl directory into trunk/platform_tools, adjust paths
(SkipBuildbotRuns)
R=djsollen@google.com
Review URL: https://codereview.chromium.org/14771017
git-svn-id: http://skia.googlecode.com/svn/trunk@9008 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'platform_tools/nacl/src')
-rw-r--r-- | platform_tools/nacl/src/nacl_debugger.cpp | 221 | ||||
-rw-r--r-- | platform_tools/nacl/src/nacl_interface.cpp | 111 | ||||
-rw-r--r-- | platform_tools/nacl/src/nacl_sample.cpp | 212 |
3 files changed, 544 insertions, 0 deletions
diff --git a/platform_tools/nacl/src/nacl_debugger.cpp b/platform_tools/nacl/src/nacl_debugger.cpp new file mode 100644 index 0000000000..26e3ed67c7 --- /dev/null +++ b/platform_tools/nacl/src/nacl_debugger.cpp @@ -0,0 +1,221 @@ + +/* + * 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) + , fPicture(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); + fPicture = new SkPicture(&pictureStream); + if (fPicture->width() == 0 || fPicture->height() == 0) { + SkDebugf("Failed to create SKP.\n"); + return; + } + fDebugger.loadPicture(fPicture); + + // 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); + 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() {} + virtual ~SkiaModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new SkiaInstance(instance); + } +}; + +namespace pp { +Module* CreateModule() { + return new SkiaModule(); +} +} // namespace pp diff --git a/platform_tools/nacl/src/nacl_interface.cpp b/platform_tools/nacl/src/nacl_interface.cpp new file mode 100644 index 0000000000..09d55c3fec --- /dev/null +++ b/platform_tools/nacl/src/nacl_interface.cpp @@ -0,0 +1,111 @@ + +/* + * 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/var.h" + +#include "SkCanvas.h" +#include "SkBitmap.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**); + +// 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 (size_t 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 (size_t 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) { + gPluginInstance = this; + } + + virtual ~SkiaInstance() { + 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")) { + RunProgram(msg); + } + } + } +}; + +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 diff --git a/platform_tools/nacl/src/nacl_sample.cpp b/platform_tools/nacl/src/nacl_sample.cpp new file mode 100644 index 0000000000..aca74f4247 --- /dev/null +++ b/platform_tools/nacl/src/nacl_sample.cpp @@ -0,0 +1,212 @@ +#include <cstdio> +#include <string> + +#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/var.h" + +#include "SampleApp.h" +#include "SkApplication.h" +#include "SkCanvas.h" +#include "SkBitmap.h" +#include "SkEvent.h" +#include "SkWindow.h" + +class SkiaInstance; + +namespace { +void FlushCallback(void* data, int32_t result); +} + +SkiaInstance* gPluginInstance; +extern int main(int, char**); + +class SkiaInstance : public pp::Instance { + public: + explicit SkiaInstance(PP_Instance instance) : pp::Instance(instance), + fFlushPending(false), + fGraphics2dContext(NULL), + fPixelBuffer(NULL) + { + gPluginInstance = this; + application_init(); + char* commandName = "SampleApp"; + fWindow = new SampleWindow(NULL, 0, &commandName, NULL); + } + + virtual ~SkiaInstance() { + gPluginInstance = NULL; + delete fWindow; + application_term(); + } + + virtual void HandleMessage(const pp::Var& var_message) { + // Receive a message from javascript. Right now this just signals us to + // get started. + uint32_t width = 500; + uint32_t height = 500; + char buffer[2048]; + sprintf(buffer, "SetSize:%d,%d", width, height); + PostMessage(buffer); + } + + virtual void DidChangeView(const pp::Rect& position, + const pp::Rect& clip) { + if (position.size().width() == width() && + position.size().height() == height()) { + return; // Size didn't change, no need to update anything. + } + // Create a new device context with the new size. + DestroyContext(); + CreateContext(position.size()); + // Delete the old pixel buffer and create a new one. + delete fPixelBuffer; + fPixelBuffer = NULL; + if (fGraphics2dContext != NULL) { + fPixelBuffer = new pp::ImageData(this, + PP_IMAGEDATAFORMAT_BGRA_PREMUL, + fGraphics2dContext->size(), + false); + fWindow->resize(position.size().width(), position.size().height()); + fWindow->update(NULL); + paint(); + } + } + + // Indicate whether a flush is pending. This can only be called from the + // main thread; it is not thread safe. + bool flush_pending() const { + return fFlushPending; + } + void set_flush_pending(bool flag) { + fFlushPending = flag; + } + + void paint() { + if (fPixelBuffer) { + // Draw some stuff. TODO(borenet): Actually have SampleApp draw into + // the plugin area. + uint32_t w = fPixelBuffer->size().width(); + uint32_t h = fPixelBuffer->size().height(); + uint32_t* data = (uint32_t*) fPixelBuffer->data(); + // Create a bitmap using the fPixelBuffer pixels + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h); + bitmap.setPixels(data); + // Create a canvas with the bitmap as the backend + SkCanvas canvas(bitmap); + + canvas.drawColor(SK_ColorBLUE); + SkRect rect = SkRect::MakeXYWH(10, 10, 80, 80); + SkPaint rect_paint; + rect_paint.setStyle(SkPaint::kFill_Style); + rect_paint.setColor(SK_ColorRED); + canvas.drawRect(rect, rect_paint); + + FlushPixelBuffer(); + } + } + +private: + int width() const { + return fPixelBuffer ? fPixelBuffer->size().width() : 0; + } + + int height() const { + return fPixelBuffer ? fPixelBuffer->size().height() : 0; + } + + bool IsContextValid() const { + return fGraphics2dContext != NULL; + } + + void CreateContext(const pp::Size& size) { + if (IsContextValid()) + return; + fGraphics2dContext = new pp::Graphics2D(this, size, false); + if (!BindGraphics(*fGraphics2dContext)) { + SkDebugf("Couldn't bind the device context"); + } + } + + void DestroyContext() { + if (!IsContextValid()) + return; + delete fGraphics2dContext; + fGraphics2dContext = NULL; + } + + void FlushPixelBuffer() { + if (!IsContextValid()) + return; + // Note that the pixel lock is held while the buffer is copied into the + // device context and then flushed. + fGraphics2dContext->PaintImageData(*fPixelBuffer, pp::Point()); + if (flush_pending()) + return; + set_flush_pending(true); + fGraphics2dContext->Flush(pp::CompletionCallback(&FlushCallback, this)); + } + + bool fFlushPending; + pp::Graphics2D* fGraphics2dContext; + pp::ImageData* fPixelBuffer; + SampleWindow* fWindow; +}; + +class SkiaModule : public pp::Module { +public: + SkiaModule() : pp::Module() {} + virtual ~SkiaModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance) { + gPluginInstance = new SkiaInstance(instance); + return gPluginInstance; + } +}; + +namespace { +void FlushCallback(void* data, int32_t result) { + static_cast<SkiaInstance*>(data)->set_flush_pending(false); +} +} + +namespace pp { +Module* CreateModule() { + return new SkiaModule(); +} +} // namespace pp + + +/////////////////////////////////////////// +///////////// SkOSWindow impl ///////////// +/////////////////////////////////////////// + +void SkOSWindow::onSetTitle(const char title[]) +{ + char buffer[2048]; + sprintf(buffer, "SetTitle:%s", title); + gPluginInstance->PostMessage(buffer); +} + +void SkOSWindow::onHandleInval(const SkIRect& rect) +{ + gPluginInstance->paint(); +} + +void SkOSWindow::onPDFSaved(const char title[], const char desc[], + const char path[]) { +} + +/////////////////////////////////////////// +/////////////// SkEvent impl ////////////// +/////////////////////////////////////////// + +void SkEvent::SignalQueueTimer(SkMSec ms) { +} + +void SkEvent::SignalNonEmptyQueue() { +} |