WebKit Roll 139512:139548
[chromium-blink-merge.git] / cc / program_binding.cc
blob8e92e9815b05be7a308a8ab3b8d4a26b544cc352
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/program_binding.h"
7 #include "base/debug/trace_event.h"
8 #include "cc/geometry_binding.h"
9 #include "cc/gl_renderer.h" // For the GLC() macro.
10 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
11 #include "third_party/khronos/GLES2/gl2.h"
13 using WebKit::WebGraphicsContext3D;
15 namespace cc {
17 ProgramBindingBase::ProgramBindingBase()
18 : m_program(0)
19 , m_vertexShaderId(0)
20 , m_fragmentShaderId(0)
21 , m_initialized(false)
25 ProgramBindingBase::~ProgramBindingBase()
27 // If you hit these asserts, you initialized but forgot to call cleanup().
28 DCHECK(!m_program);
29 DCHECK(!m_vertexShaderId);
30 DCHECK(!m_fragmentShaderId);
31 DCHECK(!m_initialized);
34 void ProgramBindingBase::init(WebGraphicsContext3D* context, const std::string& vertexShader, const std::string& fragmentShader)
36 TRACE_EVENT0("cc", "ProgramBindingBase::init");
37 m_vertexShaderId = loadShader(context, GL_VERTEX_SHADER, vertexShader);
38 if (!m_vertexShaderId) {
39 if (!IsContextLost(context))
40 LOG(ERROR) << "Failed to create vertex shader";
41 return;
44 m_fragmentShaderId = loadShader(context, GL_FRAGMENT_SHADER, fragmentShader);
45 if (!m_fragmentShaderId) {
46 GLC(context, context->deleteShader(m_vertexShaderId));
47 m_vertexShaderId = 0;
48 if (!IsContextLost(context))
49 LOG(ERROR) << "Failed to create fragment shader";
50 return;
53 m_program = createShaderProgram(context, m_vertexShaderId, m_fragmentShaderId);
54 DCHECK(m_program || IsContextLost(context));
57 void ProgramBindingBase::link(WebGraphicsContext3D* context)
59 GLC(context, context->linkProgram(m_program));
60 cleanupShaders(context);
61 #ifndef NDEBUG
62 int linked = 0;
63 GLC(context, context->getProgramiv(m_program, GL_LINK_STATUS, &linked));
64 if (!linked) {
65 if (!IsContextLost(context))
66 LOG(ERROR) << "Failed to link shader program";
67 GLC(context, context->deleteProgram(m_program));
69 #endif
72 void ProgramBindingBase::cleanup(WebGraphicsContext3D* context)
74 m_initialized = false;
75 if (!m_program)
76 return;
78 DCHECK(context);
79 GLC(context, context->deleteProgram(m_program));
80 m_program = 0;
82 cleanupShaders(context);
85 unsigned ProgramBindingBase::loadShader(WebGraphicsContext3D* context, unsigned type, const std::string& shaderSource)
87 unsigned shader = context->createShader(type);
88 if (!shader)
89 return 0;
90 GLC(context, context->shaderSource(shader, shaderSource.data()));
91 GLC(context, context->compileShader(shader));
92 #ifndef NDEBUG
93 int compiled = 0;
94 GLC(context, context->getShaderiv(shader, GL_COMPILE_STATUS, &compiled));
95 if (!compiled) {
96 GLC(context, context->deleteShader(shader));
97 return 0;
99 #endif
100 return shader;
103 unsigned ProgramBindingBase::createShaderProgram(WebGraphicsContext3D* context, unsigned vertexShader, unsigned fragmentShader)
105 unsigned programObject = context->createProgram();
106 if (!programObject) {
107 if (!IsContextLost(context))
108 LOG(ERROR) << "Failed to create shader program";
109 return 0;
112 GLC(context, context->attachShader(programObject, vertexShader));
113 GLC(context, context->attachShader(programObject, fragmentShader));
115 // Bind the common attrib locations.
116 GLC(context, context->bindAttribLocation(programObject, GeometryBinding::positionAttribLocation(), "a_position"));
117 GLC(context, context->bindAttribLocation(programObject, GeometryBinding::texCoordAttribLocation(), "a_texCoord"));
119 return programObject;
122 void ProgramBindingBase::cleanupShaders(WebGraphicsContext3D* context)
124 if (m_vertexShaderId) {
125 GLC(context, context->deleteShader(m_vertexShaderId));
126 m_vertexShaderId = 0;
128 if (m_fragmentShaderId) {
129 GLC(context, context->deleteShader(m_fragmentShaderId));
130 m_fragmentShaderId = 0;
134 bool ProgramBindingBase::IsContextLost(WebGraphicsContext3D* context) {
135 return (context->getGraphicsResetStatusARB() != GL_NO_ERROR);
138 } // namespace cc