| 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
|
|
|