diff options
-rw-r--r-- | gin/arguments.cc | 6 | ||||
-rw-r--r-- | gin/arguments.h | 6 | ||||
-rw-r--r-- | gin/handle.h | 9 | ||||
-rw-r--r-- | mojo/apps/js/bindings/gl/context.cc | 80 | ||||
-rw-r--r-- | mojo/apps/js/bindings/gl/context.h | 52 | ||||
-rw-r--r-- | mojo/apps/js/bindings/gl/module.cc | 54 | ||||
-rw-r--r-- | mojo/apps/js/bindings/gl/module.h | 22 | ||||
-rw-r--r-- | mojo/apps/js/bindings/gl/opaque.cc | 37 | ||||
-rw-r--r-- | mojo/apps/js/bindings/gl/opaque.h | 41 | ||||
-rw-r--r-- | mojo/apps/js/bindings/threading.cc | 5 | ||||
-rw-r--r-- | mojo/apps/js/bindings/threading.h | 4 | ||||
-rw-r--r-- | mojo/apps/js/main.js | 31 | ||||
-rw-r--r-- | mojo/apps/js/mojo_runner_delegate.cc | 4 | ||||
-rw-r--r-- | mojo/mojo_apps.gypi | 8 |
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', |