1/* 2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following 13 * disclaimer in the documentation and/or other materials 14 * provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 26 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include "config.h" 31 32#if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS) 33#include "CustomFilterCompiledProgram.h" 34 35#include "CustomFilterGlobalContext.h" 36 37namespace WebCore { 38 39CustomFilterCompiledProgram::CustomFilterCompiledProgram(PassRefPtr<GraphicsContext3D> context, const String& validatedVertexShader, const String& validatedFragmentShader, CustomFilterProgramType programType) 40 : m_context(context) 41 , m_program(0) 42 , m_positionAttribLocation(-1) 43 , m_texAttribLocation(-1) 44 , m_meshAttribLocation(-1) 45 , m_triangleAttribLocation(-1) 46 , m_meshBoxLocation(-1) 47 , m_projectionMatrixLocation(-1) 48 , m_tileSizeLocation(-1) 49 , m_meshSizeLocation(-1) 50 , m_samplerLocation(-1) 51 , m_samplerSizeLocation(-1) 52 , m_contentSamplerLocation(-1) 53 , m_isInitialized(false) 54{ 55 ASSERT(!validatedVertexShader.isNull() && !validatedFragmentShader.isNull()); 56 57 m_context->makeContextCurrent(); 58 59 Platform3DObject vertexShader = compileShader(GraphicsContext3D::VERTEX_SHADER, validatedVertexShader); 60 if (!vertexShader) 61 return; 62 63 Platform3DObject fragmentShader = compileShader(GraphicsContext3D::FRAGMENT_SHADER, validatedFragmentShader); 64 if (!fragmentShader) { 65 m_context->deleteShader(vertexShader); 66 return; 67 } 68 69 m_program = linkProgram(vertexShader, fragmentShader); 70 71 m_context->deleteShader(vertexShader); 72 m_context->deleteShader(fragmentShader); 73 74 if (!m_program) 75 return; 76 77 initializeParameterLocations(programType); 78 79 m_isInitialized = true; 80} 81 82Platform3DObject CustomFilterCompiledProgram::compileShader(GC3Denum shaderType, const String& shaderString) 83{ 84 ASSERT(!shaderString.isNull()); 85 86 Platform3DObject shader = m_context->createShader(shaderType); 87 m_context->shaderSource(shader, shaderString); 88 m_context->compileShader(shader); 89 90 int compiled = 0; 91 m_context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled); 92 if (!compiled) { 93 // FIXME: This is an invalid shader. Throw some errors. 94 // https://bugs.webkit.org/show_bug.cgi?id=74416 95 m_context->deleteShader(shader); 96 return 0; 97 } 98 99 return shader; 100} 101 102Platform3DObject CustomFilterCompiledProgram::linkProgram(Platform3DObject vertexShader, Platform3DObject fragmentShader) 103{ 104 Platform3DObject program = m_context->createProgram(); 105 m_context->attachShader(program, vertexShader); 106 m_context->attachShader(program, fragmentShader); 107 m_context->linkProgram(program); 108 109 int linked = 0; 110 m_context->getProgramiv(program, GraphicsContext3D::LINK_STATUS, &linked); 111 if (!linked) { 112 // FIXME: Invalid vertex/fragment shader combination. Throw some errors here. 113 // https://bugs.webkit.org/show_bug.cgi?id=74416 114 m_context->deleteProgram(program); 115 return 0; 116 } 117 118 return program; 119} 120 121void CustomFilterCompiledProgram::initializeParameterLocations(CustomFilterProgramType programType) 122{ 123 m_positionAttribLocation = m_context->getAttribLocation(m_program, "a_position"); 124 m_texAttribLocation = m_context->getAttribLocation(m_program, "a_texCoord"); 125 m_meshAttribLocation = m_context->getAttribLocation(m_program, "a_meshCoord"); 126 m_triangleAttribLocation = m_context->getAttribLocation(m_program, "a_triangleCoord"); 127 m_meshBoxLocation = m_context->getUniformLocation(m_program, "u_meshBox"); 128 m_tileSizeLocation = m_context->getUniformLocation(m_program, "u_tileSize"); 129 m_meshSizeLocation = m_context->getUniformLocation(m_program, "u_meshSize"); 130 m_projectionMatrixLocation = m_context->getUniformLocation(m_program, "u_projectionMatrix"); 131 m_samplerSizeLocation = m_context->getUniformLocation(m_program, "u_textureSize"); 132 m_contentSamplerLocation = m_context->getUniformLocation(m_program, "u_contentTexture"); 133 if (programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE) { 134 // When the author uses the CSS mix function in a custom filter, WebKit adds the internal 135 // symbol css_u_texture to the shader code, which references the texture of the element. 136 m_samplerLocation = m_context->getUniformLocation(m_program, "css_u_texture"); 137 } 138} 139 140int CustomFilterCompiledProgram::uniformLocationByName(const String& name) 141{ 142 ASSERT(m_isInitialized); 143 // FIXME: Improve this by caching the uniform locations. 144 return m_context->getUniformLocation(m_program, name); 145} 146 147CustomFilterCompiledProgram::~CustomFilterCompiledProgram() 148{ 149 if (m_program) { 150 m_context->makeContextCurrent(); 151 m_context->deleteProgram(m_program); 152 } 153} 154 155} // namespace WebCore 156#endif // ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS) 157