SkHello for NaCl
authorborenet@google.com <borenet@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 17 Jun 2013 15:39:43 +0000 (15:39 +0000)
committerborenet@google.com <borenet@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 17 Jun 2013 15:39:43 +0000 (15:39 +0000)
Not ready to submit.

R=reed@google.com

Review URL: https://codereview.chromium.org/16904003

git-svn-id: http://skia.googlecode.com/svn/trunk@9639 2bbb7eff-a529-9590-31e7-b0007b416f81

Makefile
gyp/tools.gyp
platform_tools/nacl/index.html
platform_tools/nacl/skhello/index.html [new file with mode: 0644]
platform_tools/nacl/skhello/skhello.nmf [new file with mode: 0644]
platform_tools/nacl/src/nacl_hello.cpp [new file with mode: 0644]

index 0bb3b70..d8b0205 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,7 @@ VALID_TARGETS := \
                  pathops_unittest \
                  pdfviewer \
                  SampleApp \
+                 skhello \
                  SkiaAndroidApp \
                  skia_lib \
                  tests \
index 2b0550a..d960cdc 100644 (file)
     {
       'target_name': 'skhello',
       'type': 'executable',
-      'sources': [
-        '../tools/skhello.cpp',
-      ],
       'dependencies': [
         'skia_lib.gyp:skia_lib',
-        'pdf.gyp:pdf',
-        'flags.gyp:flags',
+      ],
+      'conditions': [
+        [ 'skia_os == "nacl"', {
+          'sources': [
+            '../platform_tools/nacl/src/nacl_hello.cpp',
+          ],
+        }, {
+          'sources': [
+            '../tools/skhello.cpp',
+          ],
+          'dependencies': [
+            'pdf.gyp:pdf',
+            'flags.gyp:flags',
+          ],
+        }],
       ],
     },
     {
index abe5d1e..4d87f3e 100644 (file)
@@ -13,6 +13,7 @@
   <h1>Skia Native Client Apps</h1>
   <p>
     <ul>
+      <li><a href="skhello">Skia Hello World</a></li>
       <li><a href="tests">Skia Unit Tests</a></li>
       <li><a href="debugger">Skia Debugger</a></li>
       <li><a href="SampleApp">Skia Sample App</a></li>
diff --git a/platform_tools/nacl/skhello/index.html b/platform_tools/nacl/skhello/index.html
new file mode 100644 (file)
index 0000000..4119aed
--- /dev/null
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+  <!--
+  Copyright 2013 Google Inc.
+
+  Use of this source code is governed by a BSD-style license that can be
+  found in the LICENSE file.
+  -->
+<head>
+
+  <title>Skia Hello World</title>
+
+  <script type="text/javascript">
+    "use strict";
+
+    var SkiaModule = null;  // Global application object.
+
+    // Force a re-draw of the given element.
+    function refresh(elem) {
+      var old_display_style = elem.style.display;
+      elem.style.display = "none";
+      elem.style.display = old_display_style;
+    }
+
+    // When the module loads, begin running the application.
+    function moduleDidLoad() {
+      SkiaModule = document.getElementById("skia_nacl");
+      run();
+    }
+
+    function handleMessage(message_event) {
+      var skdebugf_cmd = "SkDebugf:";
+      if (message_event.data.indexOf(skdebugf_cmd) == 0) {
+        var msg_contents = message_event.data.slice(skdebugf_cmd.length)
+        console.log("Skia: " + msg_contents);
+      } else {
+        alert(message_event.data);
+      }
+    }
+
+    // Run the application.
+    function run() {
+      if (SkiaModule) {
+        var cmd = "init";
+        SkiaModule.postMessage(cmd);
+      } else {
+        alert("The Skia module has not properly loaded...");
+      }
+    }
+  </script>
+</head>
+<body>
+
+<h1>Skia Hello World</h1>
+<p>
+  <div id="listener">
+    <script type="text/javascript">
+      var listener = document.getElementById('listener');
+      listener.addEventListener('load', moduleDidLoad, true);
+      listener.addEventListener('message', handleMessage, true);
+    </script>
+
+    <embed name="nacl_module"
+       id="skia_nacl"
+       width=300 height=300
+       src="skhello.nmf"
+       type="application/x-nacl" />
+  </div>
+</p>
+</body>
+</html>
diff --git a/platform_tools/nacl/skhello/skhello.nmf b/platform_tools/nacl/skhello/skhello.nmf
new file mode 100644 (file)
index 0000000..3d6c02d
--- /dev/null
@@ -0,0 +1,6 @@
+{
+  "program": {
+    "x86-64": {"url": "../../out/nacl64/Debug/skhello"},
+    "x86-32": {"url": "../../out/nacl32/Debug/skhello"}
+  }
+}
diff --git a/platform_tools/nacl/src/nacl_hello.cpp b/platform_tools/nacl/src/nacl_hello.cpp
new file mode 100644 (file)
index 0000000..a091ab4
--- /dev/null
@@ -0,0 +1,150 @@
+
+/*
+ * 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 "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkColor.h"
+#include "SkGraphics.h"
+#include "SkStream.h"
+#include "SkString.h"
+
+class SkiaInstance;
+
+// Used by SkDebugf
+SkiaInstance* gPluginInstance;
+
+void FlushCallback(void* data, int32_t result);
+
+static void doDraw(SkCanvas* canvas, const SkPaint& paint, const char text[]) {
+    canvas->drawColor(SK_ColorWHITE);
+    SkPaint red;
+    red.setColor(SK_ColorRED);
+    canvas->drawCircle(150.0, 150.0, 100.0, red);
+    SkRect bounds;
+    canvas->getClipBounds(&bounds);
+    canvas->drawText(text, strlen(text),
+                     bounds.centerX(), bounds.centerY(),
+                     paint);
+}
+
+// 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.
+    }
+
+    void Paint() {
+        if (!fImage.is_null()) {
+            SkPaint paint;
+            paint.setAntiAlias(true);
+            paint.setTextSize(SkIntToScalar(30));
+            paint.setTextAlign(SkPaint::kCenter_Align);
+            doDraw(fCanvas, paint, "Hello");
+
+            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;
+
+    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