summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/graphics/gpu/opencl/OpenCLFEColorMatrix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics/gpu/opencl/OpenCLFEColorMatrix.cpp')
-rw-r--r--Source/WebCore/platform/graphics/gpu/opencl/OpenCLFEColorMatrix.cpp156
1 files changed, 156 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/gpu/opencl/OpenCLFEColorMatrix.cpp b/Source/WebCore/platform/graphics/gpu/opencl/OpenCLFEColorMatrix.cpp
new file mode 100644
index 000000000..c6c34bdb5
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/opencl/OpenCLFEColorMatrix.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2012 University of Szeged
+ * Copyright (C) 2012 Tamas Czene <tczene@inf.u-szeged.hu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS) && ENABLE(OPENCL)
+#include "FEColorMatrix.h"
+
+#include "FilterContextOpenCL.h"
+
+namespace WebCore {
+
+#define COLOR_MATRIX_KERNEL(...) \
+ int2 sourceCoord = (int2) (get_global_id(0) + x, get_global_id(1) + y); \
+ float4 sourcePixel = read_imagef(source, sampler, sourceCoord); \
+ float4 destinationPixel = (float4) (__VA_ARGS__); \
+ write_imagef(destination, (int2) (get_global_id(0), get_global_id(1)), destinationPixel);
+
+static const char* colorMatrixKernelProgram =
+PROGRAM(
+const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
+
+__kernel void matrix(__write_only image2d_t destination, __read_only image2d_t source, float x, float y, __constant float *values)
+{
+ COLOR_MATRIX_KERNEL(values[0] * sourcePixel.x + values[1] * sourcePixel.y + values[2] * sourcePixel.z + values[3] * sourcePixel.w + values[4],
+ values[5] * sourcePixel.x + values[6] * sourcePixel.y + values[7] * sourcePixel.z + values[8] * sourcePixel.w + values[9],
+ values[10] * sourcePixel.x + values[11] * sourcePixel.y + values[12] * sourcePixel.z + values[13] * sourcePixel.w + values[14],
+ values[15] * sourcePixel.x + values[16] * sourcePixel.y + values[17] * sourcePixel.z + values[18] * sourcePixel.w + values[19])
+}
+
+__kernel void saturateAndHueRotate(__write_only image2d_t destination, __read_only image2d_t source, float x, float y, __constant float *components)
+{
+ COLOR_MATRIX_KERNEL(sourcePixel.x * components[0] + sourcePixel.y * components[1] + sourcePixel.z * components[2],
+ sourcePixel.x * components[3] + sourcePixel.y * components[4] + sourcePixel.z * components[5],
+ sourcePixel.x * components[6] + sourcePixel.y * components[7] + sourcePixel.z * components[8],
+ sourcePixel.w)
+}
+
+__kernel void luminance(__write_only image2d_t destination, __read_only image2d_t source, float x, float y)
+{
+ COLOR_MATRIX_KERNEL(0, 0, 0, 0.2125 * sourcePixel.x + 0.7154 * sourcePixel.y + 0.0721 * sourcePixel.z)
+}
+); // End of OpenCL kernels
+
+inline bool FilterContextOpenCL::compileFEColorMatrix()
+{
+ if (m_colorMatrixWasCompiled || inError())
+ return !inError();
+
+ m_colorMatrixWasCompiled = true;
+
+ if (isResourceAllocationFailed((m_colorMatrixProgram = compileProgram(colorMatrixKernelProgram))))
+ return false;
+ if (isResourceAllocationFailed((m_matrixOperation = kernelByName(m_colorMatrixProgram, "matrix"))))
+ return false;
+ if (isResourceAllocationFailed((m_saturateAndHueRotateOperation = kernelByName(m_colorMatrixProgram, "saturateAndHueRotate"))))
+ return false;
+ if (isResourceAllocationFailed((m_saturateAndHueRotateOperation = kernelByName(m_colorMatrixProgram, "saturateAndHueRotate"))))
+ return false;
+ if (isResourceAllocationFailed((m_luminanceOperation = kernelByName(m_colorMatrixProgram, "luminance"))))
+ return false;
+ return true;
+}
+
+inline void FilterContextOpenCL::applyFEColorMatrix(OpenCLHandle destination, IntSize destinationSize, OpenCLHandle source, IntPoint relativeSourceLocation, float* values, int type)
+{
+ cl_kernel colorMatrix;
+ OpenCLHandle clValues;
+
+ switch (type) {
+ case FECOLORMATRIX_TYPE_MATRIX:
+ colorMatrix = m_matrixOperation;
+ break;
+ case FECOLORMATRIX_TYPE_SATURATE:
+ colorMatrix = m_saturateAndHueRotateOperation;
+ break;
+ case FECOLORMATRIX_TYPE_HUEROTATE:
+ colorMatrix = m_saturateAndHueRotateOperation;
+ break;
+ case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
+ colorMatrix = m_luminanceOperation;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ RunKernel kernel(this, colorMatrix, destinationSize.width(), destinationSize.height());
+ kernel.addArgument(destination);
+ kernel.addArgument(source);
+ kernel.addArgument(relativeSourceLocation.x());
+ kernel.addArgument(relativeSourceLocation.y());
+ if (type == FECOLORMATRIX_TYPE_MATRIX)
+ clValues = kernel.addArgument(values, sizeof(float) * 20);
+ else if (type == FECOLORMATRIX_TYPE_SATURATE || type == FECOLORMATRIX_TYPE_HUEROTATE)
+ clValues = kernel.addArgument(values, sizeof(float) * 9);
+ kernel.run();
+
+ clValues.clear();
+}
+
+bool FEColorMatrix::platformApplyOpenCL()
+{
+ FilterContextOpenCL* context = FilterContextOpenCL::context();
+ if (!context)
+ return false;
+
+ if (!context->compileFEColorMatrix())
+ return true;
+
+ FilterEffect* in = inputEffect(0);
+ OpenCLHandle source = in->openCLImage();
+ OpenCLHandle destination = createOpenCLImageResult();
+
+ IntPoint relativeSourceLocation(
+ absolutePaintRect().x() - in->absolutePaintRect().location().x(),
+ absolutePaintRect().y() - in->absolutePaintRect().location().y());
+
+ float components[9];
+ if (FECOLORMATRIX_TYPE_SATURATE == m_type)
+ calculateSaturateComponents(components, m_values[0]);
+ else if (FECOLORMATRIX_TYPE_HUEROTATE == m_type)
+ calculateHueRotateComponents(components, m_values[0]);
+
+ context->applyFEColorMatrix(destination, absolutePaintRect().size(), source, relativeSourceLocation, (FECOLORMATRIX_TYPE_MATRIX == m_type) ? m_values.data() : components, m_type);
+
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS) && ENABLE(OPENCL)