summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gin/arguments.cc6
-rw-r--r--gin/arguments.h6
-rw-r--r--gin/handle.h9
-rw-r--r--mojo/apps/js/bindings/gl/context.cc80
-rw-r--r--mojo/apps/js/bindings/gl/context.h52
-rw-r--r--mojo/apps/js/bindings/gl/module.cc54
-rw-r--r--mojo/apps/js/bindings/gl/module.h22
-rw-r--r--mojo/apps/js/bindings/gl/opaque.cc37
-rw-r--r--mojo/apps/js/bindings/gl/opaque.h41
-rw-r--r--mojo/apps/js/bindings/threading.cc5
-rw-r--r--mojo/apps/js/bindings/threading.h4
-rw-r--r--mojo/apps/js/main.js31
-rw-r--r--mojo/apps/js/mojo_runner_delegate.cc4
-rw-r--r--mojo/mojo_apps.gypi8
14 files changed, 339 insertions, 20 deletions
diff --git a/gin/arguments.cc b/gin/arguments.cc
index ee57897..c43ff28 100644
--- a/gin/arguments.cc
+++ b/gin/arguments.cc
@@ -26,13 +26,13 @@ Arguments::Arguments(const v8::FunctionCallbackInfo<v8::Value>& info)
Arguments::~Arguments() {
}
-v8::Handle<v8::Value> Arguments::PeekNext() {
+v8::Handle<v8::Value> Arguments::PeekNext() const {
if (next_ >= info_->Length())
return v8::Handle<v8::Value>();
return (*info_)[next_];
}
-void Arguments::ThrowError() {
+void Arguments::ThrowError() const {
if (insufficient_arguments_)
return ThrowTypeError("Insufficient number of arguments.");
@@ -40,7 +40,7 @@ void Arguments::ThrowError() {
"Error processing argument %d.", next_ - 1));
}
-void Arguments::ThrowTypeError(const std::string& message) {
+void Arguments::ThrowTypeError(const std::string& message) const {
isolate_->ThrowException(v8::Exception::TypeError(
StringToV8(isolate_, message)));
}
diff --git a/gin/arguments.h b/gin/arguments.h
index 104152a..ec4ae80 100644
--- a/gin/arguments.h
+++ b/gin/arguments.h
@@ -61,10 +61,10 @@ class GIN_EXPORT Arguments {
info_->GetReturnValue().Set(ConvertToV8(isolate_, val));
}
- v8::Handle<v8::Value> PeekNext();
+ v8::Handle<v8::Value> PeekNext() const;
- void ThrowError();
- void ThrowTypeError(const std::string& message);
+ void ThrowError() const;
+ void ThrowTypeError(const std::string& message) const;
v8::Isolate* isolate() const { return isolate_; }
diff --git a/gin/handle.h b/gin/handle.h
index 7178bb37..da1de34 100644
--- a/gin/handle.h
+++ b/gin/handle.h
@@ -31,7 +31,7 @@ class Handle {
}
T* operator->() const { return object_; }
- v8::Handle<v8::Value> ToV8() { return wrapper_; }
+ v8::Handle<v8::Value> ToV8() const { return wrapper_; }
T* get() const { return object_; }
private:
@@ -48,8 +48,11 @@ struct Converter<gin::Handle<T> > {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
gin::Handle<T>* out) {
T* object = NULL;
- Converter<T*>::FromV8(isolate, val, &object);
- return gin::Handle<T>(val, object);
+ if (!Converter<T*>::FromV8(isolate, val, &object)) {
+ return false;
+ }
+ *out = gin::Handle<T>(val, object);
+ return true;
}
};
diff --git a/mojo/apps/js/bindings/gl/context.cc b/mojo/apps/js/bindings/gl/context.cc
new file mode 100644
index 0000000..27622a7
--- /dev/null
+++ b/mojo/apps/js/bindings/gl/context.cc
@@ -0,0 +1,80 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/apps/js/bindings/gl/context.h"
+
+#include <GLES2/gl2.h>
+
+#include "gin/arguments.h"
+#include "gin/object_template_builder.h"
+#include "gin/per_isolate_data.h"
+#include "mojo/public/gles2/gles2.h"
+
+namespace mojo {
+namespace js {
+namespace gl {
+
+gin::WrapperInfo Context::kWrapperInfo = { gin::kEmbedderNativeGin };
+
+gin::Handle<Context> Context::Create(v8::Isolate* isolate, uint64_t encoded,
+ int width, int height) {
+ return gin::CreateHandle(isolate, new Context(encoded, width, height));
+}
+
+v8::Handle<v8::ObjectTemplate> Context::GetObjectTemplate(
+ v8::Isolate* isolate) {
+ gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
+ v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(&kWrapperInfo);
+ if (templ.IsEmpty()) {
+ templ = gin::ObjectTemplateBuilder(isolate)
+ .SetValue("VERTEX_SHADER", GL_VERTEX_SHADER)
+ .SetMethod("createShader", CreateShader)
+ .SetMethod("shaderSource", ShaderSource)
+ .SetMethod("compileShader", CompileShader)
+ .Build();
+ templ->SetInternalFieldCount(gin::kNumberOfInternalFields);
+ data->SetObjectTemplate(&kWrapperInfo, templ);
+ }
+ return templ;
+}
+
+gin::Handle<Shader> Context::CreateShader(const gin::Arguments& args,
+ GLenum type) {
+ gin::Handle<Shader> result;
+ GLuint glshader = glCreateShader(type);
+ if (glshader != 0u) {
+ result = Opaque::Create(args.isolate(), glshader);
+ }
+ return result;
+}
+
+void Context::ShaderSource(gin::Handle<Shader> shader,
+ const std::string& source) {
+ const char* source_chars = source.c_str();
+ glShaderSource(shader->value(), 1, &source_chars, NULL);
+}
+
+void Context::CompileShader(const gin::Arguments& args,
+ gin::Handle<Shader> shader) {
+ glCompileShader(shader->value());
+ GLint compiled = 0;
+ glGetShaderiv(shader->value(), GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ // Or should |shader| do it when it is destroyed?
+ glDeleteShader(shader->value());
+ args.ThrowTypeError("Could not compile shader");
+ return;
+ }
+}
+
+Context::Context(uint64_t encoded, int width, int height)
+ : encoded_(encoded) {
+ // TODO(aa): When we want to support multiple contexts, we should add
+ // Context::MakeCurrent() for developers to switch between them.
+ MojoGLES2MakeCurrent(encoded_);
+}
+
+} // namespace gl
+} // namespace js
+} // namespace mojo
diff --git a/mojo/apps/js/bindings/gl/context.h b/mojo/apps/js/bindings/gl/context.h
new file mode 100644
index 0000000..40203c3
--- /dev/null
+++ b/mojo/apps/js/bindings/gl/context.h
@@ -0,0 +1,52 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_APPS_JS_BINDINGS_GL_CONTEXT_H_
+#define MOJO_APPS_JS_BINDINGS_GL_CONTEXT_H_
+
+#include <GLES2/gl2.h>
+
+#include "gin/handle.h"
+#include "gin/public/wrapper_info.h"
+#include "gin/wrappable.h"
+#include "mojo/apps/js/bindings/gl/opaque.h"
+#include "v8/include/v8.h"
+
+namespace gin {
+class Arguments;
+}
+
+namespace mojo {
+namespace js {
+namespace gl {
+
+typedef Opaque Shader;
+
+// Context implements WebGLRenderingContext.
+class Context : public gin::Wrappable<Context> {
+ public:
+ static gin::WrapperInfo kWrapperInfo;
+
+ static gin::Handle<Context> Create(v8::Isolate* isolate, uint64_t encoded,
+ int width, int height);
+ static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
+
+ static gin::Handle<Shader> CreateShader(const gin::Arguments& arguments,
+ GLenum type);
+ static void ShaderSource(gin::Handle<Shader> shader,
+ const std::string& source);
+ static void CompileShader(const gin::Arguments& arguments,
+ gin::Handle<Shader> shader);
+
+ private:
+ Context(uint64_t encoded, int width, int height);
+
+ uint64_t encoded_;
+};
+
+} // namespace gl
+} // namespace js
+} // namespace mojo
+
+#endif // MOJO_APPS_JS_BINDINGS_GL_CONTEXT_H_
diff --git a/mojo/apps/js/bindings/gl/module.cc b/mojo/apps/js/bindings/gl/module.cc
new file mode 100644
index 0000000..abc0706
--- /dev/null
+++ b/mojo/apps/js/bindings/gl/module.cc
@@ -0,0 +1,54 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/apps/js/bindings/gl/module.h"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include "base/logging.h"
+#include "gin/arguments.h"
+#include "gin/object_template_builder.h"
+#include "gin/per_isolate_data.h"
+#include "gin/wrappable.h"
+#include "mojo/apps/js/bindings/gl/context.h"
+
+namespace mojo {
+namespace js {
+namespace gl {
+
+const char* kModuleName = "mojo/apps/js/bindings/gl";
+
+namespace {
+
+gin::WrapperInfo kWrapperInfo = { gin::kEmbedderNativeGin };
+
+gin::Handle<Context> CreateContext(const gin::Arguments& args, uint64_t encoded,
+ int width, int height) {
+ return Context::Create(args.isolate(), encoded, width, height);
+}
+
+} // namespace
+
+v8::Local<v8::ObjectTemplate> GetModuleTemplate(v8::Isolate* isolate) {
+ gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
+ v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(&kWrapperInfo);
+
+ if (templ.IsEmpty()) {
+ templ = gin::ObjectTemplateBuilder(isolate)
+ .SetMethod("Context", CreateContext)
+ .Build();
+ templ->SetInternalFieldCount(gin::kNumberOfInternalFields);
+ data->SetObjectTemplate(&kWrapperInfo, templ);
+ }
+
+ Context::GetObjectTemplate(isolate);
+ Opaque::GetObjectTemplate(isolate);
+
+ return templ;
+}
+
+} // namespace gl
+} // namespace js
+} // namespace mojo
diff --git a/mojo/apps/js/bindings/gl/module.h b/mojo/apps/js/bindings/gl/module.h
new file mode 100644
index 0000000..9b32ad4
--- /dev/null
+++ b/mojo/apps/js/bindings/gl/module.h
@@ -0,0 +1,22 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_APPS_JS_BINDINGS_GL_MODULE_H_
+#define MOJO_APPS_JS_BINDINGS_GL_MODULE_H_
+
+#include "gin/public/wrapper_info.h"
+#include "v8/include/v8.h"
+
+namespace mojo {
+namespace js {
+namespace gl {
+
+extern const char* kModuleName;
+v8::Local<v8::ObjectTemplate> GetModuleTemplate(v8::Isolate* isolate);
+
+} // namespace gl
+} // namespace js
+} // namespace mojo
+
+#endif // MOJO_APPS_JS_BINDINGS_GL_H_
diff --git a/mojo/apps/js/bindings/gl/opaque.cc b/mojo/apps/js/bindings/gl/opaque.cc
new file mode 100644
index 0000000..8f45f48
--- /dev/null
+++ b/mojo/apps/js/bindings/gl/opaque.cc
@@ -0,0 +1,37 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/apps/js/bindings/gl/opaque.h"
+
+#include "gin/object_template_builder.h"
+#include "gin/per_isolate_data.h"
+
+namespace mojo {
+namespace js {
+namespace gl {
+
+gin::WrapperInfo Opaque::kWrapperInfo = { gin::kEmbedderNativeGin };
+
+gin::Handle<Opaque> Opaque::Create(v8::Isolate* isolate, GLuint value) {
+ return gin::CreateHandle(isolate, new Opaque(value));
+}
+
+v8::Handle<v8::ObjectTemplate> Opaque::GetObjectTemplate(v8::Isolate* isolate) {
+ gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
+ v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(&kWrapperInfo);
+ if (templ.IsEmpty()) {
+ templ = gin::ObjectTemplateBuilder(isolate)
+ .Build();
+ templ->SetInternalFieldCount(gin::kNumberOfInternalFields);
+ data->SetObjectTemplate(&kWrapperInfo, templ);
+ }
+ return templ;
+}
+
+Opaque::Opaque(GLuint value) : value_(value) {
+}
+
+} // namespace gl
+} // namespace js
+} // namespace mojo
diff --git a/mojo/apps/js/bindings/gl/opaque.h b/mojo/apps/js/bindings/gl/opaque.h
new file mode 100644
index 0000000..10df134
--- /dev/null
+++ b/mojo/apps/js/bindings/gl/opaque.h
@@ -0,0 +1,41 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_APPS_JS_BINDINGS_GL_OPAQUE_H_
+#define MOJO_APPS_JS_BINDINGS_GL_OPAQUE_H_
+
+#include <GLES2/gl2.h>
+
+#include "gin/handle.h"
+#include "gin/public/wrapper_info.h"
+#include "gin/wrappable.h"
+#include "v8/include/v8.h"
+
+namespace mojo {
+namespace js {
+namespace gl {
+
+// WebGL has many interfaces, such as WebGLObject, WebGLBuffer, etc, which wrap
+// integers that are opaque to script. This class is used for all those objects.
+class Opaque : public gin::Wrappable<Opaque> {
+ public:
+ static gin::WrapperInfo kWrapperInfo;
+
+ static gin::Handle<Opaque> Create(v8::Isolate* isolate, GLuint value);
+ static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
+
+ GLuint value() const { return value_; }
+ void set_value(GLuint val) { value_ = val; }
+
+ private:
+ Opaque(GLuint value);
+
+ GLuint value_;
+};
+
+} // namespace gl
+} // namespace js
+} // namespace mojo
+
+#endif // MOJO_APPS_JS_BINDINGS_GL_CONTEXT_H_
diff --git a/mojo/apps/js/bindings/threading.cc b/mojo/apps/js/bindings/threading.cc
index b704ac8..86d0d78 100644
--- a/mojo/apps/js/bindings/threading.cc
+++ b/mojo/apps/js/bindings/threading.cc
@@ -4,9 +4,7 @@
#include "mojo/apps/js/bindings/threading.h"
-#include "base/bind.h"
#include "base/message_loop/message_loop.h"
-#include "gin/function_template.h"
#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
#include "mojo/apps/js/bindings/handle.h"
@@ -42,5 +40,8 @@ v8::Local<v8::ObjectTemplate> Threading::GetTemplate(v8::Isolate* isolate) {
return templ;
}
+Threading::Threading() {
+}
+
} // namespace apps
} // namespace mojo
diff --git a/mojo/apps/js/bindings/threading.h b/mojo/apps/js/bindings/threading.h
index 56905ce..74ea8c2 100644
--- a/mojo/apps/js/bindings/threading.h
+++ b/mojo/apps/js/bindings/threading.h
@@ -5,7 +5,7 @@
#ifndef MOJO_APPS_JS_BINDINGS_THREADING_H_
#define MOJO_APPS_JS_BINDINGS_THREADING_H_
-#include "mojo/public/system/core.h"
+#include "gin/public/wrapper_info.h"
#include "v8/include/v8.h"
namespace mojo {
@@ -15,6 +15,8 @@ class Threading {
public:
static const char kModuleName[];
static v8::Local<v8::ObjectTemplate> GetTemplate(v8::Isolate* isolate);
+ private:
+ Threading();
};
} // namespace apps
diff --git a/mojo/apps/js/main.js b/mojo/apps/js/main.js
index 1dd5ff8..88115ff 100644
--- a/mojo/apps/js/main.js
+++ b/mojo/apps/js/main.js
@@ -6,19 +6,33 @@ define([
"console",
"mojo/apps/js/bindings/connector",
"mojo/apps/js/bindings/core",
+ "mojo/apps/js/bindings/gl",
"mojo/apps/js/bindings/threading",
"mojom/native_viewport",
"mojom/gles2",
], function(console,
connector,
core,
+ gljs,
threading,
nativeViewport,
gles2) {
+ const VERTEX_SHADER_SOURCE =
+ "uniform mat4 u_mvpMatrix; \n" +
+ "attribute vec4 a_position; \n" +
+ "void main() \n" +
+ "{ \n" +
+ " gl_Position = u_mvpMatrix * a_position; \n" +
+ "} \n";
+
function NativeViewportClientImpl() {
}
+ // TODO(aa): It is a bummer to need this stub object in JavaScript. We should
+ // have a 'client' object that contains both the sending and receiving bits of
+ // the client side of the interface. Since JS is loosely typed, we do not need
+ // a separate base class to inherit from to receive callbacks.
NativeViewportClientImpl.prototype =
Object.create(nativeViewport.NativeViewportClientStub.prototype);
@@ -26,6 +40,7 @@ define([
console.log("NativeViewportClientImpl.prototype.DidOpen");
};
+
function GLES2ClientImpl() {
}
@@ -36,25 +51,27 @@ define([
width,
height) {
console.log("GLES2ClientImpl.prototype.didCreateContext");
- // Need to call MojoGLES2MakeCurrent(encoded) in C++.
- // TODO(abarth): Should we handle some of this GL setup in C++?
+ var gl = new gljs.Context(encoded, width, height);
+
+ var shader = gl.createShader(gl.VERTEX_SHADER);
+ console.log("shader is: ", String(shader));
+ gl.shaderSource(shader, VERTEX_SHADER_SOURCE);
+ gl.compileShader(shader);
+ console.log("all done");
};
GLES2ClientImpl.prototype.contextLost = function() {
console.log("GLES2ClientImpl.prototype.contextLost");
};
- var nativeViewportConnection = null;
- var gles2Connection = null;
-
return function(handle) {
- nativeViewportConnection = new connector.Connection(
+ var nativeViewportConnection = new connector.Connection(
handle,
NativeViewportClientImpl,
nativeViewport.NativeViewportProxy);
var gles2Handles = core.createMessagePipe();
- gles2Connection = new connector.Connection(
+ var gles2Connection = new connector.Connection(
gles2Handles.handle0, GLES2ClientImpl, gles2.GLES2Proxy);
nativeViewportConnection.remote.open();
diff --git a/mojo/apps/js/mojo_runner_delegate.cc b/mojo/apps/js/mojo_runner_delegate.cc
index 871e5b7..196466f 100644
--- a/mojo/apps/js/mojo_runner_delegate.cc
+++ b/mojo/apps/js/mojo_runner_delegate.cc
@@ -11,6 +11,7 @@
#include "gin/modules/module_registry.h"
#include "gin/try_catch.h"
#include "mojo/apps/js/bindings/core.h"
+#include "mojo/apps/js/bindings/gl/module.h"
#include "mojo/apps/js/bindings/support.h"
#include "mojo/apps/js/bindings/threading.h"
@@ -44,10 +45,11 @@ void StartCallback(base::WeakPtr<gin::Runner> runner,
MojoRunnerDelegate::MojoRunnerDelegate()
: ModuleRunnerDelegate(GetModuleSearchPaths()) {
- AddBuiltinModule(Threading::kModuleName, Threading::GetTemplate);
AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetTemplate);
AddBuiltinModule(js::Core::kModuleName, js::Core::GetTemplate);
AddBuiltinModule(js::Support::kModuleName, js::Support::GetTemplate);
+ AddBuiltinModule(mojo::js::gl::kModuleName, mojo::js::gl::GetModuleTemplate);
+ AddBuiltinModule(Threading::kModuleName, Threading::GetTemplate);
}
MojoRunnerDelegate::~MojoRunnerDelegate() {
diff --git a/mojo/mojo_apps.gypi b/mojo/mojo_apps.gypi
index 0efceff..fbcd134 100644
--- a/mojo/mojo_apps.gypi
+++ b/mojo/mojo_apps.gypi
@@ -5,7 +5,9 @@
'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
+ '../gpu/gpu.gyp:gles2_c_lib',
'../gin/gin.gyp:gin',
+ '../ui/gl/gl.gyp:gl',
'../v8/tools/gyp/v8.gyp:v8',
'mojo_common_lib',
'mojo_gles2',
@@ -29,6 +31,12 @@
'apps/js/bindings/threading.h',
'apps/js/bindings/core.cc',
'apps/js/bindings/core.h',
+ 'apps/js/bindings/gl/context.cc',
+ 'apps/js/bindings/gl/context.h',
+ 'apps/js/bindings/gl/module.cc',
+ 'apps/js/bindings/gl/module.h',
+ 'apps/js/bindings/gl/opaque.cc',
+ 'apps/js/bindings/gl/opaque.h',
'apps/js/bindings/handle.cc',
'apps/js/bindings/handle.h',
'apps/js/bindings/support.cc',