OLD | NEW |
| (Empty) |
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/c/gles2/gles2.h" | |
14 #include "mojo/public/cpp/environment/environment.h" | |
15 | |
16 namespace gin { | |
17 template<> | |
18 struct Converter<GLboolean> { | |
19 static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, | |
20 GLboolean* out) { | |
21 bool bool_val = false; | |
22 if (!Converter<bool>::FromV8(isolate, val, &bool_val)) | |
23 return false; | |
24 *out = static_cast<GLboolean>(bool_val); | |
25 return true; | |
26 } | |
27 }; | |
28 } | |
29 | |
30 namespace mojo { | |
31 namespace js { | |
32 namespace gl { | |
33 | |
34 gin::WrapperInfo Context::kWrapperInfo = { gin::kEmbedderNativeGin }; | |
35 | |
36 gin::Handle<Context> Context::Create( | |
37 v8::Isolate* isolate, | |
38 mojo::Handle handle, | |
39 v8::Handle<v8::Function> context_lost_callback) { | |
40 return gin::CreateHandle(isolate, | |
41 new Context(isolate, handle, context_lost_callback)); | |
42 } | |
43 | |
44 void Context::BufferData(GLenum target, const gin::ArrayBufferView& buffer, | |
45 GLenum usage) { | |
46 glBufferData(target, static_cast<GLsizeiptr>(buffer.num_bytes()), | |
47 buffer.bytes(), usage); | |
48 } | |
49 | |
50 void Context::CompileShader(const gin::Arguments& args, GLuint shader) { | |
51 glCompileShader(shader); | |
52 GLint compiled = 0; | |
53 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); | |
54 if (!compiled) { | |
55 args.ThrowTypeError(std::string("Could not compile shader: ") + | |
56 GetShaderInfoLog(shader)); | |
57 } | |
58 } | |
59 | |
60 GLuint Context::CreateBuffer() { | |
61 GLuint result = 0; | |
62 glGenBuffers(1, &result); | |
63 return result; | |
64 } | |
65 | |
66 void Context::DrawElements(GLenum mode, GLsizei count, GLenum type, | |
67 uint64_t indices) { | |
68 // This looks scary, but it's what WebGL does too: | |
69 // http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.1 | |
70 glDrawElements(mode, count, type, reinterpret_cast<void*>(indices)); | |
71 } | |
72 | |
73 GLint Context::GetAttribLocation(GLuint program, const std::string& name) { | |
74 return glGetAttribLocation(program, name.c_str()); | |
75 } | |
76 | |
77 std::string Context::GetProgramInfoLog(GLuint program) { | |
78 GLint info_log_length = 0; | |
79 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length); | |
80 std::string info_log(info_log_length, 0); | |
81 glGetProgramInfoLog(program, info_log_length, NULL, &info_log.at(0)); | |
82 return info_log; | |
83 } | |
84 | |
85 std::string Context::GetShaderInfoLog(GLuint shader) { | |
86 GLint info_log_length = 0; | |
87 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length); | |
88 std::string info_log(info_log_length, 0); | |
89 glGetShaderInfoLog(shader, info_log_length, NULL, &info_log.at(0)); | |
90 return info_log; | |
91 } | |
92 | |
93 GLint Context::GetUniformLocation(GLuint program, const std::string& name) { | |
94 return glGetUniformLocation(program, name.c_str()); | |
95 } | |
96 | |
97 void Context::ShaderSource(GLuint shader, const std::string& source) { | |
98 const char* source_chars = source.c_str(); | |
99 glShaderSource(shader, 1, &source_chars, NULL); | |
100 } | |
101 | |
102 void Context::UniformMatrix4fv(GLint location, GLboolean transpose, | |
103 const gin::ArrayBufferView& buffer) { | |
104 glUniformMatrix4fv(location, 1, transpose, | |
105 static_cast<float*>(buffer.bytes())); | |
106 } | |
107 | |
108 void Context::VertexAttribPointer(GLuint index, GLint size, GLenum type, | |
109 GLboolean normalized, GLsizei stride, | |
110 uint64_t offset) { | |
111 glVertexAttribPointer(index, size, type, normalized, stride, | |
112 reinterpret_cast<void*>(offset)); | |
113 } | |
114 | |
115 gin::ObjectTemplateBuilder Context::GetObjectTemplateBuilder( | |
116 v8::Isolate* isolate) { | |
117 return gin::ObjectTemplateBuilder(isolate) | |
118 .SetValue("ARRAY_BUFFER", GL_ARRAY_BUFFER) | |
119 .SetValue("COLOR_BUFFER_BIT", GL_COLOR_BUFFER_BIT) | |
120 .SetValue("ELEMENT_ARRAY_BUFFER", GL_ELEMENT_ARRAY_BUFFER) | |
121 .SetValue("FLOAT", GL_FLOAT) | |
122 .SetValue("FRAGMENT_SHADER", GL_FRAGMENT_SHADER) | |
123 .SetValue("STATIC_DRAW", GL_STATIC_DRAW) | |
124 .SetValue("TRIANGLES", GL_TRIANGLES) | |
125 .SetValue("UNSIGNED_SHORT", GL_UNSIGNED_SHORT) | |
126 .SetValue("VERTEX_SHADER", GL_VERTEX_SHADER) | |
127 .SetMethod("attachShader", glAttachShader) | |
128 .SetMethod("bindBuffer", glBindBuffer) | |
129 .SetMethod("bufferData", BufferData) | |
130 .SetMethod("clear", glClear) | |
131 .SetMethod("clearColor", glClearColor) | |
132 .SetMethod("compileShader", CompileShader) | |
133 .SetMethod("createBuffer", CreateBuffer) | |
134 .SetMethod("createProgram", glCreateProgram) | |
135 .SetMethod("createShader", glCreateShader) | |
136 .SetMethod("deleteShader", glDeleteShader) | |
137 .SetMethod("drawElements", DrawElements) | |
138 .SetMethod("enableVertexAttribArray", glEnableVertexAttribArray) | |
139 .SetMethod("getAttribLocation", GetAttribLocation) | |
140 .SetMethod("getProgramInfoLog", GetProgramInfoLog) | |
141 .SetMethod("getShaderInfoLog", GetShaderInfoLog) | |
142 .SetMethod("getUniformLocation", GetUniformLocation) | |
143 .SetMethod("linkProgram", glLinkProgram) | |
144 .SetMethod("shaderSource", ShaderSource) | |
145 .SetMethod("swapBuffers", MojoGLES2SwapBuffers) | |
146 .SetMethod("uniformMatrix4fv", UniformMatrix4fv) | |
147 .SetMethod("useProgram", glUseProgram) | |
148 .SetMethod("vertexAttribPointer", VertexAttribPointer) | |
149 .SetMethod("viewport", glViewport); | |
150 } | |
151 | |
152 Context::Context(v8::Isolate* isolate, | |
153 mojo::Handle handle, | |
154 v8::Handle<v8::Function> context_lost_callback) { | |
155 v8::Handle<v8::Context> context = isolate->GetCurrentContext(); | |
156 runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr(); | |
157 context_lost_callback_.Reset(isolate, context_lost_callback); | |
158 context_ = MojoGLES2CreateContext(handle.value(), | |
159 &ContextLostThunk, | |
160 this, | |
161 Environment::GetDefaultAsyncWaiter()); | |
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_->GetContextHolder()->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 | |
OLD | NEW |