Index: cc/output/program_binding.cc |
diff --git a/cc/output/program_binding.cc b/cc/output/program_binding.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7809e1085c7b11cd5e903e3dd911145eacacf7a1 |
--- /dev/null |
+++ b/cc/output/program_binding.cc |
@@ -0,0 +1,132 @@ |
+// Copyright 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "cc/output/program_binding.h" |
+ |
+#include "base/trace_event/trace_event.h" |
+#include "cc/output/geometry_binding.h" |
+#include "gpu/command_buffer/client/gles2_interface.h" |
+ |
+using gpu::gles2::GLES2Interface; |
+ |
+namespace cc { |
+ |
+ProgramBindingBase::ProgramBindingBase() |
+ : program_(0), |
+ vertex_shader_id_(0), |
+ fragment_shader_id_(0), |
+ initialized_(false) {} |
+ |
+ProgramBindingBase::~ProgramBindingBase() { |
+ // If you hit these asserts, you initialized but forgot to call Cleanup(). |
+ DCHECK(!program_); |
+ DCHECK(!vertex_shader_id_); |
+ DCHECK(!fragment_shader_id_); |
+ DCHECK(!initialized_); |
+} |
+ |
+bool ProgramBindingBase::Init(GLES2Interface* context, |
+ const std::string& vertex_shader, |
+ const std::string& fragment_shader) { |
+ TRACE_EVENT0("cc", "ProgramBindingBase::init"); |
+ vertex_shader_id_ = LoadShader(context, GL_VERTEX_SHADER, vertex_shader); |
+ if (!vertex_shader_id_) |
+ return false; |
+ |
+ fragment_shader_id_ = |
+ LoadShader(context, GL_FRAGMENT_SHADER, fragment_shader); |
+ if (!fragment_shader_id_) { |
+ context->DeleteShader(vertex_shader_id_); |
+ vertex_shader_id_ = 0; |
+ return false; |
+ } |
+ |
+ program_ = |
+ CreateShaderProgram(context, vertex_shader_id_, fragment_shader_id_); |
+ return !!program_; |
+} |
+ |
+bool ProgramBindingBase::Link(GLES2Interface* context) { |
+ context->LinkProgram(program_); |
+ CleanupShaders(context); |
+ if (!program_) |
+ return false; |
+#ifndef NDEBUG |
+ int linked = 0; |
+ context->GetProgramiv(program_, GL_LINK_STATUS, &linked); |
+ if (!linked) |
+ return false; |
+#endif |
+ return true; |
+} |
+ |
+void ProgramBindingBase::Cleanup(GLES2Interface* context) { |
+ initialized_ = false; |
+ if (!program_) |
+ return; |
+ |
+ DCHECK(context); |
+ context->DeleteProgram(program_); |
+ program_ = 0; |
+ |
+ CleanupShaders(context); |
+} |
+ |
+unsigned ProgramBindingBase::LoadShader(GLES2Interface* context, |
+ unsigned type, |
+ const std::string& shader_source) { |
+ unsigned shader = context->CreateShader(type); |
+ if (!shader) |
+ return 0u; |
+ |
+ const char* shader_source_str[] = { shader_source.data() }; |
+ int shader_length[] = { static_cast<int>(shader_source.length()) }; |
+ context->ShaderSource( |
+ shader, 1, |
+ shader_source_str, |
+ shader_length); |
+ context->CompileShader(shader); |
+#ifndef NDEBUG |
+ int compiled = 0; |
+ context->GetShaderiv(shader, GL_COMPILE_STATUS, &compiled); |
+ if (!compiled) |
+ return 0u; |
+#endif |
+ return shader; |
+} |
+ |
+unsigned ProgramBindingBase::CreateShaderProgram(GLES2Interface* context, |
+ unsigned vertex_shader, |
+ unsigned fragment_shader) { |
+ unsigned program_object = context->CreateProgram(); |
+ if (!program_object) |
+ return 0; |
+ |
+ context->AttachShader(program_object, vertex_shader); |
+ context->AttachShader(program_object, fragment_shader); |
+ |
+ // Bind the common attrib locations. |
+ context->BindAttribLocation( |
+ program_object, GeometryBinding::PositionAttribLocation(), "a_position"); |
+ context->BindAttribLocation( |
+ program_object, GeometryBinding::TexCoordAttribLocation(), "a_texCoord"); |
+ context->BindAttribLocation(program_object, |
+ GeometryBinding::TriangleIndexAttribLocation(), |
+ "a_index"); |
+ |
+ return program_object; |
+} |
+ |
+void ProgramBindingBase::CleanupShaders(GLES2Interface* context) { |
+ if (vertex_shader_id_) { |
+ context->DeleteShader(vertex_shader_id_); |
+ vertex_shader_id_ = 0; |
+ } |
+ if (fragment_shader_id_) { |
+ context->DeleteShader(fragment_shader_id_); |
+ fragment_shader_id_ = 0; |
+ } |
+} |
+ |
+} // namespace cc |