summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp')
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp126
1 files changed, 106 insertions, 20 deletions
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
index 72ad8ff4c..770a5e5e5 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
@@ -34,6 +34,7 @@
#include "CustomFilterValidatedProgram.h"
#include "ANGLEWebKitBridge.h"
+#include "CustomFilterCompiledProgram.h"
#include "CustomFilterConstants.h"
#include "CustomFilterGlobalContext.h"
#include "CustomFilterProgramInfo.h"
@@ -158,8 +159,7 @@ String CustomFilterValidatedProgram::defaultFragmentShaderString()
}
CustomFilterValidatedProgram::CustomFilterValidatedProgram(CustomFilterGlobalContext* globalContext, const CustomFilterProgramInfo& programInfo)
- : m_globalContext(globalContext)
- , m_programInfo(programInfo)
+ : m_programInfo(programInfo)
, m_isInitialized(false)
{
platformInit();
@@ -174,7 +174,7 @@ CustomFilterValidatedProgram::CustomFilterValidatedProgram(CustomFilterGlobalCon
// Shaders referenced from the CSS mix function use a different validator than regular WebGL shaders. See CustomFilterGlobalContext.h for more details.
bool blendsElementTexture = (programInfo.programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
- ANGLEWebKitBridge* validator = blendsElementTexture ? m_globalContext->mixShaderValidator() : m_globalContext->webglShaderValidator();
+ ANGLEWebKitBridge* validator = blendsElementTexture ? globalContext->mixShaderValidator() : globalContext->webglShaderValidator();
String vertexShaderLog, fragmentShaderLog;
Vector<ANGLEShaderSymbol> symbols;
bool vertexShaderValid = validator->compileShaderSource(originalVertexShader.utf8().data(), SHADER_TYPE_VERTEX, m_validatedVertexShader, vertexShaderLog, symbols);
@@ -202,14 +202,14 @@ CustomFilterValidatedProgram::CustomFilterValidatedProgram(CustomFilterGlobalCon
PassRefPtr<CustomFilterCompiledProgram> CustomFilterValidatedProgram::compiledProgram()
{
- ASSERT(m_isInitialized && m_globalContext && !m_validatedVertexShader.isNull() && !m_validatedFragmentShader.isNull());
- if (!m_compiledProgram) {
- m_compiledProgram = CustomFilterCompiledProgram::create(m_globalContext->context(), m_validatedVertexShader, m_validatedFragmentShader, m_programInfo.programType());
- ASSERT(m_compiledProgram->samplerLocation() != -1 || !needsInputTexture());
- }
return m_compiledProgram;
}
+void CustomFilterValidatedProgram::setCompiledProgram(PassRefPtr<CustomFilterCompiledProgram> compiledProgram)
+{
+ m_compiledProgram = compiledProgram;
+}
+
bool CustomFilterValidatedProgram::needsInputTexture() const
{
return m_programInfo.programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE
@@ -273,9 +273,11 @@ void CustomFilterValidatedProgram::rewriteMixFragmentShader()
{
css_main();
mediump vec4 originalColor = texture2D(css_u_texture, css_v_texCoord);
- mediump vec4 multipliedColor = css_ColorMatrix * originalColor;
- mediump vec3 blendedColor = css_BlendColor(multipliedColor.rgb, css_MixColor.rgb);
- gl_FragColor = css_Composite(multipliedColor.rgb, multipliedColor.a, blendedColor.rgb, css_MixColor.a);
+ mediump vec4 multipliedColor = clamp(css_ColorMatrix * originalColor, 0.0, 1.0);
+ mediump vec4 clampedMixColor = clamp(css_MixColor, 0.0, 1.0);
+ mediump vec3 blendedColor = css_BlendColor(multipliedColor.rgb, clampedMixColor.rgb);
+ mediump vec3 weightedColor = (1.0 - multipliedColor.a) * clampedMixColor.rgb + multipliedColor.a * blendedColor;
+ gl_FragColor = css_Composite(multipliedColor.rgb, multipliedColor.a, weightedColor.rgb, clampedMixColor.a);
}
));
m_validatedFragmentShader = builder.toString();
@@ -289,6 +291,9 @@ String CustomFilterValidatedProgram::blendFunctionString(BlendMode blendMode)
// Cb: is the backdrop color in css_BlendColor() and the backdrop color component in css_BlendComponent()
const char* blendColorExpression = "vec3(css_BlendComponent(Cb.r, Cs.r), css_BlendComponent(Cb.g, Cs.g), css_BlendComponent(Cb.b, Cs.b))";
const char* blendComponentExpression = "Co = 0.0;";
+ bool needsLuminosityHelperFunctions = false;
+ bool needsSaturationHelperFunctions = false;
+ String blendFunctionString;
switch (blendMode) {
case BlendModeNormal:
blendColorExpression = "Cs";
@@ -403,15 +408,97 @@ String CustomFilterValidatedProgram::blendFunctionString(BlendMode blendMode)
Co = Cb + (2.0 * Cs - 1.0) * (D - Cb);
);
break;
- case BlendModeHue:
- case BlendModeSaturation:
case BlendModeColor:
+ needsLuminosityHelperFunctions = true;
+ blendColorExpression = "css_SetLum(Cs, css_Lum(Cb))";
+ break;
case BlendModeLuminosity:
- notImplemented();
- return String();
+ needsLuminosityHelperFunctions = true;
+ blendColorExpression = "css_SetLum(Cb, css_Lum(Cs))";
+ break;
+ case BlendModeHue:
+ needsLuminosityHelperFunctions = true;
+ needsSaturationHelperFunctions = true;
+ blendColorExpression = "css_SetLum(css_SetSat(Cs, css_Sat(Cb)), css_Lum(Cb))";
+ break;
+ case BlendModeSaturation:
+ needsLuminosityHelperFunctions = true;
+ needsSaturationHelperFunctions = true;
+ blendColorExpression = "css_SetLum(css_SetSat(Cb, css_Sat(Cs)), css_Lum(Cb))";
+ break;
+ default:
+ ASSERT_NOT_REACHED();
}
- return String::format(SHADER(
+ if (needsLuminosityHelperFunctions) {
+ blendFunctionString.append(SHADER(
+ mediump float css_Lum(mediump vec3 C)
+ {
+ return 0.3 * C.r + 0.59 * C.g + 0.11 * C.b;
+ }
+ mediump vec3 css_ClipColor(mediump vec3 C)
+ {
+ mediump float L = css_Lum(C);
+ mediump float n = min(min(C.r, C.g), C.b);
+ mediump float x = max(max(C.r, C.g), C.b);
+ if (n < 0.0)
+ C = L + (((C - L) * L) / (L - n));
+ if (x > 1.0)
+ C = L + (((C - L) * (1.0 - L) / (x - L)));
+ return C;
+ }
+ mediump vec3 css_SetLum(mediump vec3 C, mediump float l)
+ {
+ C += l - css_Lum(C);
+ return css_ClipColor(C);
+ }
+ ));
+ }
+
+ if (needsSaturationHelperFunctions) {
+ blendFunctionString.append(SHADER(
+ mediump float css_Sat(mediump vec3 C)
+ {
+ mediump float cMin = min(min(C.r, C.g), C.b);
+ mediump float cMax = max(max(C.r, C.g), C.b);
+ return cMax - cMin;
+ }
+ void css_SetSatHelper(inout mediump float cMin, inout mediump float cMid, inout mediump float cMax, mediump float s)
+ {
+ if (cMax > cMin) {
+ cMid = (((cMid - cMin) * s) / (cMax - cMin));
+ cMax = s;
+ } else
+ cMid = cMax = 0.0;
+ cMin = 0.0;
+ }
+ mediump vec3 css_SetSat(mediump vec3 C, mediump float s)
+ {
+ if (C.r <= C.g) {
+ if (C.g <= C.b)
+ css_SetSatHelper(C.r, C.g, C.b, s);
+ else {
+ if (C.r <= C.b)
+ css_SetSatHelper(C.r, C.b, C.g, s);
+ else
+ css_SetSatHelper(C.b, C.r, C.g, s);
+ }
+ } else {
+ if (C.r <= C.b)
+ css_SetSatHelper(C.g, C.r, C.b, s);
+ else {
+ if (C.g <= C.b)
+ css_SetSatHelper(C.g, C.b, C.r, s);
+ else
+ css_SetSatHelper(C.b, C.g, C.r, s);
+ }
+ }
+ return C;
+ }
+ ));
+ }
+
+ blendFunctionString.append(String::format(SHADER(
mediump float css_BlendComponent(mediump float Cb, mediump float Cs)
{
mediump float Co;
@@ -422,7 +509,9 @@ String CustomFilterValidatedProgram::blendFunctionString(BlendMode blendMode)
{
return %s;
}
- ), blendComponentExpression, blendColorExpression);
+ ), blendComponentExpression, blendColorExpression));
+
+ return blendFunctionString;
}
String CustomFilterValidatedProgram::compositeFunctionString(CompositeOperator compositeOperator)
@@ -507,9 +596,6 @@ String CustomFilterValidatedProgram::compositeFunctionString(CompositeOperator c
CustomFilterValidatedProgram::~CustomFilterValidatedProgram()
{
platformDestroy();
-
- if (m_globalContext)
- m_globalContext->removeValidatedProgram(this);
}
CustomFilterProgramInfo CustomFilterValidatedProgram::validatedProgramInfo() const