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
;
16 ProgramBindingBase::ProgramBindingBase()
19 fragment_shader_id_(0),
20 initialized_(false) {}
22 ProgramBindingBase::~ProgramBindingBase() {
23 // If you hit these asserts, you initialized but forgot to call Cleanup().
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_
)
39 LoadShader(context
, GL_FRAGMENT_SHADER
, fragment_shader
);
40 if (!fragment_shader_id_
) {
41 context
->DeleteShader(vertex_shader_id_
);
42 vertex_shader_id_
= 0;
47 CreateShaderProgram(context
, vertex_shader_id_
, fragment_shader_id_
);
51 bool ProgramBindingBase::Link(GLES2Interface
* context
) {
52 context
->LinkProgram(program_
);
53 CleanupShaders(context
);
58 context
->GetProgramiv(program_
, GL_LINK_STATUS
, &linked
);
65 void ProgramBindingBase::Cleanup(GLES2Interface
* context
) {
71 context
->DeleteProgram(program_
);
74 CleanupShaders(context
);
77 unsigned ProgramBindingBase::LoadShader(GLES2Interface
* context
,
79 const std::string
& shader_source
) {
80 unsigned shader
= context
->CreateShader(type
);
84 const char* shader_source_str
[] = { shader_source
.data() };
85 int shader_length
[] = { static_cast<int>(shader_source
.length()) };
86 context
->ShaderSource(
90 context
->CompileShader(shader
);
93 context
->GetShaderiv(shader
, GL_COMPILE_STATUS
, &compiled
);
100 unsigned ProgramBindingBase::CreateShaderProgram(GLES2Interface
* context
,
101 unsigned vertex_shader
,
102 unsigned fragment_shader
) {
103 unsigned program_object
= context
->CreateProgram();
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(),
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
;