/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
#include "tvgCommon.h"
#include "tvgRender.h"
-#ifdef THORVG_AVX_VECTOR_SUPPORT
- #include <immintrin.h>
-#endif
-
#if 0
#include <sys/time.h>
static double timeStamp()
{
SwCoord x, y;
- SwPoint& operator+=(const SwPoint& rhs) {
+ SwPoint& operator+=(const SwPoint& rhs)
+ {
x += rhs.x;
y += rhs.y;
return *this;
}
- SwPoint operator+(const SwPoint& rhs) const {
+ SwPoint operator+(const SwPoint& rhs) const
+ {
return {x + rhs.x, y + rhs.y};
}
- SwPoint operator-(const SwPoint& rhs) const {
+ SwPoint operator-(const SwPoint& rhs) const
+ {
return {x - rhs.x, y - rhs.y};
}
- bool operator==(const SwPoint& rhs ) const {
+ bool operator==(const SwPoint& rhs) const
+ {
return (x == rhs.x && y == rhs.y);
}
- bool operator!=(const SwPoint& rhs) const {
+ bool operator!=(const SwPoint& rhs) const
+ {
return (x != rhs.x || y != rhs.y);
}
- bool zero()
+ bool zero() const
{
if (x == 0 && y == 0) return true;
else return false;
}
- bool small()
+ bool small() const
{
//2 is epsilon...
if (abs(x) < 2 && abs(y) < 2) return true;
struct SwOutline
{
- uint32_t* cntrs; //the contour end points
- uint32_t cntrsCnt; //number of contours in glyph
- uint32_t reservedCntrsCnt;
SwPoint* pts; //the outline's points
- uint32_t ptsCnt; //number of points in the glyph
- uint32_t reservedPtsCnt;
+ uint16_t ptsCnt; //number of points in the glyph
+ uint16_t reservedPtsCnt;
+ uint16_t* cntrs; //the contour end points
+ uint16_t cntrsCnt; //number of contours in glyph
+ uint16_t reservedCntrsCnt;
uint8_t* types; //curve type
+ bool* closed; //opened or closed path?
FillRule fillRule;
- bool opened; //opened path?
};
struct SwSpan
struct SwBBox
{
SwPoint min, max;
+
+ void reset()
+ {
+ min.x = min.y = max.x = max.y = 0;
+ }
+};
+
+struct SwFill
+{
+ struct SwLinear {
+ float dx, dy;
+ float len;
+ float offset;
+ };
+
+ struct SwRadial {
+ float a11, a12, shiftX;
+ float a21, a22, shiftY;
+ float detSecDeriv;
+ float a;
+ };
+
+ union {
+ SwLinear linear;
+ SwRadial radial;
+ };
+
+ uint32_t* ctable;
+ FillSpread spread;
+
+ bool translucent;
};
struct SwStrokeBorder
uint8_t* tags;
int32_t start; //index of current sub-path start point
bool movable; //true: for ends of lineto borders
- bool valid;
};
struct SwStroke
StrokeCap cap;
StrokeJoin join;
StrokeJoin joinSaved;
+ SwFill* fill = nullptr;
SwStrokeBorder borders[2];
float sx, sy;
bool firstPt;
- bool openSubPath;
+ bool closedSubPath;
bool handleWideStrokes;
};
bool curOpGap;
};
-struct SwFill
-{
- struct SwLinear {
- float dx, dy;
- float len;
- float offset;
- };
-
- struct SwRadial {
- float cx, cy;
- float a;
- float inv2a;
- };
-
- union {
- SwLinear linear;
- SwRadial radial;
- };
-
- uint32_t* ctable;
- FillSpread spread;
- float sx, sy;
-
- bool translucent;
-};
-
struct SwShape
{
SwOutline* outline = nullptr;
SwFill* fill = nullptr;
SwRleData* rle = nullptr;
SwRleData* strokeRle = nullptr;
- SwBBox bbox;
+ SwBBox bbox; //Keep it boundary without stroke region. Using for optimal filling.
- bool rect; //Fast Track: Othogonal rectangle?
+ bool fastTrack = false; //Fast Track: axis-aligned rectangle without any clips?
};
-struct SwCompositor
+struct SwImage
+{
+ SwOutline* outline = nullptr;
+ SwRleData* rle = nullptr;
+ uint32_t* data = nullptr;
+ uint32_t w, h, stride;
+ int32_t ox = 0; //offset x
+ int32_t oy = 0; //offset y
+ float scale;
+
+ bool direct = false; //draw image directly (with offset)
+ bool scaled = false; //draw scaled image
+};
+
+struct SwBlender
{
uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
uint32_t (*alpha)(uint32_t rgba);
+ uint32_t (*ialpha)(uint32_t rgba);
};
+struct SwCompositor;
+
struct SwSurface : Surface
{
- SwCompositor comp;
+ SwBlender blender; //mandatory
+ SwCompositor* compositor = nullptr; //compositor (optional)
+};
+
+struct SwCompositor : Compositor
+{
+ SwSurface* recoverSfc; //Recover surface when composition is started
+ SwCompositor* recoverCmp; //Recover compositor when composition is done
+ SwImage image;
+ SwBBox bbox;
+ bool valid;
+};
+
+struct SwMpool
+{
+ SwOutline* outline;
+ SwOutline* strokeOutline;
+ unsigned allocSize;
};
static inline SwCoord TO_SWCOORD(float val)
{
- return SwCoord(val * 64);
+ return SwCoord(val * 64.0f);
}
static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a)
{
- return (((((c >> 8) & 0x00ff00ff) * a) & 0xff00ff00) +
- ((((c & 0x00ff00ff) * a) >> 8) & 0x00ff00ff));
+ return (((((c >> 8) & 0x00ff00ff) * a + 0x00ff00ff) & 0xff00ff00) +
+ ((((c & 0x00ff00ff) * a + 0x00ff00ff) >> 8) & 0x00ff00ff));
}
static inline uint32_t COLOR_INTERPOLATE(uint32_t c1, uint32_t a1, uint32_t c2, uint32_t a2)
return (c1 |= t);
}
-static inline uint8_t ALPHA_MULTIPLY(uint32_t c, uint32_t a)
-{
- return (c * a) >> 8;
-}
-
static inline SwCoord HALF_STROKE(float width)
{
- return TO_SWCOORD(width * 0.5);
+ return TO_SWCOORD(width * 0.5f);
}
int64_t mathMultiply(int64_t a, int64_t b);
SwFixed mathSin(SwFixed angle);
void mathSplitCubic(SwPoint* base);
SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
-SwFixed mathLength(SwPoint& pt);
-bool mathSmallCubic(SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
+SwFixed mathLength(const SwPoint& pt);
+bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
SwFixed mathMean(SwFixed angle1, SwFixed angle2);
+SwPoint mathTransform(const Point* to, const Matrix* transform);
+bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack);
+bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee);
void shapeReset(SwShape* shape);
-bool shapeGenOutline(SwShape* shape, const Shape* sdata, unsigned tid, const Matrix* transform);
-bool shapePrepare(SwShape* shape, const Shape* sdata, unsigned tid, const SwSize& clip, const Matrix* transform);
-bool shapePrepared(SwShape* shape);
-bool shapeGenRle(SwShape* shape, const Shape* sdata, const SwSize& clip, bool antiAlias, bool hasComposite);
-void shapeDelOutline(SwShape* shape, uint32_t tid);
+bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite);
+bool shapePrepared(const SwShape* shape);
+bool shapeGenRle(SwShape* shape, const Shape* sdata, bool antiAlias);
+void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid);
void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform);
-bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, unsigned tid, const Matrix* transform, const SwSize& clip);
+bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
void shapeFree(SwShape* shape);
void shapeDelStroke(SwShape* shape);
-bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, bool ctable);
+bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
+bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
void shapeResetFill(SwShape* shape);
+void shapeResetStrokeFill(SwShape* shape);
void shapeDelFill(SwShape* shape);
+void shapeDelStrokeFill(SwShape* shape);
void strokeReset(SwStroke* stroke, const Shape* shape, const Matrix* transform);
bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
-SwOutline* strokeExportOutline(SwStroke* stroke);
+SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
void strokeFree(SwStroke* stroke);
-bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, bool ctable);
+bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
+bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& renderRegion, bool antiAlias);
+void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid);
+void imageReset(SwImage* image);
+void imageFree(SwImage* image);
+
+bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
void fillReset(SwFill* fill);
void fillFree(SwFill* fill);
-void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t offset, uint32_t len);
+void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
-SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias);
+SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias);
void rleFree(SwRleData* rle);
+void rleReset(SwRleData* rle);
void rleClipPath(SwRleData *rle, const SwRleData *clip);
void rleClipRect(SwRleData *rle, const SwBBox* clip);
-bool resMgrInit(uint32_t threads);
-bool resMgrTerm();
-bool resMgrClear();
-SwOutline* resMgrRequestOutline(unsigned idx);
-void resMgrRetrieveOutline(unsigned idx);
+SwMpool* mpoolInit(uint32_t threads);
+bool mpoolTerm(SwMpool* mpool);
+bool mpoolClear(SwMpool* mpool);
+SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx);
+void mpoolRetOutline(SwMpool* mpool, unsigned idx);
+SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx);
+void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx);
bool rasterCompositor(SwSurface* surface);
bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id);
-bool rasterSolidShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
+bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
+bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity);
bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
+bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id);
bool rasterClear(SwSurface* surface);
-
-static inline void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
-{
-#ifdef THORVG_AVX_VECTOR_SUPPORT
- int32_t align = (8 - (offset % 8)) % 8;
- //Vectorization
- auto avxDst = (__m256i*)(dst + offset + align);
- int32_t i = (len - align);
- for (;i > 7; i -= 8, ++avxDst) {
- *avxDst = _mm256_set1_epi32(val);
- }
- //Alignment
- if (align > 0) {
- if (align > len) align -= (align - len);
- auto tmp = dst + offset;
- for (; align > 0; --align, ++tmp) *tmp = val;
- }
- //Pack Leftovers
- dst += offset + (len - i);
- while (i-- > 0) *(dst++) = val;
-#else
- dst += offset;
- while (len--) *dst++ = val;
-#endif
-}
+void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len);
+void rasterUnpremultiply(SwSurface* surface);
#endif /* _TVG_SW_COMMON_H_ */