COMMIT_MESSAGE

 1light-neon
 2

Source/JavaScriptCore/wtf/Platform.h

347347# error "Cannot use both of WTF_CPU_ARM_TRADITIONAL and WTF_CPU_ARM_THUMB2 platforms"
348348#endif /* !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2) */
349349
 350#if defined(__ARM_NEON__)
 351#define ENABLE_ARM_NEON 1
 352#endif
 353
350354#endif /* ARM */
351355
352356

Source/WebCore/ChangeLog

 12011-02-17 Zoltan Herczeg <zherczeg@webkit.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Optimizing lightning filter to ARM-neon SIMD instruction set
 6 https://bugs.webkit.org/show_bug.cgi?id=54456
 7
 8 Neon is the SIMD instruction set for arm. This instruction set
 9 allows to speed-up the lighting filter by 4 times on arm
 10 (on WebCore/manual-tests/svg-filter-animation.svg).
 11
 12 * WebCore.pri:
 13 * WebCore.pro:
 14 * platform/graphics/filters/FELighting.cpp:
 15 (WebCore::FELighting::drawLighting):
 16 (WebCore::getPowerCoefficients):
 17 (WebCore::FELighting::drawInteriorPixels):
 18 * platform/graphics/filters/FELighting.h:
 19 * platform/graphics/filters/arm/FELightingNeonSIMD.cpp: Added.
 20 (__attribute__):
 21 * platform/graphics/filters/arm/FELightingNeonSIMD.h: Added.
 22
1232011-02-22 Steve Lacey <sjl@chromium.org>
224
325 Reviewed by Darin Fisher.

Source/WebCore/WebCore.pri

@@WEBCORE_INCLUDEPATH = \
9595 $$SOURCE_DIR/WebCore/platform/audio \
9696 $$SOURCE_DIR/WebCore/platform/graphics \
9797 $$SOURCE_DIR/WebCore/platform/graphics/filters \
 98 $$SOURCE_DIR/WebCore/platform/graphics/filters/arm \
9899 $$SOURCE_DIR/WebCore/platform/graphics/transforms \
99100 $$SOURCE_DIR/WebCore/platform/image-decoders \
100101 $$SOURCE_DIR/WebCore/platform/mock \

Source/WebCore/WebCore.pro

@@HEADERS += \
20192019 platform/graphics/filters/LightSource.h \
20202020 platform/graphics/filters/SourceAlpha.h \
20212021 platform/graphics/filters/SourceGraphic.h \
 2022 platform/graphics/filters/arm/FELightingNeonSIMD.h \
20222023 platform/graphics/FloatPoint3D.h \
20232024 platform/graphics/FloatPoint.h \
20242025 platform/graphics/FloatQuad.h \

