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.
7 #if USE(ACCELERATED_COMPOSITING)
9 #include "ProgramBinding.h"
11 #include "CCRendererGL.h" // For the GLC() macro.
12 #include "GeometryBinding.h"
13 #include "GraphicsContext3D.h"
14 #include "TraceEvent.h"
15 #include <public/WebGraphicsContext3D.h>
17 using WebKit::WebGraphicsContext3D
;
21 ProgramBindingBase::ProgramBindingBase()
24 , m_fragmentShaderId(0)
25 , m_initialized(false)
29 ProgramBindingBase::~ProgramBindingBase()
31 // If you hit these asserts, you initialized but forgot to call cleanup().
33 ASSERT(!m_vertexShaderId
);
34 ASSERT(!m_fragmentShaderId
);
35 ASSERT(!m_initialized
);
38 static bool contextLost(WebGraphicsContext3D
* context
)
40 return (context
->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR
);
44 void ProgramBindingBase::init(WebGraphicsContext3D
* context
, const std::string
& vertexShader
, const std::string
& fragmentShader
)
46 TRACE_EVENT0("cc", "ProgramBindingBase::init");
47 m_vertexShaderId
= loadShader(context
, GraphicsContext3D::VERTEX_SHADER
, vertexShader
);
48 if (!m_vertexShaderId
) {
49 if (!contextLost(context
))
50 LOG_ERROR("Failed to create vertex shader");
54 m_fragmentShaderId
= loadShader(context
, GraphicsContext3D::FRAGMENT_SHADER
, fragmentShader
);
55 if (!m_fragmentShaderId
) {
56 GLC(context
, context
->deleteShader(m_vertexShaderId
));
58 if (!contextLost(context
))
59 LOG_ERROR("Failed to create fragment shader");
63 m_program
= createShaderProgram(context
, m_vertexShaderId
, m_fragmentShaderId
);
64 ASSERT(m_program
|| contextLost(context
));
67 void ProgramBindingBase::link(WebGraphicsContext3D
* context
)
69 GLC(context
, context
->linkProgram(m_program
));
70 cleanupShaders(context
);
73 GLC(context
, context
->getProgramiv(m_program
, GraphicsContext3D::LINK_STATUS
, &linked
));
75 if (!contextLost(context
))
76 LOG_ERROR("Failed to link shader program");
77 GLC(context
, context
->deleteProgram(m_program
));
83 void ProgramBindingBase::cleanup(WebGraphicsContext3D
* context
)
85 m_initialized
= false;
90 GLC(context
, context
->deleteProgram(m_program
));
93 cleanupShaders(context
);
96 unsigned ProgramBindingBase::loadShader(WebGraphicsContext3D
* context
, unsigned type
, const std::string
& shaderSource
)
98 unsigned shader
= context
->createShader(type
);
101 GLC(context
, context
->shaderSource(shader
, shaderSource
.data()));
102 GLC(context
, context
->compileShader(shader
));
105 GLC(context
, context
->getShaderiv(shader
, GraphicsContext3D::COMPILE_STATUS
, &compiled
));
107 GLC(context
, context
->deleteShader(shader
));
114 unsigned ProgramBindingBase::createShaderProgram(WebGraphicsContext3D
* context
, unsigned vertexShader
, unsigned fragmentShader
)
116 unsigned programObject
= context
->createProgram();
117 if (!programObject
) {
118 if (!contextLost(context
))
119 LOG_ERROR("Failed to create shader program");
123 GLC(context
, context
->attachShader(programObject
, vertexShader
));
124 GLC(context
, context
->attachShader(programObject
, fragmentShader
));
126 // Bind the common attrib locations.
127 GLC(context
, context
->bindAttribLocation(programObject
, GeometryBinding::positionAttribLocation(), "a_position"));
128 GLC(context
, context
->bindAttribLocation(programObject
, GeometryBinding::texCoordAttribLocation(), "a_texCoord"));
130 return programObject
;
133 void ProgramBindingBase::cleanupShaders(WebGraphicsContext3D
* context
)
135 if (m_vertexShaderId
) {
136 GLC(context
, context
->deleteShader(m_vertexShaderId
));
137 m_vertexShaderId
= 0;
139 if (m_fragmentShaderId
) {
140 GLC(context
, context
->deleteShader(m_fragmentShaderId
));
141 m_fragmentShaderId
= 0;
147 #endif // USE(ACCELERATED_COMPOSITING)