OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/apps/js/bindings/gl/context.h" | 5 #include "mojo/apps/js/bindings/gl/context.h" |
6 | 6 |
7 #include <GLES2/gl2.h> | 7 #include <GLES2/gl2.h> |
8 | 8 |
9 #include "gin/arguments.h" | 9 #include "gin/arguments.h" |
10 #include "gin/array_buffer.h" | |
10 #include "gin/object_template_builder.h" | 11 #include "gin/object_template_builder.h" |
11 #include "gin/per_isolate_data.h" | 12 #include "gin/per_isolate_data.h" |
12 #include "mojo/public/gles2/gles2.h" | 13 #include "mojo/public/gles2/gles2.h" |
13 | 14 |
14 namespace mojo { | 15 namespace mojo { |
15 namespace js { | 16 namespace js { |
16 namespace gl { | 17 namespace gl { |
17 | 18 |
18 gin::WrapperInfo Context::kWrapperInfo = { gin::kEmbedderNativeGin }; | 19 gin::WrapperInfo Context::kWrapperInfo = { gin::kEmbedderNativeGin }; |
19 | 20 |
20 gin::Handle<Context> Context::Create(v8::Isolate* isolate, uint64_t encoded, | 21 gin::Handle<Context> Context::Create(v8::Isolate* isolate, uint64_t encoded, |
21 int width, int height) { | 22 int width, int height) { |
22 return gin::CreateHandle(isolate, new Context(encoded, width, height)); | 23 return gin::CreateHandle(isolate, new Context(encoded, width, height)); |
23 } | 24 } |
24 | 25 |
25 v8::Handle<v8::ObjectTemplate> Context::GetObjectTemplate( | 26 v8::Handle<v8::ObjectTemplate> Context::GetObjectTemplate( |
26 v8::Isolate* isolate) { | 27 v8::Isolate* isolate) { |
27 gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); | 28 gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); |
28 v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(&kWrapperInfo); | 29 v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(&kWrapperInfo); |
29 if (templ.IsEmpty()) { | 30 if (templ.IsEmpty()) { |
30 templ = gin::ObjectTemplateBuilder(isolate) | 31 templ = gin::ObjectTemplateBuilder(isolate) |
32 .SetValue("ARRAY_BUFFER", GL_ARRAY_BUFFER) | |
33 .SetValue("COLOR_BUFFER_BIT", GL_COLOR_BUFFER_BIT) | |
34 .SetValue("ELEMENT_ARRAY_BUFFER", GL_ELEMENT_ARRAY_BUFFER) | |
35 .SetValue("FLOAT", GL_FLOAT) | |
36 .SetValue("FRAGMENT_SHADER", GL_FRAGMENT_SHADER) | |
37 .SetValue("STATIC_DRAW", GL_STATIC_DRAW) | |
31 .SetValue("VERTEX_SHADER", GL_VERTEX_SHADER) | 38 .SetValue("VERTEX_SHADER", GL_VERTEX_SHADER) |
32 .SetMethod("createShader", CreateShader) | 39 .SetMethod("attachShader", glAttachShader) |
40 .SetMethod("bindBuffer", glBindBuffer) | |
41 .SetMethod("bufferData", BufferData) | |
42 .SetMethod("clear", glClear) | |
43 .SetMethod("clearColor", glClearColor) | |
44 .SetMethod("compileShader", CompileShader) | |
45 .SetMethod("createBuffer", CreateBuffer) | |
46 .SetMethod("createProgram", glCreateProgram) | |
47 .SetMethod("createShader", glCreateShader) | |
48 .SetMethod("deleteShader", glDeleteShader) | |
49 .SetMethod("enableVertexAttribArray", glEnableVertexAttribArray) | |
50 .SetMethod("getAttribLocation", GetAttribLocation) | |
51 .SetMethod("getShaderInfoLog", GetShaderInfoLog) | |
52 .SetMethod("getUniformLocation", GetUniformLocation) | |
53 .SetMethod("linkProgram", glLinkProgram) | |
33 .SetMethod("shaderSource", ShaderSource) | 54 .SetMethod("shaderSource", ShaderSource) |
34 .SetMethod("compileShader", CompileShader) | 55 .SetMethod("useProgram", glUseProgram) |
56 .SetMethod("vertexAttribPointer", VertexAttribPointer) | |
57 .SetMethod("viewport", glViewport) | |
35 .Build(); | 58 .Build(); |
59 | |
36 templ->SetInternalFieldCount(gin::kNumberOfInternalFields); | 60 templ->SetInternalFieldCount(gin::kNumberOfInternalFields); |
37 data->SetObjectTemplate(&kWrapperInfo, templ); | 61 data->SetObjectTemplate(&kWrapperInfo, templ); |
38 } | 62 } |
39 return templ; | 63 return templ; |
40 } | 64 } |
41 | 65 |
42 gin::Handle<Shader> Context::CreateShader(const gin::Arguments& args, | 66 void Context::BufferData(GLenum target, const gin::ArrayBufferView& buffer, |
43 GLenum type) { | 67 GLenum usage) { |
44 gin::Handle<Shader> result; | 68 glBufferData(target, buffer.num_bytes(), buffer.bytes(), usage); |
45 GLuint glshader = glCreateShader(type); | 69 } |
46 if (glshader != 0u) { | 70 |
47 result = Opaque::Create(args.isolate(), glshader); | 71 void Context::CompileShader(const gin::Arguments& args, GLuint shader) { |
72 glCompileShader(shader); | |
73 GLint compiled = 0; | |
74 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); | |
abarth-chromium
2013/12/13 21:30:35
Maybe http://www.khronos.org/opengles/sdk/docs/man
Aaron Boodman
2013/12/13 21:43:57
But I want the textual error message...
| |
75 if (!compiled) { | |
76 args.ThrowTypeError(std::string("Could not compile shader: ") + | |
77 GetShaderInfoLog(shader)); | |
48 } | 78 } |
79 } | |
80 | |
81 GLuint Context::CreateBuffer() { | |
82 GLuint result = 0; | |
83 glGenBuffers(1, &result); | |
49 return result; | 84 return result; |
50 } | 85 } |
51 | 86 |
52 void Context::ShaderSource(gin::Handle<Shader> shader, | 87 GLint Context::GetAttribLocation(GLuint program, const std::string& name) { |
53 const std::string& source) { | 88 return glGetAttribLocation(program, name.c_str()); |
54 const char* source_chars = source.c_str(); | |
55 glShaderSource(shader->value(), 1, &source_chars, NULL); | |
56 } | 89 } |
57 | 90 |
58 void Context::CompileShader(const gin::Arguments& args, | 91 std::string Context::GetShaderInfoLog(GLuint shader) { |
59 gin::Handle<Shader> shader) { | 92 GLint info_log_length = 0; |
60 glCompileShader(shader->value()); | 93 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length); |
61 GLint compiled = 0; | 94 char info_log[info_log_length]; |
62 glGetShaderiv(shader->value(), GL_COMPILE_STATUS, &compiled); | 95 glGetShaderInfoLog(shader, info_log_length, NULL, info_log); |
63 if (!compiled) { | 96 return std::string(info_log, info_log_length); |
abarth-chromium
2013/12/13 21:30:35
You can avoid one of these copies by resizing the
Aaron Boodman
2013/12/13 21:43:57
Good point. Fixed.
| |
64 // Or should |shader| do it when it is destroyed? | 97 } |
65 glDeleteShader(shader->value()); | 98 |
66 args.ThrowTypeError("Could not compile shader"); | 99 GLint Context::GetUniformLocation(GLuint program, const std::string& name) { |
67 return; | 100 return glGetUniformLocation(program, name.c_str()); |
68 } | 101 } |
102 | |
103 void Context::ShaderSource(GLuint shader, const std::string& source) { | |
104 const char* source_chars = source.c_str(); | |
105 glShaderSource(shader, 1, &source_chars, NULL); | |
106 } | |
107 | |
108 void Context::VertexAttribPointer(GLuint index, GLint size, GLenum type, | |
109 bool normalized, GLsizei stride, | |
110 long offset) { | |
111 glVertexAttribPointer(index, size, type, static_cast<GLboolean>(normalized), | |
112 stride, reinterpret_cast<void*>(offset)); | |
69 } | 113 } |
70 | 114 |
71 Context::Context(uint64_t encoded, int width, int height) | 115 Context::Context(uint64_t encoded, int width, int height) |
72 : encoded_(encoded) { | 116 : encoded_(encoded) { |
73 // TODO(aa): When we want to support multiple contexts, we should add | 117 // TODO(aa): When we want to support multiple contexts, we should add |
74 // Context::MakeCurrent() for developers to switch between them. | 118 // Context::MakeCurrent() for developers to switch between them. |
75 MojoGLES2MakeCurrent(encoded_); | 119 MojoGLES2MakeCurrent(encoded_); |
76 } | 120 } |
77 | 121 |
78 } // namespace gl | 122 } // namespace gl |
79 } // namespace js | 123 } // namespace js |
80 } // namespace mojo | 124 } // namespace mojo |
OLD | NEW |