ProgramBinding.cpp [plain text]
#include "config.h"
#if USE(ACCELERATED_COMPOSITING)
#include "ProgramBinding.h"
#include "GeometryBinding.h"
#include "GraphicsContext.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
#include "TraceEvent.h"
namespace WebCore {
ProgramBindingBase::ProgramBindingBase()
: m_program(0)
, m_initialized(false)
{
}
ProgramBindingBase::~ProgramBindingBase()
{
ASSERT(!m_program);
ASSERT(!m_initialized);
}
void ProgramBindingBase::init(GraphicsContext3D* context, const String& vertexShader, const String& fragmentShader)
{
m_program = createShaderProgram(context, vertexShader, fragmentShader);
ASSERT(m_program);
}
void ProgramBindingBase::cleanup(GraphicsContext3D* context)
{
m_initialized = false;
if (!m_program)
return;
ASSERT(context);
GLC(context, context->deleteProgram(m_program));
m_program = 0;
}
unsigned ProgramBindingBase::loadShader(GraphicsContext3D* context, unsigned type, const String& shaderSource)
{
unsigned shader = context->createShader(type);
if (!shader)
return 0;
String sourceString(shaderSource);
GLC(context, context->shaderSource(shader, sourceString));
GLC(context, context->compileShader(shader));
#ifndef NDEBUG
int compiled = 0;
GLC(context, context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled));
if (!compiled) {
GLC(context, context->deleteShader(shader));
return 0;
}
#endif
return shader;
}
unsigned ProgramBindingBase::createShaderProgram(GraphicsContext3D* context, const String& vertexShaderSource, const String& fragmentShaderSource)
{
TRACE_EVENT("ProgramBindingBase::createShaderProgram", this, 0);
unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource);
if (!vertexShader) {
LOG_ERROR("Failed to create vertex shader");
return 0;
}
unsigned fragmentShader = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource);
if (!fragmentShader) {
GLC(context, context->deleteShader(vertexShader));
LOG_ERROR("Failed to create fragment shader");
return 0;
}
unsigned programObject = context->createProgram();
if (!programObject) {
LOG_ERROR("Failed to create shader program");
return 0;
}
GLC(context, context->attachShader(programObject, vertexShader));
GLC(context, context->attachShader(programObject, fragmentShader));
GLC(context, context->bindAttribLocation(programObject, GeometryBinding::positionAttribLocation(), "a_position"));
GLC(context, context->bindAttribLocation(programObject, GeometryBinding::texCoordAttribLocation(), "a_texCoord"));
GLC(context, context->linkProgram(programObject));
#ifndef NDEBUG
int linked = 0;
GLC(context, context->getProgramiv(programObject, GraphicsContext3D::LINK_STATUS, &linked));
if (!linked) {
LOG_ERROR("Failed to link shader program");
GLC(context, context->deleteProgram(programObject));
return 0;
}
#endif
GLC(context, context->deleteShader(vertexShader));
GLC(context, context->deleteShader(fragmentShader));
return programObject;
}
}
#endif // USE(ACCELERATED_COMPOSITING)