diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
commit | 40736c5763bf61337c8c14e16d8587db021a87d4 (patch) | |
tree | b17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h | |
download | qtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz |
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h')
-rw-r--r-- | Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h b/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h new file mode 100644 index 000000000..9094153d7 --- /dev/null +++ b/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2011 University of Szeged + * Copyright (C) 2011 Zoltan Herczeg + * + * 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. + */ + +#ifndef FELightingNeon_h +#define FELightingNeon_h + +#include <wtf/Platform.h> + +#if CPU(ARM_NEON) && COMPILER(GCC) + +#include "FELighting.h" +#include <wtf/Alignment.h> +#include <wtf/ParallelJobs.h> + +namespace WebCore { + +// Otherwise: Distant Light. +#define FLAG_POINT_LIGHT 0x01 +#define FLAG_SPOT_LIGHT 0x02 +#define FLAG_CONE_EXPONENT_IS_1 0x04 + +// Otherwise: Diffuse light. +#define FLAG_SPECULAR_LIGHT 0x10 +#define FLAG_DIFFUSE_CONST_IS_1 0x20 +#define FLAG_SPECULAR_EXPONENT_IS_1 0x40 + +// Must be aligned to 16 bytes. +struct FELightingFloatArgumentsForNeon { + float surfaceScale; + float minusSurfaceScaleDividedByFour; + float diffuseConstant; + float padding1; + + float coneCutOffLimit; + float coneFullLight; + float coneCutOffRange; + float constOne; + + float lightX; + float lightY; + float lightZ; + float padding2; + + float directionX; + float directionY; + float directionZ; + float padding3; + + float colorRed; + float colorGreen; + float colorBlue; + float padding4; +}; + +struct FELightingPaintingDataForNeon { + unsigned char* pixels; + float yStart; + int widthDecreasedByTwo; + int absoluteHeight; + // Combination of FLAG constants above. + int flags; + int specularExponent; + int coneExponent; + FELightingFloatArgumentsForNeon* floatArguments; + short* paintingConstants; +}; + +short* feLightingConstantsForNeon(); + +extern "C" { +void neonDrawLighting(FELightingPaintingDataForNeon*); +} + +inline void FELighting::platformApplyNeon(LightingData& data, LightSource::PaintingData& paintingData) +{ + WTF_ALIGNED(FELightingFloatArgumentsForNeon, floatArguments, 16); + + FELightingPaintingDataForNeon neonData = { + data.pixels->data(), + 1, + data.widthDecreasedByOne - 1, + data.heightDecreasedByOne - 1, + 0, + 0, + 0, + &floatArguments, + feLightingConstantsForNeon() + }; + + // Set light source arguments. + floatArguments.constOne = 1; + + floatArguments.colorRed = m_lightingColor.red(); + floatArguments.colorGreen = m_lightingColor.green(); + floatArguments.colorBlue = m_lightingColor.blue(); + floatArguments.padding4 = 0; + + if (m_lightSource->type() == LS_POINT) { + neonData.flags |= FLAG_POINT_LIGHT; + PointLightSource* pointLightSource = static_cast<PointLightSource*>(m_lightSource.get()); + floatArguments.lightX = pointLightSource->position().x(); + floatArguments.lightY = pointLightSource->position().y(); + floatArguments.lightZ = pointLightSource->position().z(); + floatArguments.padding2 = 0; + } else if (m_lightSource->type() == LS_SPOT) { + neonData.flags |= FLAG_SPOT_LIGHT; + SpotLightSource* spotLightSource = static_cast<SpotLightSource*>(m_lightSource.get()); + floatArguments.lightX = spotLightSource->position().x(); + floatArguments.lightY = spotLightSource->position().y(); + floatArguments.lightZ = spotLightSource->position().z(); + floatArguments.padding2 = 0; + + floatArguments.directionX = paintingData.directionVector.x(); + floatArguments.directionY = paintingData.directionVector.y(); + floatArguments.directionZ = paintingData.directionVector.z(); + floatArguments.padding3 = 0; + + floatArguments.coneCutOffLimit = paintingData.coneCutOffLimit; + floatArguments.coneFullLight = paintingData.coneFullLight; + floatArguments.coneCutOffRange = paintingData.coneCutOffLimit - paintingData.coneFullLight; + neonData.coneExponent = getPowerCoefficients(spotLightSource->specularExponent()); + if (spotLightSource->specularExponent() == 1) + neonData.flags |= FLAG_CONE_EXPONENT_IS_1; + } else { + ASSERT(m_lightSource->type() == LS_DISTANT); + floatArguments.lightX = paintingData.lightVector.x(); + floatArguments.lightY = paintingData.lightVector.y(); + floatArguments.lightZ = paintingData.lightVector.z(); + floatArguments.padding2 = 1; + } + + // Set lighting arguments. + floatArguments.surfaceScale = data.surfaceScale; + floatArguments.minusSurfaceScaleDividedByFour = -data.surfaceScale / 4; + if (m_lightingType == FELighting::DiffuseLighting) + floatArguments.diffuseConstant = m_diffuseConstant; + else { + neonData.flags |= FLAG_SPECULAR_LIGHT; + floatArguments.diffuseConstant = m_specularConstant; + neonData.specularExponent = getPowerCoefficients(m_specularExponent); + if (m_specularExponent == 1) + neonData.flags |= FLAG_SPECULAR_EXPONENT_IS_1; + } + if (floatArguments.diffuseConstant == 1) + neonData.flags |= FLAG_DIFFUSE_CONST_IS_1; + + int optimalThreadNumber = ((data.widthDecreasedByOne - 1) * (data.heightDecreasedByOne - 1)) / s_minimalRectDimension; + if (optimalThreadNumber > 1) { + // Initialize parallel jobs + ParallelJobs<FELightingPaintingDataForNeon> parallelJobs(&WebCore::FELighting::platformApplyNeonWorker, optimalThreadNumber); + + // Fill the parameter array + int job = parallelJobs.numberOfJobs(); + if (job > 1) { + int yStart = 1; + int yStep = (data.heightDecreasedByOne - 1) / job; + for (--job; job >= 0; --job) { + FELightingPaintingDataForNeon& params = parallelJobs.parameter(job); + params = neonData; + params.yStart = yStart; + params.pixels += (yStart - 1) * (data.widthDecreasedByOne + 1) * 4; + if (job > 0) { + params.absoluteHeight = yStep; + yStart += yStep; + } else + params.absoluteHeight = data.heightDecreasedByOne - yStart; + } + parallelJobs.execute(); + return; + } + } + + neonDrawLighting(&neonData); +} + +} // namespace WebCore + +#endif // CPU(ARM_NEON) && COMPILER(GCC) + +#endif // FELightingNeon_h |