1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mojo/apps/js/bindings/gl/context.h"
9 #include "gin/arguments.h"
10 #include "gin/array_buffer.h"
11 #include "gin/object_template_builder.h"
12 #include "gin/per_context_data.h"
13 #include "mojo/public/gles2/gles2.h"
17 struct Converter<GLboolean> {
18 static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
20 bool bool_val = false;
21 if (!Converter<bool>::FromV8(isolate, val, &bool_val))
23 *out = static_cast<GLboolean>(bool_val);
33 gin::WrapperInfo Context::kWrapperInfo = { gin::kEmbedderNativeGin };
35 gin::Handle<Context> Context::Create(
38 v8::Handle<v8::Function> context_lost_callback) {
39 return gin::CreateHandle(isolate,
40 new Context(isolate, handle, context_lost_callback));
43 void Context::BufferData(GLenum target, const gin::ArrayBufferView& buffer,
45 glBufferData(target, static_cast<GLsizeiptr>(buffer.num_bytes()),
46 buffer.bytes(), usage);
49 void Context::CompileShader(const gin::Arguments& args, GLuint shader) {
50 glCompileShader(shader);
52 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
54 args.ThrowTypeError(std::string("Could not compile shader: ") +
55 GetShaderInfoLog(shader));
59 GLuint Context::CreateBuffer() {
61 glGenBuffers(1, &result);
65 void Context::DrawElements(GLenum mode, GLsizei count, GLenum type,
67 // This looks scary, but it's what WebGL does too:
68 // http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.1
69 glDrawElements(mode, count, type, reinterpret_cast<void*>(indices));
72 GLint Context::GetAttribLocation(GLuint program, const std::string& name) {
73 return glGetAttribLocation(program, name.c_str());
76 std::string Context::GetProgramInfoLog(GLuint program) {
77 GLint info_log_length = 0;
78 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);
79 std::string info_log(info_log_length, 0);
80 glGetProgramInfoLog(program, info_log_length, NULL, &info_log.at(0));
84 std::string Context::GetShaderInfoLog(GLuint shader) {
85 GLint info_log_length = 0;
86 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);
87 std::string info_log(info_log_length, 0);
88 glGetShaderInfoLog(shader, info_log_length, NULL, &info_log.at(0));
92 GLint Context::GetUniformLocation(GLuint program, const std::string& name) {
93 return glGetUniformLocation(program, name.c_str());
96 void Context::ShaderSource(GLuint shader, const std::string& source) {
97 const char* source_chars = source.c_str();
98 glShaderSource(shader, 1, &source_chars, NULL);
101 void Context::UniformMatrix4fv(GLint location, GLboolean transpose,
102 const gin::ArrayBufferView& buffer) {
103 glUniformMatrix4fv(location, 1, transpose,
104 static_cast<float*>(buffer.bytes()));
107 void Context::VertexAttribPointer(GLuint index, GLint size, GLenum type,
108 GLboolean normalized, GLsizei stride,
110 glVertexAttribPointer(index, size, type, normalized, stride,
111 reinterpret_cast<void*>(offset));
114 gin::ObjectTemplateBuilder Context::GetObjectTemplateBuilder(
115 v8::Isolate* isolate) {
116 return gin::ObjectTemplateBuilder(isolate)
117 .SetValue("ARRAY_BUFFER", GL_ARRAY_BUFFER)
118 .SetValue("COLOR_BUFFER_BIT", GL_COLOR_BUFFER_BIT)
119 .SetValue("ELEMENT_ARRAY_BUFFER", GL_ELEMENT_ARRAY_BUFFER)
120 .SetValue("FLOAT", GL_FLOAT)
121 .SetValue("FRAGMENT_SHADER", GL_FRAGMENT_SHADER)
122 .SetValue("STATIC_DRAW", GL_STATIC_DRAW)
123 .SetValue("TRIANGLES", GL_TRIANGLES)
124 .SetValue("UNSIGNED_SHORT", GL_UNSIGNED_SHORT)
125 .SetValue("VERTEX_SHADER", GL_VERTEX_SHADER)
126 .SetMethod("attachShader", glAttachShader)
127 .SetMethod("bindBuffer", glBindBuffer)
128 .SetMethod("bufferData", BufferData)
129 .SetMethod("clear", glClear)
130 .SetMethod("clearColor", glClearColor)
131 .SetMethod("compileShader", CompileShader)
132 .SetMethod("createBuffer", CreateBuffer)
133 .SetMethod("createProgram", glCreateProgram)
134 .SetMethod("createShader", glCreateShader)
135 .SetMethod("deleteShader", glDeleteShader)
136 .SetMethod("drawElements", DrawElements)
137 .SetMethod("enableVertexAttribArray", glEnableVertexAttribArray)
138 .SetMethod("getAttribLocation", GetAttribLocation)
139 .SetMethod("getProgramInfoLog", GetProgramInfoLog)
140 .SetMethod("getShaderInfoLog", GetShaderInfoLog)
141 .SetMethod("getUniformLocation", GetUniformLocation)
142 .SetMethod("linkProgram", glLinkProgram)
143 .SetMethod("shaderSource", ShaderSource)
144 .SetMethod("swapBuffers", MojoGLES2SwapBuffers)
145 .SetMethod("uniformMatrix4fv", UniformMatrix4fv)
146 .SetMethod("useProgram", glUseProgram)
147 .SetMethod("vertexAttribPointer", VertexAttribPointer)
148 .SetMethod("viewport", glViewport);
151 Context::Context(v8::Isolate* isolate,
153 v8::Handle<v8::Function> context_lost_callback) {
154 v8::Handle<v8::Context> context = isolate->GetCurrentContext();
155 runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr();
156 context_lost_callback_.Reset(isolate, context_lost_callback);
157 context_ = MojoGLES2CreateContext(
162 MojoGLES2MakeCurrent(context_);
165 Context::~Context() {
166 MojoGLES2DestroyContext(context_);
169 void Context::ContextLost() {
172 gin::Runner::Scope scope(runner_.get());
173 v8::Isolate* isolate = runner_->GetContextHolder()->isolate();
175 v8::Handle<v8::Function> callback = v8::Local<v8::Function>::New(
176 isolate, context_lost_callback_);
178 runner_->Call(callback, runner_->global(), 0, NULL);
181 void Context::ContextLostThunk(void* closure) {
182 static_cast<Context*>(closure)->ContextLost();