SkMojo: test linking Skia against the Mojo SDK
authorhalcanary <halcanary@google.com>
Wed, 3 Feb 2016 19:53:18 +0000 (11:53 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 3 Feb 2016 19:53:19 +0000 (11:53 -0800)
TODO: build on systems other than Linux.

Add mojo_skd to the DEPS.

Add a DM::Via called `mojo-`.

everything is hidden behind the gyp variable `skia_mojo`.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1644043003

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

DEPS
dm/DM.cpp
dm/DMSrcSink.cpp
dm/DMSrcSink.h
experimental/mojo/.gitignore [new file with mode: 0644]
experimental/mojo/SkMojo.mojom [new file with mode: 0644]
experimental/mojo/generate.py [new file with mode: 0755]
gyp/common_variables.gypi
gyp/dm.gypi
gyp/skmojo.gyp [new file with mode: 0644]

diff --git a/DEPS b/DEPS
index 7145953..80c6b18 100644 (file)
--- a/DEPS
+++ b/DEPS
@@ -47,6 +47,9 @@ deps = {
 
   # microhttpd for skiaserve
   "third_party/externals/microhttpd" : "https://android.googlesource.com/platform/external/libmicrohttpd@748945ec6f1c67b7efc934ab0808e1d32f2fb98d",
+
+  # Mojo SDK for Mojo RPC experiments.
+  "third_party/externals/mojo/public" : "https://chromium.googlesource.com/external/github.com/domokit/mojo_sdk@172be18ea745ab29aea132e6cb952e726dc32543",
 }
 
 recursedeps = [ "common" ]
index cdd53c6..538e2f6 100644 (file)
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -691,6 +691,7 @@ static Sink* create_via(const SkString& tag, Sink* wrapped) {
     VIA("tiles_rt",  ViaTiles, 256, 256, new SkRTreeFactory, wrapped);
     VIA("remote",       ViaRemote, false, wrapped);
     VIA("remote_cache", ViaRemote, true,  wrapped);
+    VIA("mojo",      ViaMojo,             wrapped);
 
     if (FLAGS_matrix.count() == 4) {
         SkMatrix m;
index 9712fd7..f5a00b5 100644 (file)
 #include "SkSwizzler.h"
 #include <functional>
 
+#ifdef SK_MOJO
+    #include "SkMojo.mojom.h"
+#endif
+
 DEFINE_bool(multiPage, false, "For document-type backends, render the source"
             " into multiple pages");
 
@@ -1230,6 +1234,55 @@ Error ViaTwice::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStri
 
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
+#ifdef SK_MOJO
+    Error ViaMojo::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const {
+        SkPictureRecorder recorder;
+        SkRect size = SkRect::Make(SkIRect::MakeSize(src.size()));
+        Error err = src.draw(recorder.beginRecording(size));
+        if (!err.isEmpty()) {
+            return err;
+        }
+        SkAutoTUnref<SkPicture> skPicture(recorder.endRecording());
+
+        SkASSERT(skPicture);
+        SkDynamicMemoryWStream buffer;
+        skPicture->serialize(&buffer);
+        skPicture.reset();
+        SkMojo::FlattenedPicturePtr mojoPicture = SkMojo::FlattenedPicture::New();
+        mojoPicture->data.resize(buffer.bytesWritten());
+        buffer.copyTo(mojoPicture->data.data());
+        buffer.reset();
+        SkASSERT(mojoPicture.get() && mojoPicture->data);
+
+        size_t flatSize = mojoPicture->GetSerializedSize();
+        SkAutoMalloc storage(flatSize);
+        if (!mojoPicture->Serialize(storage.get(), flatSize)) {
+            return "SkMojo::FlattenedPicture::Serialize failed";
+        }
+        mojoPicture = SkMojo::FlattenedPicture::New();
+        mojoPicture->Deserialize(storage.get());
+        storage.free();
+        if (!mojoPicture) {
+            return "SkMojo::FlattenedPicture::Deserialize failed";
+        }
+        SkMemoryStream tmpStream(mojoPicture->data.data(),
+                                 mojoPicture->data.size());
+        skPicture.reset(SkPicture::CreateFromStream(&tmpStream));
+        mojoPicture.reset();
+        auto fn = [&](SkCanvas* canvas) -> Error {
+            canvas->drawPicture(skPicture.get());
+            return check_against_reference(bitmap, src, fSink);
+        };
+        return draw_to_canvas(fSink, bitmap, stream, log, src.size(), fn);
+    }
+#else // not SK_MOJO
+    Error ViaMojo::draw(const Src&, SkBitmap*, SkWStream*, SkString*) const {
+        return "Mojo is missing!";
+    }
+#endif
+
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
 // This is like SkRecords::Draw, in that it plays back SkRecords ops into a Canvas.
 // Unlike SkRecords::Draw, it builds a single-op sub-picture out of each Draw-type op.
 // This is an only-slightly-exaggerated simluation of Blink's Slimming Paint pictures.
index a719bd1..3a7d4ee 100644 (file)
@@ -357,6 +357,12 @@ public:
     Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
 };
 
+class ViaMojo : public Via {
+public:
+    explicit ViaMojo(Sink* sink) : Via(sink) {}
+    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
+};
+
 }  // namespace DM
 
 #endif//DMSrcSink_DEFINED
diff --git a/experimental/mojo/.gitignore b/experimental/mojo/.gitignore
new file mode 100644 (file)
index 0000000..6ac4a17
--- /dev/null
@@ -0,0 +1,6 @@
+*.mojom-*
+*.mojom.*
+*_mojom.*
+dart-gen
+go
+
diff --git a/experimental/mojo/SkMojo.mojom b/experimental/mojo/SkMojo.mojom
new file mode 100644 (file)
index 0000000..85b46cc
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+module SkMojo;
+
+struct FlattenedPicture { array<uint8> data; };
diff --git a/experimental/mojo/generate.py b/experimental/mojo/generate.py
new file mode 100755 (executable)
index 0000000..a32afbb
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+
+# Copyright 2016 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import hashlib
+import os
+import subprocess
+import urllib2
+import stat
+
+THIS_DIR = os.path.abspath(os.path.dirname(__file__))
+MOJO_DIR = os.path.abspath(os.path.join(THIS_DIR, '../../third_party/externals/mojo'))
+
+def GetFile(filename, bucket_directory):
+    def sha1hash(path):
+        hasher = hashlib.sha1()
+        if os.path.isfile(path):
+            with open(path, 'r') as f:
+                hasher.update(f.read())
+        return hasher.hexdigest()
+    sha_path = filename + '.sha1'
+    assert os.path.isfile(sha_path)
+    with open(sha_path, 'r') as f:
+        sha = f.read(40)
+    if sha1hash(filename) == sha:
+        return
+    url = 'https://storage.googleapis.com/%s/%s' % (bucket_directory, sha)
+    with open(filename, 'w') as o:
+        o.write(urllib2.urlopen(url).read())
+    os.chmod(filename, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH |
+                       stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
+    assert sha1hash(filename) == sha
+
+def GenerateBindings(path, cdir=None):
+    GetFile(os.path.join(MOJO_DIR,
+                         'public/tools/bindings/mojom_parser/bin/linux64/mojom_parser'),
+            'mojo/mojom_parser/linux64')
+    assert os.path.isfile(path)
+    path = os.path.abspath(path)
+    exe = os.path.join(
+        MOJO_DIR, 'public/tools/bindings/mojom_bindings_generator.py')
+    assert os.path.isfile(exe)
+    if cdir is None:
+        cdir = os.path.dirname(path)
+    assert os.path.isdir(cdir)
+    cwd = os.getcwd()
+    os.chdir(cdir)
+    subprocess.check_call([exe, os.path.relpath(path, cdir)])
+    os.chdir(cwd)
+
+for f in [
+    'public/interfaces/bindings/interface_control_messages.mojom',
+    'public/interfaces/application/service_provider.mojom',
+    'public/interfaces/bindings/tests/ping_service.mojom',
+    'public/interfaces/application/application.mojom',
+    ]:
+    GenerateBindings(os.path.join(MOJO_DIR, f), os.path.join(MOJO_DIR, os.pardir))
+
+GenerateBindings(os.path.join(THIS_DIR, 'SkMojo.mojom'))
index 7cf9660..ba4d203 100644 (file)
@@ -38,6 +38,8 @@
   'variables': {  # level 1
     'angle_path%': '../',
 
+    'skia_mojo%': '0',
+
     'variables': {  # level 2
 
       # Variables needed by conditions list within the level-2 variables dict.
index bb21923..2fda486 100644 (file)
@@ -51,5 +51,6 @@
     [ 'skia_gpu == 1', {
       'dependencies': [ 'gputest.gyp:skgputest' ],
     }],
+    [ 'skia_mojo', { 'dependencies': [ 'skmojo.gyp:skmojo' ], } ],
   ],
 }
diff --git a/gyp/skmojo.gyp b/gyp/skmojo.gyp
new file mode 100644 (file)
index 0000000..63385cd
--- /dev/null
@@ -0,0 +1,59 @@
+# Copyright 2016 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+{
+  'targets': [
+    {
+      'target_name': 'mojo',
+      'type': 'static_library',
+      'variables': { 'mojo_parent_dir': '../third_party/externals' },
+      'include_dirs': [ '<(mojo_parent_dir)' ],
+      'all_dependent_settings': { 'include_dirs': [ '<(mojo_parent_dir)' ] },
+      'sources': [
+        '<!@(python find.py <(mojo_parent_dir)/mojo/public/cpp "*.cc")',
+        '<(mojo_parent_dir)/mojo/public/platform/native/system_thunks.c',
+      ],
+      'sources!': [
+        '<!@(python find.py <(mojo_parent_dir)/mojo/public/cpp "*_unittest.cc")',
+        '<!@(python find.py <(mojo_parent_dir)/mojo/public/cpp "*_perftest.cc")',
+        '<!@(python find.py <(mojo_parent_dir)/mojo/public/cpp "*_apptest.cc")',
+        '<!@(python find.py <(mojo_parent_dir)/mojo/public/cpp "*_test_*.cc")',
+        '<!@(python find.py <(mojo_parent_dir)/mojo/public/cpp "*_win.cc")',
+      ],
+    },
+    {
+      'target_name': 'skmojo',
+      'type': 'static_library',
+      'variables': {
+        'mojo_dir': '../third_party/externals/mojo/public'
+      },
+      'dependencies': [ 'mojo' ],
+      'defines': [ 'SK_MOJO' ],
+      'sources': [ '../experimental/mojo/SkMojo.mojom.cc', ],
+      'include_dirs': [ '../experimental/mojo', ],
+      'all_dependent_settings': {
+        'include_dirs': [ '../experimental/mojo' ],
+        'defines': [ 'SK_MOJO' ],
+      },
+      'actions':[
+        {
+          'action_name': 'generate_from_mojoms',
+          'inputs': [
+            '../experimental/mojo/generate.py',
+            '../experimental/mojo/SkMojo.mojom',
+            '<(mojo_dir)/tools/bindings/mojom_parser/bin/linux64/mojom_parser.sha1',
+            '<(mojo_dir)/tools/bindings/mojom_bindings_generator.py',
+            '<(mojo_dir)/interfaces/bindings/interface_control_messages.mojom',
+            '<(mojo_dir)/interfaces/application/service_provider.mojom',
+            '<(mojo_dir)/interfaces/bindings/tests/ping_service.mojom',
+            '<(mojo_dir)/interfaces/application/application.mojom',
+          ],
+          'outputs': ['../experimental/mojo/SkMojo.mojom.h',
+                      '../experimental/mojo/SkMojo.mojom.cc'],
+          'action': ['python', '../experimental/mojo/generate.py']
+        },
+      ],
+    },
+  ],
+}