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