Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / mojo / apps / js / bindings / gl / context.cc
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.
4
5 #include "mojo/apps/js/bindings/gl/context.h"
6
7 #include <GLES2/gl2.h>
8
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"
14
15 namespace gin {
16 template<>
17 struct Converter<GLboolean> {
18   static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
19                      GLboolean* out) {
20     bool bool_val = false;
21     if (!Converter<bool>::FromV8(isolate, val, &bool_val))
22       return false;
23     *out = static_cast<GLboolean>(bool_val);
24     return true;
25   }
26 };
27 }
28
29 namespace mojo {
30 namespace js {
31 namespace gl {
32
33 gin::WrapperInfo Context::kWrapperInfo = { gin::kEmbedderNativeGin };
34
35 gin::Handle<Context> Context::Create(
36     v8::Isolate* isolate,
37     mojo::Handle handle,
38     v8::Handle<v8::Function> context_lost_callback) {
39   return gin::CreateHandle(isolate,
40                            new Context(isolate, handle, context_lost_callback));
41 }
42
43 void Context::BufferData(GLenum target, const gin::ArrayBufferView& buffer,
44                          GLenum usage) {
45   glBufferData(target, static_cast<GLsizeiptr>(buffer.num_bytes()),
46                buffer.bytes(), usage);
47 }
48
49 void Context::CompileShader(const gin::Arguments& args, GLuint shader) {
50   glCompileShader(shader);
51   GLint compiled = 0;
52   glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
53   if (!compiled) {
54     args.ThrowTypeError(std::string("Could not compile shader: ") +
55                         GetShaderInfoLog(shader));
56   }
57 }
58
59 GLuint Context::CreateBuffer() {
60   GLuint result = 0;
61   glGenBuffers(1, &result);
62   return result;
63 }
64
65 void Context::DrawElements(GLenum mode, GLsizei count, GLenum type,
66                            uint64_t indices) {
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));
70 }
71
72 GLint Context::GetAttribLocation(GLuint program, const std::string& name) {
73   return glGetAttribLocation(program, name.c_str());
74 }
75
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));
81   return info_log;
82 }
83
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));
89   return info_log;
90 }
91
92 GLint Context::GetUniformLocation(GLuint program, const std::string& name) {
93   return glGetUniformLocation(program, name.c_str());
94 }
95
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);
99 }
100
101 void Context::UniformMatrix4fv(GLint location, GLboolean transpose,
102                                const gin::ArrayBufferView& buffer) {
103   glUniformMatrix4fv(location, 1, transpose,
104                      static_cast<float*>(buffer.bytes()));
105 }
106
107 void Context::VertexAttribPointer(GLuint index, GLint size, GLenum type,
108                                   GLboolean normalized, GLsizei stride,
109                                   uint64_t offset) {
110   glVertexAttribPointer(index, size, type, normalized, stride,
111                         reinterpret_cast<void*>(offset));
112 }
113
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);
149 }
150
151 Context::Context(v8::Isolate* isolate,
152                  mojo::Handle handle,
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(
158       handle.value(),
159       &ContextLostThunk,
160       NULL,
161       this);
162   MojoGLES2MakeCurrent(context_);
163 }
164
165 Context::~Context() {
166   MojoGLES2DestroyContext(context_);
167 }
168
169 void Context::ContextLost() {
170   if (!runner_)
171     return;
172   gin::Runner::Scope scope(runner_.get());
173   v8::Isolate* isolate = runner_->isolate();
174
175   v8::Handle<v8::Function> callback = v8::Local<v8::Function>::New(
176       isolate, context_lost_callback_);
177
178   runner_->Call(callback, runner_->global(), 0, NULL);
179 }
180
181 void Context::ContextLostThunk(void* closure) {
182   static_cast<Context*>(closure)->ContextLost();
183 }
184
185 }  // namespace gl
186 }  // namespace js
187 }  // namespace mojo