Upgrade ReadPixels to ES3 semantic in command buffer.
[chromium-blink-merge.git] / cc / output / program_binding.cc
blobc05447c7d65037c762a8bd590af50919be6e0910
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/GLES2/gl2extchromium.h"
10 #include "gpu/command_buffer/client/gles2_interface.h"
12 using gpu::gles2::GLES2Interface;
14 namespace cc {
16 ProgramBindingBase::ProgramBindingBase()
17 : program_(0),
18 vertex_shader_id_(0),
19 fragment_shader_id_(0),
20 initialized_(false) {}
22 ProgramBindingBase::~ProgramBindingBase() {
23 // If you hit these asserts, you initialized but forgot to call Cleanup().
24 DCHECK(!program_);
25 DCHECK(!vertex_shader_id_);
26 DCHECK(!fragment_shader_id_);
27 DCHECK(!initialized_);
30 bool ProgramBindingBase::Init(GLES2Interface* context,
31 const std::string& vertex_shader,
32 const std::string& fragment_shader) {
33 TRACE_EVENT0("cc", "ProgramBindingBase::init");
34 vertex_shader_id_ = LoadShader(context, GL_VERTEX_SHADER, vertex_shader);
35 if (!vertex_shader_id_)
36 return false;
38 fragment_shader_id_ =
39 LoadShader(context, GL_FRAGMENT_SHADER, fragment_shader);
40 if (!fragment_shader_id_) {
41 context->DeleteShader(vertex_shader_id_);
42 vertex_shader_id_ = 0;
43 return false;
46 program_ =
47 CreateShaderProgram(context, vertex_shader_id_, fragment_shader_id_);
48 return !!program_;
51 bool ProgramBindingBase::Link(GLES2Interface* context) {
52 context->LinkProgram(program_);
53 CleanupShaders(context);
54 if (!program_)
55 return false;
56 #ifndef NDEBUG
57 int linked = 0;
58 context->GetProgramiv(program_, GL_LINK_STATUS, &linked);
59 if (!linked)
60 return false;
61 #endif
62 return true;
65 void ProgramBindingBase::Cleanup(GLES2Interface* context) {
66 initialized_ = false;
67 if (!program_)
68 return;
70 DCHECK(context);
71 context->DeleteProgram(program_);
72 program_ = 0;
74 CleanupShaders(context);
77 unsigned ProgramBindingBase::LoadShader(GLES2Interface* context,
78 unsigned type,
79 const std::string& shader_source) {
80 unsigned shader = context->CreateShader(type);
81 if (!shader)
82 return 0u;
84 const char* shader_source_str[] = { shader_source.data() };
85 int shader_length[] = { static_cast<int>(shader_source.length()) };
86 context->ShaderSource(
87 shader, 1,
88 shader_source_str,
89 shader_length);
90 context->CompileShader(shader);
91 #ifndef NDEBUG
92 int compiled = 0;
93 context->GetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
94 if (!compiled)
95 return 0u;
96 #endif
97 return shader;
100 unsigned ProgramBindingBase::CreateShaderProgram(GLES2Interface* context,
101 unsigned vertex_shader,
102 unsigned fragment_shader) {
103 unsigned program_object = context->CreateProgram();
104 if (!program_object)
105 return 0;
107 context->AttachShader(program_object, vertex_shader);
108 context->AttachShader(program_object, fragment_shader);
110 // Bind the common attrib locations.
111 context->BindAttribLocation(
112 program_object, GeometryBinding::PositionAttribLocation(), "a_position");
113 context->BindAttribLocation(
114 program_object, GeometryBinding::TexCoordAttribLocation(), "a_texCoord");
115 context->BindAttribLocation(program_object,
116 GeometryBinding::TriangleIndexAttribLocation(),
117 "a_index");
119 return program_object;
122 void ProgramBindingBase::CleanupShaders(GLES2Interface* context) {
123 if (vertex_shader_id_) {
124 context->DeleteShader(vertex_shader_id_);
125 vertex_shader_id_ = 0;
127 if (fragment_shader_id_) {
128 context->DeleteShader(fragment_shader_id_);
129 fragment_shader_id_ = 0;
133 bool ProgramBindingBase::IsContextLost(GLES2Interface* context) {
134 return context->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
137 } // namespace cc