sw_engine image: optimized image rendering.
[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 #if 0
29 #include <sys/time.h>
30 static double timeStamp()
31 {
32    struct timeval tv;
33    gettimeofday(&tv, NULL);
34    return (tv.tv_sec + tv.tv_usec / 1000000.0);
35 }
36 #endif
37
38 #define SW_CURVE_TYPE_POINT 0
39 #define SW_CURVE_TYPE_CUBIC 1
40 #define SW_ANGLE_PI (180L << 16)
41 #define SW_ANGLE_2PI (SW_ANGLE_PI << 1)
42 #define SW_ANGLE_PI2 (SW_ANGLE_PI >> 1)
43 #define SW_ANGLE_PI4 (SW_ANGLE_PI >> 2)
44
45 using SwCoord = signed long;
46 using SwFixed = signed long long;
47
48 struct SwPoint
49 {
50     SwCoord x, y;
51
52     SwPoint& operator+=(const SwPoint& rhs)
53     {
54         x += rhs.x;
55         y += rhs.y;
56         return *this;
57     }
58
59     SwPoint operator+(const SwPoint& rhs) const
60     {
61         return {x + rhs.x, y + rhs.y};
62     }
63
64     SwPoint operator-(const SwPoint& rhs) const
65     {
66         return {x - rhs.x, y - rhs.y};
67     }
68
69     bool operator==(const SwPoint& rhs) const
70     {
71         return (x == rhs.x && y == rhs.y);
72     }
73
74     bool operator!=(const SwPoint& rhs) const
75     {
76         return (x != rhs.x || y != rhs.y);
77     }
78
79     bool zero() const
80     {
81         if (x == 0 && y == 0) return true;
82         else return false;
83     }
84
85     bool small() const
86     {
87         //2 is epsilon...
88         if (abs(x) < 2 && abs(y) < 2) return true;
89         else return false;
90     }
91
92 };
93
94 struct SwSize
95 {
96     SwCoord w, h;
97 };
98
99 struct SwOutline
100 {
101     SwPoint*      pts;              //the outline's points
102     uint16_t      ptsCnt;           //number of points in the glyph
103     uint16_t      reservedPtsCnt;
104     uint16_t*     cntrs;            //the contour end points
105     uint16_t      cntrsCnt;         //number of contours in glyph
106     uint16_t      reservedCntrsCnt;
107     uint8_t*      types;            //curve type
108     bool*         closed;           //opened or closed path?
109     FillRule      fillRule;
110 };
111
112 struct SwSpan
113 {
114     int16_t x, y;
115     uint16_t len;
116     uint8_t coverage;
117 };
118
119 struct SwRleData
120 {
121     SwSpan *spans;
122     uint32_t alloc;
123     uint32_t size;
124 };
125
126 struct SwBBox
127 {
128     SwPoint min, max;
129
130     void reset()
131     {
132         min.x = min.y = max.x = max.y = 0;
133     }
134 };
135
136 struct SwFill
137 {
138     struct SwLinear {
139         float dx, dy;
140         float len;
141         float offset;
142     };
143
144     struct SwRadial {
145         float a11, a12, shiftX;
146         float a21, a22, shiftY;
147         float detSecDeriv;
148         float a;
149     };
150
151     union {
152         SwLinear linear;
153         SwRadial radial;
154     };
155
156     uint32_t* ctable;
157     FillSpread spread;
158
159     bool translucent;
160 };
161
162 struct SwStrokeBorder
163 {
164     uint32_t ptsCnt;
165     uint32_t maxPts;
166     SwPoint* pts;
167     uint8_t* tags;
168     int32_t start;     //index of current sub-path start point
169     bool movable;      //true: for ends of lineto borders
170 };
171
172 struct SwStroke
173 {
174     SwFixed angleIn;
175     SwFixed angleOut;
176     SwPoint center;
177     SwFixed lineLength;
178     SwFixed subPathAngle;
179     SwPoint ptStartSubPath;
180     SwFixed subPathLineLength;
181     SwFixed width;
182
183     StrokeCap cap;
184     StrokeJoin join;
185     StrokeJoin joinSaved;
186     SwFill* fill = nullptr;
187
188     SwStrokeBorder borders[2];
189
190     float sx, sy;
191
192     bool firstPt;
193     bool closedSubPath;
194     bool handleWideStrokes;
195 };
196
197 struct SwDashStroke
198 {
199     SwOutline* outline;
200     float curLen;
201     int32_t curIdx;
202     Point ptStart;
203     Point ptCur;
204     float* pattern;
205     uint32_t cnt;
206     bool curOpGap;
207 };
208
209 struct SwShape
210 {
211     SwOutline*   outline = nullptr;
212     SwStroke*    stroke = nullptr;
213     SwFill*      fill = nullptr;
214     SwRleData*   rle = nullptr;
215     SwRleData*   strokeRle = nullptr;
216     SwBBox       bbox;           //Keep it boundary without stroke region. Using for optimal filling.
217
218     bool         fastTrack = false;   //Fast Track: axis-aligned rectangle without any clips?
219 };
220
221 struct SwImage
222 {
223     SwOutline*   outline = nullptr;
224     SwRleData*   rle = nullptr;
225     uint32_t*    data = nullptr;
226     uint32_t     w, h, stride;
227 };
228
229 struct SwBlender
230 {
231     uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
232     uint32_t (*alpha)(uint32_t rgba);
233     uint32_t (*ialpha)(uint32_t rgba);
234 };
235
236 struct SwCompositor;
237
238 struct SwSurface : Surface
239 {
240     SwBlender blender;                    //mandatory
241     SwCompositor* compositor = nullptr;   //compositor (optional)
242 };
243
244 struct SwCompositor : Compositor
245 {
246     SwSurface* recoverSfc;                  //Recover surface when composition is started
247     SwCompositor* recoverCmp;               //Recover compositor when composition is done
248     SwImage image;
249     SwBBox bbox;
250     bool valid;
251 };
252
253 struct SwMpool
254 {
255     SwOutline* outline;
256     SwOutline* strokeOutline;
257     unsigned allocSize;
258 };
259
260 static inline SwCoord TO_SWCOORD(float val)
261 {
262     return SwCoord(val * 64.0f);
263 }
264
265 static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a)
266 {
267     return (((((c >> 8) & 0x00ff00ff) * a + 0x00ff00ff) & 0xff00ff00) +
268             ((((c & 0x00ff00ff) * a + 0x00ff00ff) >> 8) & 0x00ff00ff));
269 }
270
271 static inline uint32_t COLOR_INTERPOLATE(uint32_t c1, uint32_t a1, uint32_t c2, uint32_t a2)
272 {
273     auto t = (((c1 & 0xff00ff) * a1 + (c2 & 0xff00ff) * a2) >> 8) & 0xff00ff;
274     c1 = (((c1 >> 8) & 0xff00ff) * a1 + ((c2 >> 8) & 0xff00ff) * a2) & 0xff00ff00;
275     return (c1 |= t);
276 }
277
278 static inline uint32_t ALPHA_MULTIPLY(uint32_t c, uint32_t a)
279 {
280     return ((c * a + 0xff) >> 8);
281 }
282
283 static inline SwCoord HALF_STROKE(float width)
284 {
285     return TO_SWCOORD(width * 0.5f);
286 }
287
288 int64_t mathMultiply(int64_t a, int64_t b);
289 int64_t mathDivide(int64_t a, int64_t b);
290 int64_t mathMulDiv(int64_t a, int64_t b, int64_t c);
291 void mathRotate(SwPoint& pt, SwFixed angle);
292 SwFixed mathTan(SwFixed angle);
293 SwFixed mathAtan(const SwPoint& pt);
294 SwFixed mathCos(SwFixed angle);
295 SwFixed mathSin(SwFixed angle);
296 void mathSplitCubic(SwPoint* base);
297 SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
298 SwFixed mathLength(const SwPoint& pt);
299 bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
300 SwFixed mathMean(SwFixed angle1, SwFixed angle2);
301 SwPoint mathTransform(const Point* to, const Matrix* transform);
302 bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack);
303 bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee);
304
305 void shapeReset(SwShape* shape);
306 bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite);
307 bool shapePrepared(const SwShape* shape);
308 bool shapeGenRle(SwShape* shape, const Shape* sdata, bool antiAlias);
309 void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid);
310 void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform);
311 bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
312 void shapeFree(SwShape* shape);
313 void shapeDelStroke(SwShape* shape);
314 bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
315 bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
316 void shapeResetFill(SwShape* shape);
317 void shapeResetStrokeFill(SwShape* shape);
318 void shapeDelFill(SwShape* shape);
319 void shapeDelStrokeFill(SwShape* shape);
320
321 void strokeReset(SwStroke* stroke, const Shape* shape, const Matrix* transform);
322 bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
323 SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
324 void strokeFree(SwStroke* stroke);
325
326 bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool outline);
327 bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& renderRegion, bool antiAlias);
328 void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid);
329 void imageReset(SwImage* image);
330 void imageFree(SwImage* image);
331
332 bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
333 void fillReset(SwFill* fill);
334 void fillFree(SwFill* fill);
335 void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
336 void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
337
338 SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias);
339 void rleFree(SwRleData* rle);
340 void rleReset(SwRleData* rle);
341 void rleClipPath(SwRleData *rle, const SwRleData *clip);
342 void rleClipRect(SwRleData *rle, const SwBBox* clip);
343
344 SwMpool* mpoolInit(uint32_t threads);
345 bool mpoolTerm(SwMpool* mpool);
346 bool mpoolClear(SwMpool* mpool);
347 SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx);
348 void mpoolRetOutline(SwMpool* mpool, unsigned idx);
349 SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx);
350 void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx);
351
352 bool rasterCompositor(SwSurface* surface);
353 bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id);
354 bool rasterSolidShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
355 bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity);
356 bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
357 bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id);
358 bool rasterClear(SwSurface* surface);
359 void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len);
360 void rasterUnpremultiply(SwSurface* surface);
361
362 #endif /* _TVG_SW_COMMON_H_ */