Add signalSyncPoint to the WebGraphicsContext3D command buffer impls.
[chromium-blink-merge.git] / cc / output / program_binding.cc
blobc9c5e1580c34818271b559cd6aceab7838381b02
1 // Copyright 2011 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 "cc/output/program_binding.h"
7 #include "base/debug/trace_event.h"
8 #include "cc/output/geometry_binding.h"
9 #include "cc/output/gl_renderer.h" // For the GLC() macro.
10 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
11 #include "third_party/khronos/GLES2/gl2.h"
13 using WebKit::WebGraphicsContext3D;
15 namespace cc {
17 ProgramBindingBase::ProgramBindingBase()
18 : program_(0),
19 vertex_shader_id_(0),
20 fragment_shader_id_(0),
21 initialized_(false) {}
23 ProgramBindingBase::~ProgramBindingBase() {
24 // If you hit these asserts, you initialized but forgot to call Cleanup().
25 DCHECK(!program_);
26 DCHECK(!vertex_shader_id_);
27 DCHECK(!fragment_shader_id_);
28 DCHECK(!initialized_);
31 void ProgramBindingBase::Init(WebGraphicsContext3D* context,
32 const std::string& vertex_shader,
33 const std::string& fragment_shader) {
34 TRACE_EVENT0("cc", "ProgramBindingBase::init");
35 vertex_shader_id_ = LoadShader(context, GL_VERTEX_SHADER, vertex_shader);
36 if (!vertex_shader_id_) {
37 if (!IsContextLost(context))
38 LOG(ERROR) << "Failed to create vertex shader";
39 return;
42 fragment_shader_id_ =
43 LoadShader(context, GL_FRAGMENT_SHADER, fragment_shader);
44 if (!fragment_shader_id_) {
45 GLC(context, context->deleteShader(vertex_shader_id_));
46 vertex_shader_id_ = 0;
47 if (!IsContextLost(context))
48 LOG(ERROR) << "Failed to create fragment shader";
49 return;
52 program_ =
53 CreateShaderProgram(context, vertex_shader_id_, fragment_shader_id_);
54 DCHECK(program_ || IsContextLost(context));
57 void ProgramBindingBase::Link(WebGraphicsContext3D* context) {
58 GLC(context, context->linkProgram(program_));
59 CleanupShaders(context);
60 if (!program_)
61 return;
62 #ifndef NDEBUG
63 int linked = 0;
64 GLC(context, context->getProgramiv(program_, GL_LINK_STATUS, &linked));
65 if (!linked) {
66 if (!IsContextLost(context))
67 LOG(ERROR) << "Failed to link shader program";
68 GLC(context, context->deleteProgram(program_));
70 #endif
73 void ProgramBindingBase::Cleanup(WebGraphicsContext3D* context) {
74 initialized_ = false;
75 if (!program_)
76 return;
78 DCHECK(context);
79 GLC(context, context->deleteProgram(program_));
80 program_ = 0;
82 CleanupShaders(context);
85 unsigned ProgramBindingBase::LoadShader(WebGraphicsContext3D* context,
86 unsigned type,
87 const std::string& shader_source) {
88 unsigned shader = context->createShader(type);
89 if (!shader)
90 return 0;
91 GLC(context, context->shaderSource(shader, shader_source.data()));
92 GLC(context, context->compileShader(shader));
93 #ifndef NDEBUG
94 int compiled = 0;
95 GLC(context, context->getShaderiv(shader, GL_COMPILE_STATUS, &compiled));
96 if (!compiled) {
97 GLC(context, context->deleteShader(shader));
98 return 0;
100 #endif
101 return shader;
104 unsigned ProgramBindingBase::CreateShaderProgram(WebGraphicsContext3D* context,
105 unsigned vertex_shader,
106 unsigned fragment_shader) {
107 unsigned program_object = context->createProgram();
108 if (!program_object) {
109 if (!IsContextLost(context))
110 LOG(ERROR) << "Failed to create shader program";
111 return 0;
114 GLC(context, context->attachShader(program_object, vertex_shader));
115 GLC(context, context->attachShader(program_object, fragment_shader));
117 // Bind the common attrib locations.
118 GLC(context,
119 context->bindAttribLocation(program_object,
120 GeometryBinding::PositionAttribLocation(),
121 "a_position"));
122 GLC(context,
123 context->bindAttribLocation(program_object,
124 GeometryBinding::TexCoordAttribLocation(),
125 "a_texCoord"));
126 GLC(context,
127 context->bindAttribLocation(
128 program_object,
129 GeometryBinding::TriangleIndexAttribLocation(),
130 "a_index"));
132 return program_object;
135 void ProgramBindingBase::CleanupShaders(WebGraphicsContext3D* context) {
136 if (vertex_shader_id_) {
137 GLC(context, context->deleteShader(vertex_shader_id_));
138 vertex_shader_id_ = 0;
140 if (fragment_shader_id_) {
141 GLC(context, context->deleteShader(fragment_shader_id_));
142 fragment_shader_id_ = 0;
146 bool ProgramBindingBase::IsContextLost(WebGraphicsContext3D* context) {
147 return (context->getGraphicsResetStatusARB() != GL_NO_ERROR);
150 } // namespace cc