aboutsummaryrefslogtreecommitdiffhomepage
path: root/platform_tools/nacl/src
diff options
context:
space:
mode:
authorGravatar borenet@google.com <borenet@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-06 12:50:00 +0000
committerGravatar borenet@google.com <borenet@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-06 12:50:00 +0000
commit6a98b8c0b5ffe1a23902cdf7e692f702b703eaeb (patch)
tree7c5b356f6fa4fb71876465f372eedc3d3ee25801 /platform_tools/nacl/src
parentf073b3332d7c9f7dba6bcf7eb93708593a90036c (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.cpp221
-rw-r--r--platform_tools/nacl/src/nacl_interface.cpp111
-rw-r--r--platform_tools/nacl/src/nacl_sample.cpp212
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() {
+}