sw_engine: --sanitizer errors
[platform/core/graphics/tizenvg.git] / src / lib / sw_engine / tvgSwCommon.h
1 /*
2  * Copyright (c) 2020-2021 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     {
58         x += rhs.x;
59         y += rhs.y;
60         return *this;
61     }
62
63     SwPoint operator+(const SwPoint& rhs) const
64     {
65         return {x + rhs.x, y + rhs.y};
66     }
67
68     SwPoint operator-(const SwPoint& rhs) const
69     {
70         return {x - rhs.x, y - rhs.y};
71     }
72
73     bool operator==(const SwPoint& rhs ) const
74     {
75         return (x == rhs.x && y == rhs.y);
76     }
77
78     bool operator!=(const SwPoint& rhs) const
79     {
80         return (x != rhs.x || y != rhs.y);
81     }
82
83     bool zero() const
84     {
85         if (x == 0 && y == 0) return true;
86         else return false;
87     }
88
89     bool small() const
90     {
91         //2 is epsilon...
92         if (abs(x) < 2 && abs(y) < 2) return true;
93         else return false;
94     }
95
96 };
97
98 struct SwSize
99 {
100     SwCoord w, h;
101 };
102
103 struct SwOutline
104 {
105     uint32_t*     cntrs;            //the contour end points
106     uint32_t      cntrsCnt;         //number of contours in glyph
107     uint32_t      reservedCntrsCnt;
108     SwPoint*      pts;              //the outline's points
109     uint32_t      ptsCnt;           //number of points in the glyph
110     uint32_t      reservedPtsCnt;
111     uint8_t*      types;            //curve type
112     FillRule      fillRule;
113     bool          opened;           //opened path?
114 };
115
116 struct SwSpan
117 {
118     int16_t x, y;
119     uint16_t len;
120     uint8_t coverage;
121 };
122
123 struct SwRleData
124 {
125     SwSpan *spans;
126     uint32_t alloc;
127     uint32_t size;
128 };
129
130 struct SwBBox
131 {
132     SwPoint min, max;
133
134     void reset()
135     {
136         min.x = min.y = max.x = max.y = 0;
137     }
138 };
139
140 struct SwFill
141 {
142     struct SwLinear {
143         float dx, dy;
144         float len;
145         float offset;
146     };
147
148     struct SwRadial {
149         float cx, cy;
150         float a;
151         float inva;
152     };
153
154     union {
155         SwLinear linear;
156         SwRadial radial;
157     };
158
159     uint32_t* ctable;
160     FillSpread spread;
161     float sx, sy;
162
163     bool translucent;
164 };
165
166 struct SwStrokeBorder
167 {
168     uint32_t ptsCnt;
169     uint32_t maxPts;
170     SwPoint* pts;
171     uint8_t* tags;
172     int32_t start;     //index of current sub-path start point
173     bool movable;      //true: for ends of lineto borders
174 };
175
176 struct SwStroke
177 {
178     SwFixed angleIn;
179     SwFixed angleOut;
180     SwPoint center;
181     SwFixed lineLength;
182     SwFixed subPathAngle;
183     SwPoint ptStartSubPath;
184     SwFixed subPathLineLength;
185     SwFixed width;
186
187     StrokeCap cap;
188     StrokeJoin join;
189     StrokeJoin joinSaved;
190     SwFill* fill = nullptr;
191
192     SwStrokeBorder borders[2];
193
194     float sx, sy;
195
196     bool firstPt;
197     bool openSubPath;
198     bool handleWideStrokes;
199 };
200
201 struct SwDashStroke
202 {
203     SwOutline* outline;
204     float curLen;
205     int32_t curIdx;
206     Point ptStart;
207     Point ptCur;
208     float* pattern;
209     uint32_t cnt;
210     bool curOpGap;
211 };
212
213 struct SwShape
214 {
215     SwOutline*   outline = nullptr;
216     SwStroke*    stroke = nullptr;
217     SwFill*      fill = nullptr;
218     SwRleData*   rle = nullptr;
219     SwRleData*   strokeRle = nullptr;
220     SwBBox       bbox;           //Keep it boundary without stroke region. Using for optimal filling.
221
222     bool         rect = false;   //Fast Track: Othogonal rectangle?
223 };
224
225 struct SwImage
226 {
227     SwOutline*   outline = nullptr;
228     SwRleData*   rle = nullptr;
229     uint32_t*    data = nullptr;
230     uint32_t     w, h;
231 };
232
233 struct SwBlender
234 {
235     uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
236     uint32_t (*alpha)(uint32_t rgba);
237 };
238
239 struct SwCompositor;
240
241 struct SwSurface : Surface
242 {
243     SwBlender blender;                    //mandatory
244     SwCompositor* compositor = nullptr;   //compositor (optional)
245 };
246
247 struct SwCompositor : Compositor
248 {
249     SwSurface* recoverSfc;                  //Recover surface when composition is started
250     SwCompositor* recoverCmp;               //Recover compositor when composition is done
251     SwImage image;
252     SwBBox bbox;
253     bool valid;
254 };
255
256 struct SwMpool
257 {
258     SwOutline* outline = nullptr;
259     SwOutline* strokeOutline = nullptr;
260     unsigned allocSize = 0;
261 };
262
263 static inline SwCoord TO_SWCOORD(float val)
264 {
265     return SwCoord(val * 64);
266 }
267
268 static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a)
269 {
270     return (((((c >> 8) & 0x00ff00ff) * a + 0x00ff00ff) & 0xff00ff00) +
271             ((((c & 0x00ff00ff) * a + 0x00ff00ff) >> 8) & 0x00ff00ff));
272 }
273
274 static inline uint32_t COLOR_INTERPOLATE(uint32_t c1, uint32_t a1, uint32_t c2, uint32_t a2)
275 {
276     auto t = (((c1 & 0xff00ff) * a1 + (c2 & 0xff00ff) * a2) >> 8) & 0xff00ff;
277     c1 = (((c1 >> 8) & 0xff00ff) * a1 + ((c2 >> 8) & 0xff00ff) * a2) & 0xff00ff00;
278     return (c1 |= t);
279 }
280
281 static inline uint32_t ALPHA_MULTIPLY(uint32_t c, uint32_t a)
282 {
283     return ((c * a + 0xff) >> 8);
284 }
285
286 static inline SwCoord HALF_STROKE(float width)
287 {
288     return TO_SWCOORD(width * 0.5);
289 }
290
291 int64_t mathMultiply(int64_t a, int64_t b);
292 int64_t mathDivide(int64_t a, int64_t b);
293 int64_t mathMulDiv(int64_t a, int64_t b, int64_t c);
294 void mathRotate(SwPoint& pt, SwFixed angle);
295 SwFixed mathTan(SwFixed angle);
296 SwFixed mathAtan(const SwPoint& pt);
297 SwFixed mathCos(SwFixed angle);
298 SwFixed mathSin(SwFixed angle);
299 void mathSplitCubic(SwPoint* base);
300 SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
301 SwFixed mathLength(const SwPoint& pt);
302 bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
303 SwFixed mathMean(SwFixed angle1, SwFixed angle2);
304 SwPoint mathTransform(const Point* to, const Matrix* transform);
305 bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion);
306
307 void shapeReset(SwShape* shape);
308 bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
309 bool shapePrepared(const SwShape* shape);
310 bool shapeGenRle(SwShape* shape, const Shape* sdata, bool antiAlias, bool hasComposite);
311 void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid);
312 void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform);
313 bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
314 void shapeFree(SwShape* shape);
315 void shapeDelStroke(SwShape* shape);
316 bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
317 bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
318 void shapeResetFill(SwShape* shape);
319 void shapeResetStrokeFill(SwShape* shape);
320 void shapeDelFill(SwShape* shape);
321 void shapeDelStrokeFill(SwShape* shape);
322
323 void strokeReset(SwStroke* stroke, const Shape* shape, const Matrix* transform);
324 bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
325 SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
326 void strokeFree(SwStroke* stroke);
327
328 bool imagePrepare(SwImage* image, const Picture* pdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
329 bool imagePrepared(const SwImage* image);
330 bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& renderRegion, bool antiAlias);
331 void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid);
332 void imageReset(SwImage* image);
333 void imageFree(SwImage* image);
334
335 bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
336 void fillReset(SwFill* fill);
337 void fillFree(SwFill* fill);
338 void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
339 void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
340
341 SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias);
342 void rleFree(SwRleData* rle);
343 void rleReset(SwRleData* rle);
344 void rleClipPath(SwRleData *rle, const SwRleData *clip);
345 void rleClipRect(SwRleData *rle, const SwBBox* clip);
346 void rleAlphaMask(SwRleData *rle, const SwRleData *clip);
347
348 SwMpool* mpoolInit(uint32_t threads);
349 bool mpoolTerm(SwMpool* mpool);
350 bool mpoolClear(SwMpool* mpool);
351 SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx);
352 void mpoolRetOutline(SwMpool* mpool, unsigned idx);
353 SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx);
354 void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx);
355
356 bool rasterCompositor(SwSurface* surface);
357 bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id);
358 bool rasterSolidShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
359 bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity);
360 bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
361 bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id);
362 bool rasterClear(SwSurface* surface);
363
364 static inline void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
365 {
366 #ifdef THORVG_AVX_VECTOR_SUPPORT
367     //1. calculate how many iterations we need to cover length
368     uint32_t iterations = len / 8;
369     uint32_t avxFilled = iterations * 8;
370     int32_t leftovers = 0;
371
372     //2. set beginning of the array
373     dst+=offset;
374     __m256i_u* avxDst = (__m256i_u*) dst;
375
376     //3. fill octets
377     for (uint32_t i = 0; i < iterations; ++i) {
378         *avxDst = _mm256_set1_epi32(val);
379         avxDst++;
380     }
381
382     //4. fill leftovers (in first step we have to set pointer to place where avx job is done)
383     leftovers = len - avxFilled;
384     dst+= avxFilled;
385
386     while (leftovers--) *dst++ = val;
387 #else
388     dst += offset;
389     while (len--) *dst++ = val;
390 #endif
391 }
392
393 #endif /* _TVG_SW_COMMON_H_ */