Adding Peter Thatcher to the owners file.
[chromium-blink-merge.git] / cc / output / program_binding.cc
blob7809e1085c7b11cd5e903e3dd911145eacacf7a1
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/trace_event/trace_event.h"
8 #include "cc/output/geometry_binding.h"
9 #include "gpu/command_buffer/client/gles2_interface.h"
11 using gpu::gles2::GLES2Interface;
13 namespace cc {
15 ProgramBindingBase::ProgramBindingBase()
16 : program_(0),
17 vertex_shader_id_(0),
18 fragment_shader_id_(0),
19 initialized_(false) {}
21 ProgramBindingBase::~ProgramBindingBase() {
22 // If you hit these asserts, you initialized but forgot to call Cleanup().
23 DCHECK(!program_);
24 DCHECK(!vertex_shader_id_);
25 DCHECK(!fragment_shader_id_);
26 DCHECK(!initialized_);
29 bool ProgramBindingBase::Init(GLES2Interface* context,
30 const std::string& vertex_shader,
31 const std::string& fragment_shader) {
32 TRACE_EVENT0("cc", "ProgramBindingBase::init");
33 vertex_shader_id_ = LoadShader(context, GL_VERTEX_SHADER, vertex_shader);
34 if (!vertex_shader_id_)
35 return false;
37 fragment_shader_id_ =
38 LoadShader(context, GL_FRAGMENT_SHADER, fragment_shader);
39 if (!fragment_shader_id_) {
40 context->DeleteShader(vertex_shader_id_);
41 vertex_shader_id_ = 0;
42 return false;
45 program_ =
46 CreateShaderProgram(context, vertex_shader_id_, fragment_shader_id_);
47 return !!program_;
50 bool ProgramBindingBase::Link(GLES2Interface* context) {
51 context->LinkProgram(program_);
52 CleanupShaders(context);
53 if (!program_)
54 return false;
55 #ifndef NDEBUG
56 int linked = 0;
57 context->GetProgramiv(program_, GL_LINK_STATUS, &linked);
58 if (!linked)
59 return false;
60 #endif
61 return true;
64 void ProgramBindingBase::Cleanup(GLES2Interface* context) {
65 initialized_ = false;
66 if (!program_)
67 return;
69 DCHECK(context);
70 context->DeleteProgram(program_);
71 program_ = 0;
73 CleanupShaders(context);
76 unsigned ProgramBindingBase::LoadShader(GLES2Interface* context,
77 unsigned type,
78 const std::string& shader_source) {
79 unsigned shader = context->CreateShader(type);
80 if (!shader)
81 return 0u;
83 const char* shader_source_str[] = { shader_source.data() };
84 int shader_length[] = { static_cast<int>(shader_source.length()) };
85 context->ShaderSource(
86 shader, 1,
87 shader_source_str,
88 shader_length);
89 context->CompileShader(shader);
90 #ifndef NDEBUG
91 int compiled = 0;
92 context->GetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
93 if (!compiled)
94 return 0u;
95 #endif
96 return shader;
99 unsigned ProgramBindingBase::CreateShaderProgram(GLES2Interface* context,
100 unsigned vertex_shader,
101 unsigned fragment_shader) {
102 unsigned program_object = context->CreateProgram();
103 if (!program_object)
104 return 0;
106 context->AttachShader(program_object, vertex_shader);
107 context->AttachShader(program_object, fragment_shader);
109 // Bind the common attrib locations.
110 context->BindAttribLocation(
111 program_object, GeometryBinding::PositionAttribLocation(), "a_position");
112 context->BindAttribLocation(
113 program_object, GeometryBinding::TexCoordAttribLocation(), "a_texCoord");
114 context->BindAttribLocation(program_object,
115 GeometryBinding::TriangleIndexAttribLocation(),
116 "a_index");
118 return program_object;
121 void ProgramBindingBase::CleanupShaders(GLES2Interface* context) {
122 if (vertex_shader_id_) {
123 context->DeleteShader(vertex_shader_id_);
124 vertex_shader_id_ = 0;
126 if (fragment_shader_id_) {
127 context->DeleteShader(fragment_shader_id_);
128 fragment_shader_id_ = 0;
132 } // namespace cc