common: Functions that can declare const are refactored to use const
[platform/core/graphics/tizenvg.git] / src / lib / sw_engine / tvgSwCommon.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
3
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 #ifndef _TVG_SW_COMMON_H_
23 #define _TVG_SW_COMMON_H_
24
25 #include "tvgCommon.h"
26 #include "tvgRender.h"
27
28 #ifdef THORVG_AVX_VECTOR_SUPPORT
29     #include <immintrin.h>
30 #endif
31
32 #if 0
33 #include <sys/time.h>
34 static double timeStamp()
35 {
36    struct timeval tv;
37    gettimeofday(&tv, NULL);
38    return (tv.tv_sec + tv.tv_usec / 1000000.0);
39 }
40 #endif
41
42 #define SW_CURVE_TYPE_POINT 0
43 #define SW_CURVE_TYPE_CUBIC 1
44 #define SW_ANGLE_PI (180L << 16)
45 #define SW_ANGLE_2PI (SW_ANGLE_PI << 1)
46 #define SW_ANGLE_PI2 (SW_ANGLE_PI >> 1)
47 #define SW_ANGLE_PI4 (SW_ANGLE_PI >> 2)
48
49 using SwCoord = signed long;
50 using SwFixed = signed long long;
51
52 struct SwPoint
53 {
54     SwCoord x, y;
55
56     SwPoint& operator+=(const SwPoint& rhs) {
57         x += rhs.x;
58         y += rhs.y;
59         return *this;
60     }
61
62     SwPoint operator+(const SwPoint& rhs) const {
63         return {x + rhs.x, y + rhs.y};
64     }
65
66     SwPoint operator-(const SwPoint& rhs) const {
67         return {x - rhs.x, y - rhs.y};
68     }
69
70     bool operator==(const SwPoint& rhs ) const {
71         return (x == rhs.x && y == rhs.y);
72     }
73
74     bool operator!=(const SwPoint& rhs) const {
75         return (x != rhs.x || y != rhs.y);
76     }
77
78     bool zero() const
79     {
80         if (x == 0 && y == 0) return true;
81         else return false;
82     }
83
84     bool small() const
85     {
86         //2 is epsilon...
87         if (abs(x) < 2 && abs(y) < 2) return true;
88         else return false;
89     }
90
91 };
92
93 struct SwSize
94 {
95     SwCoord w, h;
96 };
97
98 struct SwOutline
99 {
100     uint32_t*     cntrs;            //the contour end points
101     uint32_t      cntrsCnt;         //number of contours in glyph
102     uint32_t      reservedCntrsCnt;
103     SwPoint*      pts;              //the outline's points
104     uint32_t      ptsCnt;           //number of points in the glyph
105     uint32_t      reservedPtsCnt;
106     uint8_t*      types;            //curve type
107     FillRule      fillRule;
108     bool          opened;           //opened path?
109 };
110
111 struct SwSpan
112 {
113     int16_t x, y;
114     uint16_t len;
115     uint8_t coverage;
116 };
117
118 struct SwRleData
119 {
120     SwSpan *spans;
121     uint32_t alloc;
122     uint32_t size;
123 };
124
125 struct SwBBox
126 {
127     SwPoint min, max;
128 };
129
130 struct SwStrokeBorder
131 {
132     uint32_t ptsCnt;
133     uint32_t maxPts;
134     SwPoint* pts;
135     uint8_t* tags;
136     int32_t start;     //index of current sub-path start point
137     bool movable;      //true: for ends of lineto borders
138     bool valid;
139 };
140
141 struct SwStroke
142 {
143     SwFixed angleIn;
144     SwFixed angleOut;
145     SwPoint center;
146     SwFixed lineLength;
147     SwFixed subPathAngle;
148     SwPoint ptStartSubPath;
149     SwFixed subPathLineLength;
150     SwFixed width;
151
152     StrokeCap cap;
153     StrokeJoin join;
154     StrokeJoin joinSaved;
155
156     SwStrokeBorder borders[2];
157
158     float sx, sy;
159
160     bool firstPt;
161     bool openSubPath;
162     bool handleWideStrokes;
163 };
164
165 struct SwDashStroke
166 {
167     SwOutline* outline;
168     float curLen;
169     int32_t curIdx;
170     Point ptStart;
171     Point ptCur;
172     float* pattern;
173     uint32_t cnt;
174     bool curOpGap;
175 };
176
177 struct SwFill
178 {
179     struct SwLinear {
180         float dx, dy;
181         float len;
182         float offset;
183     };
184
185     struct SwRadial {
186         float cx, cy;
187         float a;
188         float inv2a;
189     };
190
191     union {
192         SwLinear linear;
193         SwRadial radial;
194     };
195
196     uint32_t* ctable;
197     FillSpread spread;
198     float sx, sy;
199
200     bool translucent;
201 };
202
203 struct SwShape
204 {
205     SwOutline*   outline = nullptr;
206     SwStroke*    stroke = nullptr;
207     SwFill*      fill = nullptr;
208     SwRleData*   rle = nullptr;
209     SwRleData*   strokeRle = nullptr;
210     SwBBox       bbox;   //keep it boundary without stroke region. Using for optimal filling.
211
212     bool         rect;   //Fast Track: Othogonal rectangle?
213 };
214
215 struct SwImage
216 {
217     SwOutline*   outline = nullptr;
218     SwRleData*   rle = nullptr;
219     uint32_t*    data = nullptr;
220     uint32_t     w, h;
221 };
222
223 struct SwBlender
224 {
225     uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
226     uint32_t (*alpha)(uint32_t rgba);
227 };
228
229 struct SwCompositor;
230
231 struct SwSurface : Surface
232 {
233     SwBlender blender;                    //mandatory
234     SwCompositor* compositor = nullptr;   //compositor (optional)
235 };
236
237 struct SwCompositor : Compositor
238 {
239     SwSurface* recoverSfc;                  //Recover surface when composition is started
240     SwCompositor* recoverCmp;               //Recover compositor when composition is done
241     SwImage image;
242     SwBBox bbox;
243     bool valid;
244 };
245
246 static inline SwCoord TO_SWCOORD(float val)
247 {
248     return SwCoord(val * 64);
249 }
250
251 static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a)
252 {
253     return (((((c >> 8) & 0x00ff00ff) * a) & 0xff00ff00) +
254             ((((c & 0x00ff00ff) * a) >> 8) & 0x00ff00ff));
255 }
256
257 static inline uint32_t COLOR_INTERPOLATE(uint32_t c1, uint32_t a1, uint32_t c2, uint32_t a2)
258 {
259     auto t = (((c1 & 0xff00ff) * a1 + (c2 & 0xff00ff) * a2) >> 8) & 0xff00ff;
260     c1 = (((c1 >> 8) & 0xff00ff) * a1 + ((c2 >> 8) & 0xff00ff) * a2) & 0xff00ff00;
261     return (c1 |= t);
262 }
263
264 static inline uint8_t ALPHA_MULTIPLY(uint32_t c, uint32_t a)
265 {
266     return (c * a) >> 8;
267 }
268
269 static inline SwCoord HALF_STROKE(float width)
270 {
271     return TO_SWCOORD(width * 0.5);
272 }
273
274 int64_t mathMultiply(int64_t a, int64_t b);
275 int64_t mathDivide(int64_t a, int64_t b);
276 int64_t mathMulDiv(int64_t a, int64_t b, int64_t c);
277 void mathRotate(SwPoint& pt, SwFixed angle);
278 SwFixed mathTan(SwFixed angle);
279 SwFixed mathAtan(const SwPoint& pt);
280 SwFixed mathCos(SwFixed angle);
281 SwFixed mathSin(SwFixed angle);
282 void mathSplitCubic(SwPoint* base);
283 SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
284 SwFixed mathLength(SwPoint& pt);
285 bool mathSmallCubic(SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
286 SwFixed mathMean(SwFixed angle1, SwFixed angle2);
287 SwPoint mathTransform(const Point* to, const Matrix* transform);
288
289 void shapeReset(SwShape* shape);
290 bool shapeGenOutline(SwShape* shape, const Shape* sdata, unsigned tid, const Matrix* transform);
291 bool shapePrepare(SwShape* shape, const Shape* sdata, unsigned tid, const SwSize& clip, const Matrix* transform, SwBBox& bbox);
292 bool shapePrepared(SwShape* shape);
293 bool shapeGenRle(SwShape* shape, const Shape* sdata, const SwSize& clip, bool antiAlias, bool hasComposite);
294 void shapeDelOutline(SwShape* shape, uint32_t tid);
295 void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform);
296 bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, unsigned tid, const Matrix* transform, const SwSize& clip, SwBBox& bbox);
297 void shapeFree(SwShape* shape);
298 void shapeDelStroke(SwShape* shape);
299 bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
300 void shapeResetFill(SwShape* shape);
301 void shapeDelFill(SwShape* shape);
302
303 void strokeReset(SwStroke* stroke, const Shape* shape, const Matrix* transform);
304 bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
305 SwOutline* strokeExportOutline(SwStroke* stroke, unsigned tid);
306 void strokeFree(SwStroke* stroke);
307
308 bool imagePrepare(SwImage* image, const Picture* pdata, unsigned tid, const SwSize& clip, const Matrix* transform, SwBBox& bbox);
309 bool imagePrepared(SwImage* image);
310 bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwSize& clip, SwBBox& bbox, bool antiAlias, bool hasComposite);
311 void imageDelOutline(SwImage* image, uint32_t tid);
312 void imageReset(SwImage* image);
313 bool imageGenOutline(SwImage* image, const Picture* pdata, unsigned tid, const Matrix* transform);
314 void imageFree(SwImage* image);
315
316 bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
317 void fillReset(SwFill* fill);
318 void fillFree(SwFill* fill);
319 void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t offset, uint32_t len);
320 void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
321
322 SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias);
323 void rleFree(SwRleData* rle);
324 void rleReset(SwRleData* rle);
325 void rleClipPath(SwRleData *rle, const SwRleData *clip);
326 void rleClipRect(SwRleData *rle, const SwBBox* clip);
327 void rleAlphaMask(SwRleData *rle, const SwRleData *clip);
328
329 bool mpoolInit(uint32_t threads);
330 bool mpoolTerm();
331 bool mpoolClear();
332 SwOutline* mpoolReqOutline(unsigned idx);
333 void mpoolRetOutline(unsigned idx);
334 SwOutline* mpoolReqStrokeOutline(unsigned idx);
335 void mpoolRetStrokeOutline(unsigned idx);
336
337 bool rasterCompositor(SwSurface* surface);
338 bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id);
339 bool rasterSolidShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
340 bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, SwBBox& bbox, uint32_t opacity);
341 bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
342 bool rasterClear(SwSurface* surface);
343
344 static inline void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
345 {
346 #ifdef THORVG_AVX_VECTOR_SUPPORT
347     int32_t align = (8 - (offset % 8)) % 8;
348     //Vectorization
349     auto avxDst = (__m256i*)(dst + offset + align);
350     int32_t i = (len - align);
351     for (;i > 7; i -= 8, ++avxDst) {
352        *avxDst = _mm256_set1_epi32(val);
353     }
354     //Alignment
355     if (align > 0) {
356         if (align > len) align -= (align - len);
357         auto tmp = dst + offset;
358         for (; align > 0; --align, ++tmp) *tmp = val;
359     }
360     //Pack Leftovers
361     dst += offset + (len - i);
362     while (i-- > 0) *(dst++) = val;
363 #else
364     dst += offset;
365     while (len--) *dst++ = val;
366 #endif
367 }
368
369 #endif /* _TVG_SW_COMMON_H_ */