Browse files

Rough stab at adding NaCl target.

  • Loading branch information...
1 parent 60a7406 commit 105e5b97b037ab25294685f4dd01048579a34ef8 @joelgwebber committed Dec 9, 2011
Showing with 323 additions and 5 deletions.
  1. +1 −0 .gitignore
  2. +11 −5 c/Bench2d.cpp
  3. +94 −0 c/bench2d.html
  4. +6 −0 c/bench2d.nmf
  5. +6 −0 c/bench2d_dbg.nmf
  6. +103 −0 c/bench2d_nacl.cpp
  7. +70 −0 c/build.scons
  8. +32 −0 c/make-nacl
View
1 .gitignore
@@ -1 +1,2 @@
*.swp
+.sconsign.dblite
View
16 c/Bench2d.cpp
@@ -8,7 +8,7 @@ using namespace std;
#define FRAMES 256
const int e_count = 40;
-int main(int argc, char** argv) {
+void bench() {
// Define the gravity vector.
b2Vec2 gravity(0.0f, -10.0f);
@@ -36,17 +36,17 @@ int main(int argc, char** argv) {
for (int32 i = 0; i < e_count; ++i) {
y = x;
-
+
for (int32 j = i; j < e_count; ++j) {
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position = y;
b2Body* body = world.CreateBody(&bd);
body->CreateFixture(&shape, 5.0f);
-
+
y += deltaY;
}
-
+
x += deltaX;
}
}
@@ -67,6 +67,12 @@ int main(int argc, char** argv) {
total += times[i];
}
printf("%f\n", (float32)total / FRAMES / CLOCKS_PER_SEC * 1000);
- return 0;
}
+#if 0
+int main(int argc, char** argv) {
+ bench();
+ return 0;
+}
+#endif
+
View
94 c/bench2d.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Bench2d!</title>
+
+ <script type="text/javascript">
+ Bench2dModule = null; // Global application object.
+ statusText = 'NO-STATUS';
+
+ // Indicate load success.
+ function moduleDidLoad() {
+ Bench2dModule = document.getElementById('Bench2d');
+ updateStatus('SUCCESS');
+
+ Bench2dModule.postMessage('bench');
+ }
+
+ // The 'message' event handler. This handler is fired when the NaCl module
+ // posts a message to the browser by calling PPB_Messaging.PostMessage()
+ // (in C) or pp::Instance.PostMessage() (in C++). This implementation
+ // simply displays the content of the message in an alert panel.
+ function handleMessage(message_event) {
+ alert(message_event.data);
+ }
+
+ // If the page loads before the Native Client module loads, then set the
+ // status message indicating that the module is still loading. Otherwise,
+ // do not change the status message.
+ function pageDidLoad() {
+ if (Bench2dModule == null) {
+ updateStatus('LOADING...');
+ } else {
+ // It's possible that the Native Client module onload event fired
+ // before the page's onload event. In this case, the status message
+ // will reflect 'SUCCESS', but won't be displayed. This call will
+ // display the current message.
+ updateStatus();
+ }
+ }
+
+ // Set the global status message. If the element with id 'statusField'
+ // exists, then set its HTML to the status message as well.
+ // opt_message The message test. If this is null or undefined, then
+ // attempt to set the element with id 'statusField' to the value of
+ // |statusText|.
+ function updateStatus(opt_message) {
+ if (opt_message)
+ statusText = opt_message;
+ var statusField = document.getElementById('status_field');
+ if (statusField) {
+ statusField.innerHTML = statusText;
+ }
+ }
+ </script>
+</head>
+
+<body onload="pageDidLoad()">
+ <h1>Native Client Module Bench2d</h1>
+ <p>
+ <!-- Load the published .nexe. This includes the 'nacl' attribute which
+ shows how to load multi-architecture modules. Each entry in the "nexes"
+ object in the .nmf manifest file is a key-value pair: the key is the
+ instruction set architecture ('x86-32', 'x86-64', etc.); the value is a URL
+ for the desired NaCl module.
+ To load the debug versions of your .nexes, set the 'nacl' attribute to the
+ _dbg.nmf version of the manifest file.
+
+ Note: Since this NaCl module does not use any real-estate in the browser,
+ its width and height are set to 0.
+
+ Note: The <EMBED> element is wrapped inside a <DIV>, which has both a 'load'
+ and a 'message' event listener attached. This wrapping method is used
+ instead of attaching the event listeners directly to the <EMBED> element to
+ ensure that the listeners are active before the NaCl module 'load' event
+ fires. This also allows you to use PPB_Messaging.PostMessage() (in C) or
+ pp::Instance.PostMessage() (in C++) from within the initialization code in
+ your NaCl module.
+ -->
+ <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="Bench2d" width=0 height=0 src="bench2d.nmf" type="application/x-nacl"/>
+ </div>
+ </p>
+
+ <h2>Status</h2>
+ <div id="status_field">NO-STATUS</div>
+</body>
+</html>
+
View
6 c/bench2d.nmf
@@ -0,0 +1,6 @@
+{
+ "program": {
+ "x86-64": {"url": "bench2d_x86_64.nexe"},
+ "x86-32": {"url": "bench2d_x86_32.nexe"}
+ }
+}
View
6 c/bench2d_dbg.nmf
@@ -0,0 +1,6 @@
+{
+ "program": {
+ "x86-64": {"url": "bench2d_x86_64_dbg.nexe"},
+ "x86-32": {"url": "bench2d_x86_32_dbg.nexe"}
+ }
+}
View
103 c/bench2d_nacl.cpp
@@ -0,0 +1,103 @@
+/// @file <PROJECT_NAME>.cc
+/// This example demonstrates loading, running and scripting a very simple NaCl
+/// module. To load the NaCl module, the browser first looks for the
+/// CreateModule() factory method (at the end of this file). It calls
+/// CreateModule() once to load the module code from your .nexe. After the
+/// .nexe code is loaded, CreateModule() is not called again.
+///
+/// Once the .nexe code is loaded, the browser than calls the CreateInstance()
+/// method on the object returned by CreateModule(). It calls CreateInstance()
+/// each time it encounters an <embed> tag that references your NaCl module.
+///
+/// The browser can talk to your NaCl module via the postMessage() Javascript
+/// function. When you call postMessage() on your NaCl module from the browser,
+/// this becomes a call to the HandleMessage() method of your pp::Instance
+/// subclass. You can send messages back to the browser by calling the
+/// PostMessage() method on your pp::Instance. Note that these two methods
+/// (postMessage() in Javascript and PostMessage() in C++) are asynchronous.
+/// This means they return immediately - there is no waiting for the message
+/// to be handled. This has implications in your program design, particularly
+/// when mutating property values that are exposed to both the browser and the
+/// NaCl module.
+
+#include <cstdio>
+#include <string>
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+const char* const kBenchString = "bench";
+const char* const kReplyString = "Benchmarks complete.";
+
+void bench();
+
+/// The Instance class. One of these exists for each instance of your NaCl
+/// module on the web page. The browser will ask the Module object to create
+/// a new Instance for each occurence of the <embed> tag that has these
+/// attributes:
+/// type="application/x-nacl"
+/// src="<PROJECT_NAME>.nmf"
+/// To communicate with the browser, you must override HandleMessage() for
+/// receiving messages from the borwser, and use PostMessage() to send messages
+/// back to the browser. Note that this interface is entirely asynchronous.
+class Bench2dInstance : public pp::Instance {
+ public:
+ /// The constructor creates the plugin-side instance.
+ /// @param[in] instance the handle to the browser-side plugin instance.
+ explicit Bench2dInstance(PP_Instance instance) : pp::Instance(instance) {}
+ virtual ~Bench2dInstance() {}
+
+ /// Handler for messages coming in from the browser via postMessage(). The
+ /// @a var_message can contain anything: a JSON string; a string that encodes
+ /// method names and arguments; etc. For example, you could use
+ /// JSON.stringify in the browser to create a message that contains a method
+ /// name and some parameters, something like this:
+ /// var json_message = JSON.stringify({ "myMethod" : "3.14159" });
+ /// nacl_module.postMessage(json_message);
+ /// On receipt of this message in @a var_message, you could parse the JSON to
+ /// retrieve the method name, match it to a function call, and then call it
+ /// with the parameter.
+ /// @param[in] var_message The message posted by the browser.
+ virtual void HandleMessage(const pp::Var& var_message) {
+ if (!var_message.is_string())
+ return;
+
+ std::string message = var_message.AsString();
+ pp::Var var_reply;
+ if (message == kBenchString) {
+ bench();
+ var_reply = pp::Var(kReplyString);
+ PostMessage(var_reply);
+ }
+ }
+};
+
+/// The Module class. The browser calls the CreateInstance() method to create
+/// an instance of your NaCl module on the web page. The browser creates a new
+/// instance for each <embed> tag with type="application/x-nacl".
+class Bench2dModule : public pp::Module {
+ public:
+ Bench2dModule() : pp::Module() {}
+ virtual ~Bench2dModule() {}
+
+ /// Create and return a Bench2dInstance object.
+ /// @param[in] instance The browser-side instance.
+ /// @return the plugin-side instance.
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new Bench2dInstance(instance);
+ }
+};
+
+namespace pp {
+
+/// Factory function called by the browser when the module is first loaded.
+/// The browser keeps a singleton of this module. It calls the
+/// CreateInstance() method on the object you return to make instances. There
+/// is one instance per <embed> tag on the page. This is the main binding
+/// point for your NaCl module with the browser.
+Module* CreateModule() {
+ return new Bench2dModule();
+}
+
+} // namespace pp
+
View
70 c/build.scons
@@ -0,0 +1,70 @@
+#! -*- python -*-
+#
+# Copyright (c) 2011 The Native Client Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import make_nacl_env
+import nacl_utils
+import os
+
+nacl_env = make_nacl_env.NaClEnvironment(
+ use_c_plus_plus_libs=True,
+ nacl_platform=os.getenv('NACL_TARGET_PLATFORM')
+)
+
+nacl_env.Append(CPPPATH='Box2D_v2.2.1')
+
+sources = [
+ 'bench2d_nacl.cpp',
+
+ 'Bench2d.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/b2BroadPhase.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/b2CollideCircle.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/b2CollideEdge.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/b2CollidePolygon.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/b2Collision.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/b2Distance.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/b2DynamicTree.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/b2TimeOfImpact.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/Shapes/b2ChainShape.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/Shapes/b2CircleShape.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/Shapes/b2EdgeShape.cpp',
+ 'Box2D_v2.2.1/Box2d/Collision/Shapes/b2PolygonShape.cpp',
+ 'Box2D_v2.2.1/Box2d/Common/b2BlockAllocator.cpp',
+ 'Box2D_v2.2.1/Box2d/Common/b2Draw.cpp',
+ 'Box2D_v2.2.1/Box2d/Common/b2Math.cpp',
+ 'Box2D_v2.2.1/Box2d/Common/b2Settings.cpp',
+ 'Box2D_v2.2.1/Box2d/Common/b2StackAllocator.cpp',
+ 'Box2D_v2.2.1/Box2d/Common/b2Timer.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/b2Body.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/b2ContactManager.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/b2Fixture.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/b2Island.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/b2World.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/b2WorldCallbacks.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Contacts/b2ChainAndCircleContact.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Contacts/b2ChainAndPolygonContact.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Contacts/b2CircleContact.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Contacts/b2Contact.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Contacts/b2ContactSolver.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Contacts/b2EdgeAndCircleContact.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Contacts/b2PolygonAndCircleContact.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Contacts/b2PolygonContact.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2DistanceJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2FrictionJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2GearJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2Joint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2MouseJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2PrismaticJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2PulleyJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2RevoluteJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2RopeJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2WeldJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Dynamics/Joints/b2WheelJoint.cpp',
+ 'Box2D_v2.2.1/Box2d/Rope/b2Rope.cpp',
+]
+
+nacl_env.AllNaClModules(sources, 'bench2d')
+
View
32 c/make-nacl
@@ -0,0 +1,32 @@
+#!/bin/bash
+#
+# Copyright (c) 2011 The Native Client Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+readonly SCRIPT_DIR="$(dirname "$0")"
+readonly SCRIPT_DIR_ABS="$(cd "${SCRIPT_DIR}" ; pwd -P)"
+
+export NACL_SDK_ROOT=/opt/nacl_sdk
+# NACL_TARGET_PLATFORM is really the name of a folder with the base dir -
+# usually NACL_SDK_ROOT - within which the toolchain for the target platform
+# are found.
+# Replace the platform with the name of your target platform. For example, to
+# build applications that target the pepper_15 API, set
+# NACL_TARGET_PLATFORM="pepper_15"
+export NACL_TARGET_PLATFORM="pepper_15"
+
+readonly NACL_PLATFORM_DIR="${NACL_SDK_ROOT}/${NACL_TARGET_PLATFORM}"
+readonly BASE_SCRIPT="${NACL_PLATFORM_DIR}/third_party/scons-2.0.1/script/scons"
+
+export SCONS_LIB_DIR="${NACL_PLATFORM_DIR}/third_party/scons-2.0.1/engine"
+export PYTHONPATH="${NACL_PLATFORM_DIR}/third_party/scons-2.0.1/engine"
+# We have to do this because scons overrides PYTHONPATH and does not preserve
+# what is provided by the OS. The custom variable name won't be overwritten.
+export PYMOX="${NACL_PLATFORM_DIR}/third_party/pymox"
+
+"${BASE_SCRIPT}" --file=build.scons \
+ --site-dir="${NACL_PLATFORM_DIR}/build_tools/nacl_sdk_scons" \
+ $*
+

0 comments on commit 105e5b9

Please sign in to comment.