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 #include "core/platform/graphics/filters/custom/CustomFilterCompiledProgram.h" 33 34 namespace WebCore { 35 36 CustomFilterCompiledProgram::CustomFilterCompiledProgram(PassRefPtr<GraphicsContext3D> context, const String& validatedVertexShader, const String& validatedFragmentShader, CustomFilterProgramType programType) 37 : m_context(context) 38 , m_program(0) 39 , m_positionAttribLocation(-1) 40 , m_texAttribLocation(-1) 41 , m_meshAttribLocation(-1) 42 , m_triangleAttribLocation(-1) 43 , m_meshBoxLocation(-1) 44 , m_projectionMatrixLocation(-1) 45 , m_tileSizeLocation(-1) 46 , m_meshSizeLocation(-1) 47 , m_samplerLocation(-1) 48 , m_samplerSizeLocation(-1) 49 , m_contentSamplerLocation(-1) 50 , m_isInitialized(false) 51 { 52 m_context->makeContextCurrent(); 53 54 Platform3DObject vertexShader = compileShader(GraphicsContext3D::VERTEX_SHADER, validatedVertexShader); 55 if (!vertexShader) 56 return; 57 58 Platform3DObject fragmentShader = compileShader(GraphicsContext3D::FRAGMENT_SHADER, validatedFragmentShader); 59 if (!fragmentShader) { 60 m_context->deleteShader(vertexShader); 61 return; 62 } 63 64 m_program = linkProgram(vertexShader, fragmentShader); 65 66 m_context->deleteShader(vertexShader); 67 m_context->deleteShader(fragmentShader); 68 69 if (!m_program) 70 return; 71 72 initializeParameterLocations(programType); 73 74 m_isInitialized = true; 75 } 76 77 Platform3DObject CustomFilterCompiledProgram::compileShader(GC3Denum shaderType, const String& shaderString) 78 { 79 ASSERT(!shaderString.isNull()); 80 81 Platform3DObject shader = m_context->createShader(shaderType); 82 m_context->shaderSource(shader, shaderString); 83 m_context->compileShader(shader); 84 85 int compiled = 0; 86 m_context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled); 87 if (!compiled) { 88 // FIXME: This is an invalid shader. Throw some errors. 89 // https://bugs.webkit.org/show_bug.cgi?id=74416 90 m_context->deleteShader(shader); 91 return 0; 92 } 93 94 return shader; 95 } 96 97 Platform3DObject CustomFilterCompiledProgram::linkProgram(Platform3DObject vertexShader, Platform3DObject fragmentShader) 98 { 99 Platform3DObject program = m_context->createProgram(); 100 m_context->attachShader(program, vertexShader); 101 m_context->attachShader(program, fragmentShader); 102 m_context->linkProgram(program); 103 104 int linked = 0; 105 m_context->getProgramiv(program, GraphicsContext3D::LINK_STATUS, &linked); 106 if (!linked) { 107 // FIXME: Invalid vertex/fragment shader combination. Throw some errors here. 108 // https://bugs.webkit.org/show_bug.cgi?id=74416 109 m_context->deleteProgram(program); 110 return 0; 111 } 112 113 return program; 114 } 115 116 void CustomFilterCompiledProgram::initializeParameterLocations(CustomFilterProgramType programType) 117 { 118 m_positionAttribLocation = m_context->getAttribLocation(m_program, "a_position"); 119 m_texAttribLocation = m_context->getAttribLocation(m_program, "a_texCoord"); 120 m_meshAttribLocation = m_context->getAttribLocation(m_program, "a_meshCoord"); 121 m_triangleAttribLocation = m_context->getAttribLocation(m_program, "a_triangleCoord"); 122 m_meshBoxLocation = m_context->getUniformLocation(m_program, "u_meshBox"); 123 m_tileSizeLocation = m_context->getUniformLocation(m_program, "u_tileSize"); 124 m_meshSizeLocation = m_context->getUniformLocation(m_program, "u_meshSize"); 125 m_projectionMatrixLocation = m_context->getUniformLocation(m_program, "u_projectionMatrix"); 126 m_samplerSizeLocation = m_context->getUniformLocation(m_program, "u_textureSize"); 127 m_contentSamplerLocation = m_context->getUniformLocation(m_program, "u_contentTexture"); 128 if (programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE) { 129 // When the author uses the CSS mix function in a custom filter, WebKit adds the internal 130 // symbol css_u_texture to the shader code, which references the texture of the element. 131 m_samplerLocation = m_context->getUniformLocation(m_program, "css_u_texture"); 132 } 133 } 134 135 int CustomFilterCompiledProgram::uniformLocationByName(const String& name) 136 { 137 ASSERT(m_isInitialized); 138 // FIXME: Improve this by caching the uniform locations. 139 return m_context->getUniformLocation(m_program, name); 140 } 141 142 CustomFilterCompiledProgram::~CustomFilterCompiledProgram() 143 { 144 if (m_program) { 145 m_context->makeContextCurrent(); 146 m_context->deleteProgram(m_program); 147 } 148 } 149 150 } // namespace WebCore 151