| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "config.h" | |
| 6 | |
| 7 #if USE(ACCELERATED_COMPOSITING) | |
| 8 | |
| 9 #include "ProgramBinding.h" | |
| 10 | |
| 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> | |
| 16 | |
| 17 using WebKit::WebGraphicsContext3D; | |
| 18 | |
| 19 namespace cc { | |
| 20 | |
| 21 ProgramBindingBase::ProgramBindingBase() | |
| 22 : m_program(0) | |
| 23 , m_vertexShaderId(0) | |
| 24 , m_fragmentShaderId(0) | |
| 25 , m_initialized(false) | |
| 26 { | |
| 27 } | |
| 28 | |
| 29 ProgramBindingBase::~ProgramBindingBase() | |
| 30 { | |
| 31 // If you hit these asserts, you initialized but forgot to call cleanup(). | |
| 32 ASSERT(!m_program); | |
| 33 ASSERT(!m_vertexShaderId); | |
| 34 ASSERT(!m_fragmentShaderId); | |
| 35 ASSERT(!m_initialized); | |
| 36 } | |
| 37 | |
| 38 static bool contextLost(WebGraphicsContext3D* context) | |
| 39 { | |
| 40 return (context->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR)
; | |
| 41 } | |
| 42 | |
| 43 | |
| 44 void ProgramBindingBase::init(WebGraphicsContext3D* context, const std::string&
vertexShader, const std::string& fragmentShader) | |
| 45 { | |
| 46 TRACE_EVENT0("cc", "ProgramBindingBase::init"); | |
| 47 m_vertexShaderId = loadShader(context, GraphicsContext3D::VERTEX_SHADER, ver
texShader); | |
| 48 if (!m_vertexShaderId) { | |
| 49 if (!contextLost(context)) | |
| 50 LOG_ERROR("Failed to create vertex shader"); | |
| 51 return; | |
| 52 } | |
| 53 | |
| 54 m_fragmentShaderId = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER,
fragmentShader); | |
| 55 if (!m_fragmentShaderId) { | |
| 56 GLC(context, context->deleteShader(m_vertexShaderId)); | |
| 57 m_vertexShaderId = 0; | |
| 58 if (!contextLost(context)) | |
| 59 LOG_ERROR("Failed to create fragment shader"); | |
| 60 return; | |
| 61 } | |
| 62 | |
| 63 m_program = createShaderProgram(context, m_vertexShaderId, m_fragmentShaderI
d); | |
| 64 ASSERT(m_program || contextLost(context)); | |
| 65 } | |
| 66 | |
| 67 void ProgramBindingBase::link(WebGraphicsContext3D* context) | |
| 68 { | |
| 69 GLC(context, context->linkProgram(m_program)); | |
| 70 cleanupShaders(context); | |
| 71 #ifndef NDEBUG | |
| 72 int linked = 0; | |
| 73 GLC(context, context->getProgramiv(m_program, GraphicsContext3D::LINK_STATUS
, &linked)); | |
| 74 if (!linked) { | |
| 75 if (!contextLost(context)) | |
| 76 LOG_ERROR("Failed to link shader program"); | |
| 77 GLC(context, context->deleteProgram(m_program)); | |
| 78 return; | |
| 79 } | |
| 80 #endif | |
| 81 } | |
| 82 | |
| 83 void ProgramBindingBase::cleanup(WebGraphicsContext3D* context) | |
| 84 { | |
| 85 m_initialized = false; | |
| 86 if (!m_program) | |
| 87 return; | |
| 88 | |
| 89 ASSERT(context); | |
| 90 GLC(context, context->deleteProgram(m_program)); | |
| 91 m_program = 0; | |
| 92 | |
| 93 cleanupShaders(context); | |
| 94 } | |
| 95 | |
| 96 unsigned ProgramBindingBase::loadShader(WebGraphicsContext3D* context, unsigned
type, const std::string& shaderSource) | |
| 97 { | |
| 98 unsigned shader = context->createShader(type); | |
| 99 if (!shader) | |
| 100 return 0; | |
| 101 GLC(context, context->shaderSource(shader, shaderSource.data())); | |
| 102 GLC(context, context->compileShader(shader)); | |
| 103 #ifndef NDEBUG | |
| 104 int compiled = 0; | |
| 105 GLC(context, context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS,
&compiled)); | |
| 106 if (!compiled) { | |
| 107 GLC(context, context->deleteShader(shader)); | |
| 108 return 0; | |
| 109 } | |
| 110 #endif | |
| 111 return shader; | |
| 112 } | |
| 113 | |
| 114 unsigned ProgramBindingBase::createShaderProgram(WebGraphicsContext3D* context,
unsigned vertexShader, unsigned fragmentShader) | |
| 115 { | |
| 116 unsigned programObject = context->createProgram(); | |
| 117 if (!programObject) { | |
| 118 if (!contextLost(context)) | |
| 119 LOG_ERROR("Failed to create shader program"); | |
| 120 return 0; | |
| 121 } | |
| 122 | |
| 123 GLC(context, context->attachShader(programObject, vertexShader)); | |
| 124 GLC(context, context->attachShader(programObject, fragmentShader)); | |
| 125 | |
| 126 // Bind the common attrib locations. | |
| 127 GLC(context, context->bindAttribLocation(programObject, GeometryBinding::pos
itionAttribLocation(), "a_position")); | |
| 128 GLC(context, context->bindAttribLocation(programObject, GeometryBinding::tex
CoordAttribLocation(), "a_texCoord")); | |
| 129 | |
| 130 return programObject; | |
| 131 } | |
| 132 | |
| 133 void ProgramBindingBase::cleanupShaders(WebGraphicsContext3D* context) | |
| 134 { | |
| 135 if (m_vertexShaderId) { | |
| 136 GLC(context, context->deleteShader(m_vertexShaderId)); | |
| 137 m_vertexShaderId = 0; | |
| 138 } | |
| 139 if (m_fragmentShaderId) { | |
| 140 GLC(context, context->deleteShader(m_fragmentShaderId)); | |
| 141 m_fragmentShaderId = 0; | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 } // namespace cc | |
| 146 | |
| 147 #endif // USE(ACCELERATED_COMPOSITING) | |
| OLD | NEW |