@@contains(DEFINES, ENABLE_FILTERS=1) {
32763277 platform/graphics/filters/PointLightSource.cpp \
32773278 platform/graphics/filters/SpotLightSource.cpp \
32783279 platform/graphics/filters/SourceAlpha.cpp \
3279  platform/graphics/filters/SourceGraphic.cpp
 3280 platform/graphics/filters/SourceGraphic.cpp \
 3281 platform/graphics/filters/arm/FELightingNeonSIMD.cpp
32803282}
32813283
32823284contains(DEFINES, ENABLE_MATHML=1) {

Source/WebCore/platform/graphics/filters/FELighting.cpp

3030#include "FELighting.h"
3131
3232#include "LightSource.h"
 33#include "PointLightSource.h"
 34#include "SpotLightSource.h"
 35
 36#if CPU(ARM) && ENABLE(ARM_NEON) && COMPILER(GCC)
 37#include "FELightingNeonSIMD.h"
 38#endif
3339
3440namespace WebCore {
3541

@@bool FELighting::drawLighting(ByteArray* pixels, int width, int height)
301307
302308 if (width >= 3 && height >= 3) {
303309 // Interior pixels
 310#if CPU(ARM) && ENABLE(ARM_NEON) && COMPILER(GCC)
 311 drawInteriorPixels(data, paintingData);
 312#else
304313 for (int y = 1; y < data.heightDecreasedByOne; ++y) {
305314 offset = y * data.widthMultipliedByPixelSize + cPixelSize;
306315 for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {

@@bool FELighting::drawLighting(ByteArray* pixels, int width, int height)
308317 inlineSetPixel(offset, data, paintingData, x, y, cFactor1div4, cFactor1div4, normalVector);
309318 }
310319 }
 320#endif
311321 }
312322
313323 int lastPixel = data.widthMultipliedByPixelSize * height;

@@void FELighting::apply()
354364 drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height());
355365}
356366
 367#if CPU(ARM) && ENABLE(ARM_NEON) && COMPILER(GCC)
 368
 369static int getPowerCoefficients(float exponent)
 370{
 371 int i, result;
 372
 373 if (exponent < 0)
 374 exponent = 1 / (-exponent);
 375
 376 if (exponent > 63.99)
 377 exponent = 63.99;
 378
 379 exponent /= 64;
 380 result = 0;
 381 for (i = 11; i >= 0; --i) {
 382 exponent *= 2;
 383 if (exponent >= 1) {
 384 result |= 1 << i;
 385 exponent -= 1;
 386 }
 387 }
 388 return result;
 389}
 390
 391void FELighting::drawInteriorPixels(LightingData& data, LightSource::PaintingData& paintingData)
 392{
 393 FELightingPaintingDataForNeon neonData;
 394 char buffer[sizeof(FELightingFloatArgumentsForNeon) + 16];
 395 FELightingFloatArgumentsForNeon* floatArguments = reinterpret_cast<FELightingFloatArgumentsForNeon*>((reinterpret_cast<long>(buffer) + 15) & ~0xf);
 396
 397 neonData.pixels = data.pixels->data();
 398 neonData.widthDecreasedByTwo = data.widthDecreasedByOne - 1;
 399 neonData.heightDecreasedByTwo = data.heightDecreasedByOne - 1;
 400 neonData.flags = 0;
 401 neonData.specularExponent = 0;
 402 neonData.coneExponent = 0;
 403 neonData.floatArguments = floatArguments;
 404 neonData.paintingConstants = s_FELightingConstantsForNeon;
 405
 406 // Set light source arguments.
 407 floatArguments->constOne = 1;
 408
 409 floatArguments->colorRed = m_lightingColor.red();
 410 floatArguments->colorGreen = m_lightingColor.green();
 411 floatArguments->colorBlue = m_lightingColor.blue();
 412 floatArguments->padding4 = 0;
 413
 414 if (m_lightSource->type() == LS_POINT) {
 415 neonData.flags |= FLAG_POINT_LIGHT;
 416 PointLightSource* pointLightSource = static_cast<PointLightSource*>(m_lightSource.get());
 417 floatArguments->lightX = pointLightSource->position().x();
 418 floatArguments->lightY = pointLightSource->position().y();
 419 floatArguments->lightZ = pointLightSource->position().z();
 420 floatArguments->padding2 = 0;
 421 } else if (m_lightSource->type() == LS_SPOT) {
 422 neonData.flags |= FLAG_SPOT_LIGHT;
 423 SpotLightSource* spotLightSource = static_cast<SpotLightSource*>(m_lightSource.get());
 424 floatArguments->lightX = spotLightSource->position().x();
 425 floatArguments->lightY = spotLightSource->position().y();
 426 floatArguments->lightZ = spotLightSource->position().z();
 427 floatArguments->padding2 = 0;
 428
 429 floatArguments->directionX = paintingData.directionVector.x();
 430 floatArguments->directionY = paintingData.directionVector.y();
 431 floatArguments->directionZ = paintingData.directionVector.z();
 432 floatArguments->padding3 = 0;
 433
 434 floatArguments->coneCutOffLimit = paintingData.coneCutOffLimit;
 435 floatArguments->coneFullLight = paintingData.coneFullLight;
 436 floatArguments->coneCutOffRange = paintingData.coneCutOffLimit - paintingData.coneFullLight;
 437 neonData.coneExponent = getPowerCoefficients(spotLightSource->specularExponent());
 438 if (spotLightSource->specularExponent() == 1)
 439 neonData.flags |= FLAG_CONE_EXPONENT_IS_1;
 440 } else {
 441 ASSERT(m_lightSource.type == LS_DISTANT);
 442 floatArguments->lightX = paintingData.lightVector.x();
 443 floatArguments->lightY = paintingData.lightVector.y();
 444 floatArguments->lightZ = paintingData.lightVector.z();
 445 floatArguments->padding2 = 1;
 446 }
 447
 448 // Set lightnig arguments.
 449 floatArguments->surfaceScale = data.surfaceScale;
 450 floatArguments->minusSurfaceScaleDividedByFour = -data.surfaceScale / 4;
 451 if (m_lightingType == FELighting::DiffuseLighting)
 452 floatArguments->diffuseConstant = m_diffuseConstant;
 453 else {
 454 neonData.flags |= FLAG_SPECULAR_LIGHT;
 455 floatArguments->diffuseConstant = m_specularConstant;
 456 neonData.specularExponent = getPowerCoefficients(m_specularExponent);
 457 if (m_specularExponent == 1)
 458 neonData.flags |= FLAG_SPECULAR_EXPONENT_IS_1;
 459 }
 460 if (floatArguments->diffuseConstant == 1)
 461 neonData.flags |= FLAG_DIFFUSE_CONST_IS_1;
 462
 463 neonDrawLighting(&neonData);
 464}
 465#endif // CPU(ARM) && ENABLE(ARM_NEON) && COMPILER(GCC)
 466
