3e1ef0abb2eef3521ee8c0bf8c191d93e0b806d2
[WebKit-https.git] / Source / WebCore / platform / graphics / filters / FELighting.h
1 /*
2  * Copyright (C) 2010 University of Szeged
3  * Copyright (C) 2010 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 #pragma once
28
29 #include "Color.h"
30 #include "Filter.h"
31 #include "FilterEffect.h"
32 #include "LightSource.h"
33 #include <runtime/Uint8ClampedArray.h>
34
35 // Common base class for FEDiffuseLighting and FESpecularLighting
36
37 namespace WebCore {
38
39 struct FELightingPaintingDataForNeon;
40
41 class FELighting : public FilterEffect {
42 public:
43     void determineAbsolutePaintRect() override { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
44
45     float surfaceScale() const { return m_surfaceScale; }
46     bool setSurfaceScale(float);
47
48     const Color& lightingColor() const { return m_lightingColor; }
49     bool setLightingColor(const Color&);
50
51     float kernelUnitLengthX() const { return m_kernelUnitLengthX; }
52     bool setKernelUnitLengthX(float);
53
54     float kernelUnitLengthY() const { return m_kernelUnitLengthY; }
55     bool setKernelUnitLengthY(float);
56
57     const LightSource& lightSource() const { return m_lightSource.get(); }
58
59 protected:
60     static const int s_minimalRectDimension = 100 * 100; // Empirical data limit for parallel jobs
61
62     enum LightingType {
63         DiffuseLighting,
64         SpecularLighting
65     };
66     
67     struct AlphaWindow {
68         uint8_t alpha[3][3] { };
69         
70         // The implementations are lined up to make comparing indices easier.
71         uint8_t topLeft() const             { return alpha[0][0]; }
72         uint8_t left() const                { return alpha[1][0]; }
73         uint8_t bottomLeft() const          { return alpha[2][0]; }
74
75         uint8_t top() const                 { return alpha[0][1]; }
76         uint8_t center() const              { return alpha[1][1]; }
77         uint8_t bottom() const              { return alpha[2][1]; }
78
79         void setTop(uint8_t value)          { alpha[0][1] = value; }
80         void setCenter(uint8_t value)       { alpha[1][1] = value; }
81         void setBottom(uint8_t value)       { alpha[2][1] = value; }
82
83         void setTopRight(uint8_t value)     { alpha[0][2] = value; }
84         void setRight(uint8_t value)        { alpha[1][2] = value; }
85         void setBottomRight(uint8_t value)  { alpha[2][2] = value; }
86
87         static void shiftRow(uint8_t alpha[3])
88         {
89             alpha[0] = alpha[1];
90             alpha[1] = alpha[2];
91         }
92         
93         void shift()
94         {
95             shiftRow(alpha[0]);
96             shiftRow(alpha[1]);
97             shiftRow(alpha[2]);
98         }
99     };
100
101     struct LightingData {
102         // This structure contains only read-only (SMP safe) data
103         Uint8ClampedArray* pixels;
104         float surfaceScale;
105         int widthMultipliedByPixelSize;
106         int widthDecreasedByOne;
107         int heightDecreasedByOne;
108
109         inline IntSize topLeftNormal(int offset) const;
110         inline IntSize topRowNormal(int offset) const;
111         inline IntSize topRightNormal(int offset) const;
112         inline IntSize leftColumnNormal(int offset) const;
113         inline IntSize interiorNormal(int offset, AlphaWindow&) const;
114         inline IntSize rightColumnNormal(int offset) const;
115         inline IntSize bottomLeftNormal(int offset) const;
116         inline IntSize bottomRowNormal(int offset) const;
117         inline IntSize bottomRightNormal(int offset) const;
118     };
119
120     template<typename Type>
121     friend class ParallelJobs;
122
123     struct PlatformApplyGenericParameters {
124         FELighting* filter;
125         LightingData data;
126         LightSource::PaintingData paintingData;
127         int yStart;
128         int yEnd;
129     };
130
131     static void platformApplyGenericWorker(PlatformApplyGenericParameters*);
132     static void platformApplyNeonWorker(FELightingPaintingDataForNeon*);
133
134     FELighting(Filter&, LightingType, const Color&, float, float, float, float, float, float, Ref<LightSource>&&);
135
136     bool drawLighting(Uint8ClampedArray*, int, int);
137
138     void setPixel(int offset, const LightingData&, const LightSource::PaintingData&, int x, int y, float factorX, float factorY, IntSize normalVector);
139     void setPixelInternal(int offset, const LightingData&, const LightSource::PaintingData&, int x, int y, float factorX, float factorY, IntSize normalVector, float alpha);
140
141     void platformApplySoftware() override;
142
143     void platformApply(const LightingData&, const LightSource::PaintingData&);
144
145     void platformApplyGenericPaint(const LightingData&, const LightSource::PaintingData&, int startX, int startY);
146     void platformApplyGeneric(const LightingData&, const LightSource::PaintingData&);
147
148 #if CPU(ARM_NEON) && CPU(ARM_TRADITIONAL) && COMPILER(GCC_OR_CLANG)
149     static int getPowerCoefficients(float exponent);
150     inline void platformApplyNeon(const LightingData&, const LightSource::PaintingData&);
151 #endif
152
153     LightingType m_lightingType;
154     Ref<LightSource> m_lightSource;
155
156     Color m_lightingColor;
157     float m_surfaceScale;
158     float m_diffuseConstant;
159     float m_specularConstant;
160     float m_specularExponent;
161     float m_kernelUnitLengthX;
162     float m_kernelUnitLengthY;
163 };
164
165 } // namespace WebCore
166