357467} // namespace WebCore
358468
359469#endif // ENABLE(FILTERS)

Source/WebCore/platform/graphics/filters/FELighting.h

3333#include "FilterEffect.h"
3434#include "LightSource.h"
3535#include <wtf/ByteArray.h>
 36#include <wtf/Platform.h>
3637
3738// Common base class for FEDiffuseLighting and FESpecularLighting
3839

@@protected:
7980 void setPixel(int offset, LightingData&, LightSource::PaintingData&,
8081 int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector);
8182
 83#if CPU(ARM) && ENABLE(ARM_NEON)
 84 void drawInteriorPixels(LightingData&, LightSource::PaintingData&);
 85#endif
 86
8287 LightingType m_lightingType;
8388 RefPtr<LightSource> m_lightSource;
8489

Source/WebCore/platform/graphics/filters/arm/FELightingNeonSIMD.cpp

 1/*
 2 * Copyright (C) 2011 University of Szeged
 3 * Copyright (C) 2011 Zoltan Herczeg
 4 *
 5 * Redistribution and use in source and binary forms, with or without
 6 * modification, are permitted provided that the following conditions
 7 * are met:
 8 * 1. Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 * notice, this list of conditions and the following disclaimer in the
 12 * documentation and/or other materials provided with the distribution.
 13 *
 14 * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 25 */
 26
 27#include "config.h"
 28#include "FELightingNeonSIMD.h"
 29
 30#if CPU(ARM) && ENABLE(ARM_NEON) && COMPILER(GCC)
 31
 32namespace WebCore {
 33
 34// These constants are copied to the following SIMD registers:
 35// ALPHAX_Q ALPHAY_Q REMAPX_D REMAPY_D
 36
 37short s_FELightingConstantsForNeon[] __attribute__((aligned(0x10))) = {
 38 // Alpha coefficients.
 39 -2, 1, 0, -1, 2, 1, 0, -1,
 40 0, -1, -2, -1, 0, 1, 2, 1,
 41 // Remapping indicies.
 42 0x0f0e, 0x0302, 0x0504, 0x0706,
 43 0x0b0a, 0x1312, 0x1514, 0x1716,
 44};
 45
 46#define ASSTRING(str) #str
 47#define TOSTRING(value) ASSTRING(value)
 48
 49#define PIXELS_OFFSET TOSTRING(0)
 50#define WIDTH_OFFSET TOSTRING(4)
 51#define HEIGHT_OFFSET TOSTRING(8)
 52#define FLAGS_OFFSET TOSTRING(12)
 53#define SPECULAR_EXPONENT_OFFSET TOSTRING(16)
 54#define CONE_EXPONENT_OFFSET TOSTRING(20)
 55#define FLOAT_ARGUMENTS_OFFSET TOSTRING(24)
 56#define DRAWING_CONSTANTS_OFFSET TOSTRING(28)
 57#define NL "\n"
 58
 59// Register allocation
 60#define PAINTING_DATA_R "r11"
 61#define RESET_WIDTH_R PAINTING_DATA_R
 62#define PIXELS_R "r4"
 63#define WIDTH_R "r5"
 64#define HEIGHT_R "r6"
 65#define FLAGS_R "r7"
 66#define SPECULAR_EXPONENT_R "r8"
 67#define CONE_EXPONENT_R "r10"
 68#define SCANLINE_R "r12"
 69
 70#define TMP1_Q "q0"
 71#define TMP1_D0 "d0"
 72#define TMP1_S0 "s0"
 73#define TMP1_S1 "s1"
 74#define TMP1_D1 "d1"
 75#define TMP1_S2 "s2"
 76#define TMP1_S3 "s3"
 77#define TMP2_Q "q1"
 78#define TMP2_D0 "d2"
 79#define TMP2_S0 "s4"
 80#define TMP2_S1 "s5"
 81#define TMP2_D1 "d3"
 82#define TMP2_S2 "s6"
 83#define TMP2_S3 "s7"
 84#define TMP3_Q "q2"
 85#define TMP3_D0 "d4"
 86#define TMP3_S0 "s8"
 87#define TMP3_S1 "s9"
 88#define TMP3_D1 "d5"
 89#define TMP3_S2 "s10"
 90#define TMP3_S3 "s11"
 91
 92#define COSINE_OF_ANGLE "s12"
 93#define POWF_INT_S "s13"
 94#define POWF_FRAC_S "s14"
 95#define SPOT_COLOR_Q "q4"
 96
 97// Because of VMIN and VMAX CONST_ZERO_S and CONST_ONE_S
 98// must be placed on the same side of the double vector
 99
 100// Current pixel position
 101#define POSITION_Q "q5"
 102#define POSITION_X_S "s20"
 103#define POSITION_Y_S "s21"
 104#define POSITION_Z_S "s22"
 105#define CONST_ZERO_HI_D "d11"
 106#define CONST_ZERO_S "s23"
 107
 108// -------------------------------
 109// Variable arguments
 110// Misc arguments
 111#define READ1_RANGE "d12-d15"
 112#define READ2_RANGE "d16-d19"
 113#define READ3_RANGE "d20-d21"
 114
 115#define SCALE_S "s24"
 116#define SCALE_DIV4_S "s25"
 117#define DIFFUSE_CONST_S "s26"
 118
 119// Light source position
 120#define CONE_CUT_OFF_S "s28"
 121#define CONE_FULL_LIGHT_S "s29"
 122#define CONE_CUT_OFF_RANGE_S "s30"
 123#define CONST_ONE_HI_D "d15"
 124#define CONST_ONE_S "s31"
 125
 126#define LIGHT_Q "q8"
 127#define DIRECTION_Q "q9"
 128#define COLOR_Q "q10"
 129// -------------------------------
 130// Constant coefficients
 131#define READ4_RANGE "d22-d25"
 132#define READ5_RANGE "d26-d27"
 133
 134#define ALPHAX_Q "q11"
 135#define ALPHAY_Q "q12"
 136#define REMAPX_D "d26"
 137#define REMAPY_D "d27"
 138// -------------------------------
 139
 140#define ALL_ROWS_D "{d28,d29,d30}"
 141#define TOP_ROW_D "d28"
 142#define MIDDLE_ROW_D "d29"
 143#define BOTTOM_ROW_D "d30"
 144
 145#define GET_LENGTH(source, temp) \
 146 "vmul.f32 " temp##_Q ", " source##_Q ", " source##_Q NL \
 147 "vadd.f32 " source##_S3 ", " temp##_S0 ", " temp##_S1 NL \
 148 "vadd.f32 " source##_S3 ", " source##_S3 ", " temp##_S2 NL \
 149 "vsqrt.f32 " source##_S3 ", " source##_S3 NL
 150
 151// destination##_S3 can contain the multiply of length.
 152#define DOT_PRODUCT(destination, source1, source2) \
 153 "vmul.f32 " destination##_Q ", " source1##_Q ", " source2##_Q NL \
 154 "vadd.f32 " destination##_S0 ", " destination##_S0 ", " destination##_S1 NL \
 155 "vadd.f32 " destination##_S0 ", " destination##_S0 ", " destination##_S2 NL
 156
 157#define MULTIPLY_BY_DIFFUSE_CONST(normalVectorLength, dotProductLength) \
 158 "tst " FLAGS_R ", #" TOSTRING(FLAG_DIFFUSE_CONST_IS_1) NL \
 159 "vmuleq.f32 " TMP2_S1 ", " DIFFUSE_CONST_S ", " normalVectorLength NL \
 160 "vdiveq.f32 " TMP2_S1 ", " TMP2_S1 ", " dotProductLength NL \
 161 "vdivne.f32 " TMP2_S1 ", " normalVectorLength ", " dotProductLength NL
 162
 163#define POWF_SQR(value, exponent, current, remaining) \
 164 "tst " exponent ", #" ASSTRING(current) NL \
 165 "vmulne.f32 " value ", " value ", " POWF_INT_S NL \
 166 "tst " exponent ", #" ASSTRING(remaining) NL \
 167 "vmulne.f32 " POWF_INT_S ", " POWF_INT_S ", " POWF_INT_S NL
 168
 169#define POWF_SQRT(value, exponent, current, remaining) \
 170 "tst " exponent ", #" ASSTRING(remaining) NL \
 171 "vsqrtne.f32 " POWF_FRAC_S ", " POWF_FRAC_S NL \
 172 "tst " exponent ", #" ASSTRING(current) NL \
 173 "vmulne.f32 " value ", " value ", " POWF_FRAC_S NL
 174
 175#define POWF(value, exponent) \
 176 "tst " exponent ", #0xfc0" NL \
 177 "vmovne.f32 " POWF_INT_S ", " value NL \
 178 "tst " exponent ", #0x03f" NL \
 179 "vmovne.f32 " POWF_FRAC_S ", " value NL \
 180 "vmov.f32 " value ", " CONST_ONE_S NL \
 181 \
 182 POWF_SQR(value, exponent, 0x040, 0xf80) \
 183 POWF_SQR(value, exponent, 0x080, 0xf00) \
 184 POWF_SQR(value, exponent, 0x100, 0xe00) \
 185 POWF_SQR(value, exponent, 0x200, 0xc00) \
 186 POWF_SQR(value, exponent, 0x400, 0x800) \
 187 "tst " exponent ", #0x800" NL \
 188 "vmulne.f32 " value ", " value ", " POWF_INT_S NL \
 189 \
 190 POWF_SQRT(value, exponent, 0x20, 0x3f) \
 191 POWF_SQRT(value, exponent, 0x10, 0x1f) \
 192 POWF_SQRT(value, exponent, 0x08, 0x0f) \
 193 POWF_SQRT(value, exponent, 0x04, 0x07) \
 194 POWF_SQRT(value, exponent, 0x02, 0x03) \
 195 POWF_SQRT(value, exponent, 0x01, 0x01)
 196
 197asm (
 198".globl " TOSTRING(neonDrawLighting) NL
 199TOSTRING(neonDrawLighting) ":" NL
 200 // Must be aligned to 8 bytes.
 201 "stmdb sp!, {r4-r8, r10, r11, lr}" NL
 202 "vstmdb sp!, {d8-d15}" NL
 203 "mov " PAINTING_DATA_R ", r0" NL
 204 "ldr r0, [" PAINTING_DATA_R ", #" FLOAT_ARGUMENTS_OFFSET "]" NL
 205 "ldr r1, [" PAINTING_DATA_R ", #" DRAWING_CONSTANTS_OFFSET "]" NL
 206 "ldr " PIXELS_R ", [" PAINTING_DATA_R ", #" PIXELS_OFFSET "]" NL
 207 "ldr " WIDTH_R ", [" PAINTING_DATA_R ", #" WIDTH_OFFSET "]" NL
 208 "ldr " HEIGHT_R ", [" PAINTING_DATA_R ", #" HEIGHT_OFFSET "]" NL
 209 "ldr " FLAGS_R ", [" PAINTING_DATA_R ", #" FLAGS_OFFSET "]" NL
 210 "ldr " SPECULAR_EXPONENT_R ", [" PAINTING_DATA_R ", #" SPECULAR_EXPONENT_OFFSET "]" NL
 211 "ldr " CONE_EXPONENT_R ", [" PAINTING_DATA_R ", #" CONE_EXPONENT_OFFSET "]" NL
 212 "vld1.f32 { " READ1_RANGE " }, [r0]!" NL
 213 "vld1.f32 { " READ2_RANGE " }, [r0]!" NL
 214 "vld1.f32 { " READ3_RANGE " }, [r0]!" NL
 215 "vld1.s16 {" READ4_RANGE "}, [r1]!" NL
 216 "vld1.s16 {" READ5_RANGE "}, [r1]!" NL
 217 "mov " SCANLINE_R ", " WIDTH_R ", lsl #2" NL
 218 "add " SCANLINE_R ", " SCANLINE_R ", #8" NL
 219 "add " PIXELS_R ", " PIXELS_R ", " SCANLINE_R NL
 220 "add " PIXELS_R ", " PIXELS_R ", #3" NL
 221 "mov r0, #0" NL
 222 "vmov.f32 " CONST_ZERO_S ", r0" NL
 223 "vmov.f32 " POSITION_Y_S ", " CONST_ONE_S NL
 224 "tst " FLAGS_R ", #" TOSTRING(FLAG_SPOT_LIGHT) NL
 225 "vmov.f32 " SPOT_COLOR_Q ", " COLOR_Q NL
 226 "mov " RESET_WIDTH_R ", " WIDTH_R NL
 227
 228".mainloop:" NL
 229 "mov r3, #3" NL
 230 "vmov.f32 " POSITION_X_S ", " CONST_ONE_S NL
 231
 232".scanline:" NL
 233 // Reading the next pixel to the ROW data.
 234 "ldrb r0, [" PIXELS_R ", -" SCANLINE_R "]" NL
 235 "ldrb r1, [" PIXELS_R ", +" SCANLINE_R "]" NL
 236 "ldrb r2, [" PIXELS_R "], #4" NL
 237 "vext.s16 " TOP_ROW_D ", " TOP_ROW_D ", " TOP_ROW_D ", #3" NL
 238 "vext.s16 " MIDDLE_ROW_D ", " MIDDLE_ROW_D ", " MIDDLE_ROW_D ", #3" NL
 239 "vext.s16 " BOTTOM_ROW_D ", " BOTTOM_ROW_D ", " BOTTOM_ROW_D ", #3" NL
 240 "vmov.s16 " TOP_ROW_D "[1], r0" NL
 241 "vmov.s16 " MIDDLE_ROW_D "[1], r2" NL
 242 "vmov.s16 " BOTTOM_ROW_D "[1], r1" NL
 243
 244 "subs r3, r3, #1" NL
 245 "bne .scanline" NL
 246
 247 // Light vector goes to TMP1_Q.
 248 "tst " FLAGS_R ", #" TOSTRING(FLAG_POINT_LIGHT | FLAG_SPOT_LIGHT) NL
 249 "beq .distantLight" NL
 250
 251 "vmov.s16 r3, " MIDDLE_ROW_D "[2]" NL
 252 "vmov.f32 " POSITION_Z_S ", r3" NL
 253 "vcvt.f32.s32 " POSITION_Z_S ", " POSITION_Z_S NL
 254 "vmul.f32 " POSITION_Z_S ", " POSITION_Z_S ", " SCALE_S NL
 255
 256 "vsub.f32 " TMP1_Q ", " LIGHT_Q ", " POSITION_Q NL
 257 GET_LENGTH(TMP1, TMP2)
 258
 259 "tst " FLAGS_R ", #" TOSTRING(FLAG_SPOT_LIGHT) NL
 260 "bne .cosineOfAngle" NL
 261".visiblePixel:" NL
 262
 263 // Moving the 8 alpha value to ALPHA.
 264 "vtbl.8 " TMP3_D0 ", " ALL_ROWS_D ", " REMAPX_D NL
 265 "vtbl.8 " TMP3_D1 ", " ALL_ROWS_D ", " REMAPY_D NL
 266
 267 // Multiply by ALPHAX and ALPHAY.
 268 "vmul.s16 " TMP2_Q ", " TMP3_Q ", " ALPHAX_Q NL
 269 "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D1 NL
 270 "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D0 NL
 271 "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D0 NL
 272 "vmov.s16 r0, " TMP2_D0 "[0]" NL
 273
 274 "vmul.s16 " TMP2_Q ", " TMP3_Q ", " ALPHAY_Q NL
 275 "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D1 NL
 276 "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D0 NL
 277 "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D0 NL
 278 "vmov.s16 r1, " TMP2_D0 "[0]" NL
 279
 280 // Calculating light.
 281 "tst " FLAGS_R ", #" TOSTRING(FLAG_SPOT_LIGHT) NL
 282 "beq .endLight" NL
 283
 284 "vneg.f32 " TMP3_S1 ", " COSINE_OF_ANGLE NL
 285 "tst " FLAGS_R ", #" TOSTRING(FLAG_CONE_EXPONENT_IS_1) NL
 286 "beq .coneExpPowf" NL
 287".coneExpPowfFinished:" NL
 288
 289 "vcmp.f32 " COSINE_OF_ANGLE ", " CONE_FULL_LIGHT_S NL
 290 "fmstat" NL
 291 "bhi .cutOff" NL
 292".cutOffFinished:" NL
 293
 294 "vmin.f32 " TMP3_D0 ", " TMP3_D0 ", " CONST_ONE_HI_D NL
 295 "vmul.f32 " COLOR_Q ", " SPOT_COLOR_Q ", " TMP3_D0 "[1]" NL
 296
 297".endLight:" NL
 298 // r0 contains normalVector X.
 299 // r1 contains normalVector Y.
 300 // TMP1_Q contains the light vector and its length.
 301 // COLOR_Q contains the color of the light vector.
 302
 303 // Testing both r0 and r1 are zero (Normal vector is (0, 0, 1)).
 304 "orrs r2, r0, r1" NL
 305 "bne .normalVectorIsNonZero" NL
 306
 307 "tst " FLAGS_R ", #" TOSTRING(FLAG_SPECULAR_LIGHT) NL
 308 "bne .specularLight1" NL
 309
 310 MULTIPLY_BY_DIFFUSE_CONST(TMP1_S2, TMP1_S3)
 311 "b .lightStrengthCalculated" NL
 312
 313".specularLight1:" NL
 314 // Calculating specular lighting light strength.
 315 "vadd.f32 " TMP1_S2 ", " TMP1_S2 ", " TMP1_S3 NL
 316 GET_LENGTH(TMP1, TMP2)
 317
 318 "tst " FLAGS_R ", #" TOSTRING(FLAG_SPECULAR_EXPONENT_IS_1) NL
 319 "vdiveq.f32 " TMP2_S1 ", " TMP1_S2 ", " TMP1_S3 NL
 320 "beq .specularExpPowf" NL
 321
 322 MULTIPLY_BY_DIFFUSE_CONST(TMP1_S2, TMP1_S3)
 323 "b .lightStrengthCalculated" NL
 324
 325".normalVectorIsNonZero:" NL
 326 // Calculating specular lighting light strength.
 327 "vmov.s32 " TMP2_S0 ", r0" NL
 328 "vcvt.f32.s32 " TMP2_S0 ", " TMP2_S0 NL
 329 "vmul.f32 " TMP2_S0 ", " TMP2_S0 ", " SCALE_DIV4_S NL
 330 "vmov.s32 " TMP2_S1 ", r1" NL
 331 "vcvt.f32.s32 " TMP2_S1 ", " TMP2_S1 NL
 332 "vmul.f32 " TMP2_S1 ", " TMP2_S1 ", " SCALE_DIV4_S NL
 333 "vmov.f32 " TMP2_S2 ", " CONST_ONE_S NL
 334 GET_LENGTH(TMP2, TMP3)
 335
 336 "tst " FLAGS_R ", #" TOSTRING(FLAG_SPECULAR_LIGHT) NL
 337 "bne .specularLight2" NL
 338
 339 // Calculating diffuse lighting light strength.
 340 DOT_PRODUCT(TMP3, TMP2, TMP1)
 341 MULTIPLY_BY_DIFFUSE_CONST(TMP3_S0, TMP3_S3)
 342 "b .lightStrengthCalculated" NL
 343
 344".specularLight2:" NL
 345 // Calculating specular lighting light strength.
 346 "vadd.f32 " TMP1_S2 ", " TMP1_S2 ", " TMP1_S3 NL
 347 GET_LENGTH(TMP1, TMP3)
 348 DOT_PRODUCT(TMP3, TMP2, TMP1)
 349
 350 "tst " FLAGS_R ", #" TOSTRING(FLAG_SPECULAR_EXPONENT_IS_1) NL
 351 "vdiveq.f32 " TMP2_S1 ", " TMP3_S0 ", " TMP3_S3 NL
 352 "beq .specularExpPowf" NL
 353 MULTIPLY_BY_DIFFUSE_CONST(TMP3_S0, TMP3_S3)
 354
 355".lightStrengthCalculated:" NL
 356 // TMP2_S1 contains the light strength.
 357 "vmax.f32 " TMP2_D0 ", " TMP2_D0 ", " CONST_ZERO_HI_D NL
 358 "vmin.f32 " TMP2_D0 ", " TMP2_D0 ", " CONST_ONE_HI_D NL
 359 "vmul.f32 " TMP3_Q ", " COLOR_Q ", " TMP2_D0 "[1]" NL
 360 "vcvt.u32.f32 " TMP3_Q ", " TMP3_Q NL
 361 "vmov.u32 r2, r3, " TMP3_S0 ", " TMP3_S1 NL
 362 "strb r2, [" PIXELS_R ", #-11]" NL
 363 "strb r3, [" PIXELS_R ", #-10]" NL
 364 "vmov.u32 r2, " TMP3_S2 NL
 365 "strb r2, [" PIXELS_R ", #-9]" NL
 366
 367 // Continue scanline.
 368".invisiblePixel:" NL
 369 "vadd.f32 " POSITION_X_S ", " CONST_ONE_S NL
 370 "mov r3, #1" NL
 371 "subs " WIDTH_R ", " WIDTH_R ", #1" NL
 372 "bne .scanline" NL
 373
 374 // Next line
 375 "vadd.f32 " POSITION_Y_S ", " CONST_ONE_S NL
 376 "mov " WIDTH_R ", " RESET_WIDTH_R NL
 377 "subs " HEIGHT_R ", " HEIGHT_R ", #1" NL
 378 "bne .mainloop" NL
 379
 380 "vldmia sp!, {d8-d15}" NL
 381 "ldmia sp!, {r4-r8, r10, r11, pc}" NL
 382
 383".distantLight:" NL
 384 "vmov.f32 " TMP1_Q ", " LIGHT_Q NL
 385 "b .visiblePixel" NL
 386
 387".cosineOfAngle:" NL
 388 DOT_PRODUCT(TMP3, TMP1, DIRECTION)
 389 "vdiv.f32 " COSINE_OF_ANGLE ", " TMP3_S0 ", " TMP1_S3 NL
 390 "vcmp.f32 " COSINE_OF_ANGLE ", " CONE_CUT_OFF_S NL
 391 "fmstat" NL
 392 "bls .visiblePixel" NL
 393 "mov r0, #0" NL
 394 "strh r0, [" PIXELS_R ", #-11]" NL
 395 "strb r0, [" PIXELS_R ", #-9]" NL
 396 "b .invisiblePixel" NL
 397
 398".cutOff:" NL
 399 "vsub.f32 " TMP3_S0 ", " CONE_CUT_OFF_S ", " COSINE_OF_ANGLE NL
 400 "vdiv.f32 " TMP3_S0 ", " TMP3_S0 ", " CONE_CUT_OFF_RANGE_S NL
 401 "vmul.f32 " TMP3_S1 ", " TMP3_S1 ", " TMP3_S0 NL
 402 "b .cutOffFinished" NL
 403
 404".coneExpPowf:" NL
 405 POWF(TMP3_S1, CONE_EXPONENT_R)
 406 "b .coneExpPowfFinished" NL
 407
 408".specularExpPowf:" NL
 409 POWF(TMP2_S1, SPECULAR_EXPONENT_R)
 410 "tst " FLAGS_R ", #" TOSTRING(FLAG_DIFFUSE_CONST_IS_1) NL
 411 "vmuleq.f32 " TMP2_S1 ", " TMP2_S1 ", " DIFFUSE_CONST_S NL
 412 "b .lightStrengthCalculated" NL
 413);
 414
 415} // namespace WebCore
 416
 417#endif // CPU(ARM) && ENABLE(ARM_NEON) && COMPILER(GCC)

Source/WebCore/platform/graphics/filters/arm/FELightingNeonSIMD.h

 1/*
 2 * Copyright (C) 2011 University of Szeged
 3 * Copyright (C) 2011 Zoltan Herczeg
 4 *
 5 * Redistribution and use in source and binary forms, with or without
 6 * modification, are permitted provided that the following conditions
 7 * are met:
 8 * 1. Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 * notice, this list of conditions and the following disclaimer in the
 12 * documentation and/or other materials provided with the distribution.
 13 *
 14 * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 25 */
 26
 27#ifndef FELightingNeonSIMD_h
 28#define FELightingNeonSIMD_h
 29
 30#include <wtf/Platform.h>
 31
 32#if CPU(ARM) && ENABLE(ARM_NEON) && COMPILER(GCC)
 33
 34namespace WebCore {
 35
 36// Otherwise: Distant Light.
 37#define FLAG_POINT_LIGHT 0x01
 38#define FLAG_SPOT_LIGHT 0x02
 39#define FLAG_CONE_EXPONENT_IS_1 0x04
 40
 41// Otherwise: Diffuse light.
 42#define FLAG_SPECULAR_LIGHT 0x10
 43#define FLAG_DIFFUSE_CONST_IS_1 0x20
 44#define FLAG_SPECULAR_EXPONENT_IS_1 0x40
 45
 46// Must be aligned to 16 bytes.
 47struct FELightingFloatArgumentsForNeon {
 48 float surfaceScale;
 49 float minusSurfaceScaleDividedByFour;
 50 float diffuseConstant;
 51 float padding1;
 52
 53 float coneCutOffLimit;
 54 float coneFullLight;
 55 float coneCutOffRange;
 56 float constOne;
 57
 58 float lightX;
 59 float lightY;
 60 float lightZ;
 61 float padding2;
 62
 63 float directionX;
 64 float directionY;
 65 float directionZ;
 66 float padding3;
 67
 68 float colorRed;
 69 float colorGreen;
 70 float colorBlue;
 71 float padding4;
 72};
 73
 74struct FELightingPaintingDataForNeon {
 75 unsigned char* pixels;
 76 int widthDecreasedByTwo;
 77 int heightDecreasedByTwo;
 78 // Combination of FLAG constants above.
 79 int flags;
 80 int specularExponent;
 81 int coneExponent;
 82 FELightingFloatArgumentsForNeon* floatArguments;
 83 short* paintingConstants;
 84};
 85
 86extern short s_FELightingConstantsForNeon[];
 87
 88extern "C" {
 89void neonDrawLighting(FELightingPaintingDataForNeon*);
 90}
 91
 92} // namespace WebCore
 93
 94#endif // CPU(ARM) && ENABLE(ARM_NEON) && COMPILER(GCC)
 95
 96#endif // FELightingNeonSIMD_h