sw_engine: code refactoring

1. unified clip & bounding box in rle processing
2. unified outline boundingbox functions between shape & image.
This commit is contained in:
Hermet Park 2021-03-24 18:48:39 +09:00 committed by GitHub
parent 19fc4f4b37
commit 4a8f45577a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 146 deletions

View file

@ -53,25 +53,30 @@ struct SwPoint
{
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);
}
@ -125,6 +130,11 @@ struct SwRleData
struct SwBBox
{
SwPoint min, max;
void reset()
{
min.x = min.y = max.x = max.y = 0;
}
};
struct SwFill
@ -286,12 +296,13 @@ 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, SwBBox& bbox, const SwSize& clip);
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, SwBBox& bbox);
bool shapePrepared(const SwShape* shape);
bool shapeGenRle(SwShape* shape, const Shape* sdata, const SwSize& clip, bool antiAlias, bool hasComposite);
bool shapeGenRle(SwShape* shape, const Shape* sdata, bool antiAlias, bool hasComposite);
void shapeDelOutline(SwShape* shape, 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, SwBBox& bbox);
@ -311,7 +322,7 @@ void strokeFree(SwStroke* stroke);
bool imagePrepare(SwImage* image, const Picture* pdata, unsigned tid, const SwSize& clip, const Matrix* transform, SwBBox& bbox);
bool imagePrepared(const SwImage* image);
bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwSize& clip, const SwBBox& bbox, bool antiAlias, bool hasComposite);
bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& bbox, bool antiAlias, bool hasComposite);
void imageDelOutline(SwImage* image, uint32_t tid);
void imageReset(SwImage* image);
bool imageGenOutline(SwImage* image, const Picture* pdata, unsigned tid, const Matrix* transform);
@ -323,7 +334,7 @@ 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 fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias);
SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbox, bool antiAlias);
void rleFree(SwRleData* rle);
void rleReset(SwRleData* rle);
void rleClipPath(SwRleData *rle, const SwRleData *clip);

View file

@ -27,63 +27,6 @@
/************************************************************************/
static void _initBBox(SwBBox& bbox)
{
bbox.min.x = bbox.min.y = 0;
bbox.max.x = bbox.max.y = 0;
}
static bool _updateBBox(const SwOutline* outline, SwBBox& bbox, const SwSize& clip)
{
if (!outline) return false;
auto pt = outline->pts;
if (outline->ptsCnt <= 0) {
_initBBox(bbox);
return false;
}
auto xMin = pt->x;
auto xMax = pt->x;
auto yMin = pt->y;
auto yMax = pt->y;
++pt;
for(uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
if (xMin > pt->x) xMin = pt->x;
if (xMax < pt->x) xMax = pt->x;
if (yMin > pt->y) yMin = pt->y;
if (yMax < pt->y) yMax = pt->y;
}
bbox.min.x = xMin >> 6;
bbox.max.x = (xMax + 63) >> 6;
bbox.min.y = yMin >> 6;
bbox.max.y = (yMax + 63) >> 6;
bbox.min.x = max(bbox.min.x, TO_SWCOORD(0));
bbox.min.y = max(bbox.min.y, TO_SWCOORD(0));
bbox.max.x = min(bbox.max.x, clip.w);
bbox.max.y = min(bbox.max.y, clip.h);
if (xMax - xMin < 1 && yMax - yMin < 1) return false;
return true;
}
static bool _checkValid(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip)
{
if (outline->ptsCnt == 0 || outline->cntrsCnt <= 0) return false;
//Check boundary
if (bbox.min.x >= clip.w || bbox.min.y >= clip.h || bbox.max.x <= 0 || bbox.max.y <= 0) return false;
return true;
}
/************************************************************************/
/* External Class Implementation */
@ -93,10 +36,11 @@ static bool _checkValid(const SwOutline* outline, const SwBBox& bbox, const SwSi
bool imagePrepare(SwImage* image, const Picture* pdata, unsigned tid, const SwSize& clip, const Matrix* transform, SwBBox& bbox)
{
if (!imageGenOutline(image, pdata, tid, transform)) return false;
if (!mathUpdateOutlineBBox(image->outline, bbox, clip)) return false;
if (!_updateBBox(image->outline, bbox, clip)) return false;
if (!_checkValid(image->outline, bbox, clip)) return false;
//Guarantee boundary from mathUpdateOutlineBBox()
bbox.min.x = max(bbox.min.x, TO_SWCOORD(0));
bbox.min.y = max(bbox.min.y, TO_SWCOORD(0));
return true;
}
@ -108,9 +52,9 @@ bool imagePrepared(const SwImage* image)
}
bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwSize& clip, const SwBBox& bbox, bool antiAlias, TVG_UNUSED bool hasComposite)
bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& bbox, bool antiAlias, TVG_UNUSED bool hasComposite)
{
if ((image->rle = rleRender(image->rle, image->outline, bbox, clip, antiAlias))) return true;
if ((image->rle = rleRender(image->rle, image->outline, bbox, antiAlias))) return true;
return false;
}

View file

@ -427,3 +427,46 @@ SwPoint mathTransform(const Point* to, const Matrix* transform)
return {TO_SWCOORD(tx), TO_SWCOORD(ty)};
}
bool mathUpdateOutlineBBox(const SwOutline* outline, SwBBox& bbox, const SwSize& clip)
{
if (!outline) return false;
auto pt = outline->pts;
if (outline->ptsCnt == 0 || outline->cntrsCnt <= 0) {
bbox.reset();
return false;
}
auto xMin = pt->x;
auto xMax = pt->x;
auto yMin = pt->y;
auto yMax = pt->y;
++pt;
for(uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
if (xMin > pt->x) xMin = pt->x;
if (xMax < pt->x) xMax = pt->x;
if (yMin > pt->y) yMin = pt->y;
if (yMax < pt->y) yMax = pt->y;
}
bbox.min.x = xMin >> 6;
bbox.max.x = (xMax + 63) >> 6;
bbox.min.y = yMin >> 6;
bbox.max.y = (yMax + 63) >> 6;
//Guarantee surface boundary
bbox.max.x = min(bbox.max.x, clip.w);
bbox.max.y = min(bbox.max.y, clip.h);
//Check valid region
if (bbox.max.x - bbox.min.x < 1 && bbox.max.y - bbox.min.y < 1) return false;
//Check boundary
if (bbox.min.x >= clip.w || bbox.min.y >= clip.h || bbox.max.x <= 0 || bbox.max.y <= 0) return false;
return true;
}

View file

@ -100,7 +100,7 @@ struct SwShapeTask : SwTask
shape outline below stroke could be full covered by stroke drawing.
Thus it turns off antialising in that condition. */
auto antiAlias = (strokeAlpha == 255 && strokeWidth > 2) ? false : true;
if (!shapeGenRle(&shape, sdata, clip, antiAlias, clips.count > 0 ? true : false)) goto err;
if (!shapeGenRle(&shape, sdata, antiAlias, clips.count > 0 ? true : false)) goto err;
++addStroking;
}
}
@ -189,7 +189,7 @@ struct SwImageTask : SwTask
//Clip Path?
if (clips.count > 0) {
if (!imageGenRle(&image, pdata, clip, bbox, false, true)) goto end;
if (!imageGenRle(&image, pdata, bbox, false, true)) goto end;
if (image.rle) {
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
auto clipper = &static_cast<SwShapeTask*>(*clip)->shape;

View file

@ -87,8 +87,6 @@ struct RleWorker
Cell** yCells;
SwCoord yCnt;
SwSize clip;
bool invalid;
bool antiAlias;
};
@ -161,8 +159,7 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
y += rw.cellMin.y;
//Clip Y range
if (y < 0) return;
if (y >= rw.clip.h) return;
if (y < 0 || y >= rw.cellMax.y) return;
/* compute the coverage line's coverage, depending on the outline fill rule */
/* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */
@ -200,7 +197,7 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
//Clip x range
SwCoord xOver = 0;
if (x + acount >= rw.clip.w) xOver -= (x + acount - rw.clip.w);
if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x);
if (x < 0) xOver += x;
//span->len += (acount + xOver) - 1;
@ -219,7 +216,7 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
//Clip x range
SwCoord xOver = 0;
if (x + acount >= rw.clip.w) xOver -= (x + acount - rw.clip.w);
if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x);
if (x < 0) {
xOver += x;
x = 0;
@ -785,7 +782,7 @@ void _replaceClipSpan(SwRleData *rle, SwSpan* clippedSpans, uint32_t size)
/* External Class Implementation */
/************************************************************************/
SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias)
SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbox, bool antiAlias)
{
constexpr auto RENDER_POOL_SIZE = 16384L;
constexpr auto BAND_SIZE = 40;
@ -812,7 +809,6 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbo
rw.outline = const_cast<SwOutline*>(outline);
rw.bandSize = rw.bufferSize / (sizeof(Cell) * 8); //bandSize: 64
rw.bandShoot = 0;
rw.clip = clip;
rw.antiAlias = antiAlias;
if (!rle) rw.rle = reinterpret_cast<SwRleData*>(calloc(1, sizeof(SwRleData)));

View file

@ -157,59 +157,6 @@ static void _outlineClose(SwOutline& outline)
}
static void _initBBox(SwBBox& bbox)
{
bbox.min.x = bbox.min.y = 0;
bbox.max.x = bbox.max.y = 0;
}
static bool _updateBBox(const SwOutline* outline, SwBBox& bbox)
{
if (!outline) return false;
auto pt = outline->pts;
if (outline->ptsCnt <= 0) {
_initBBox(bbox);
return false;
}
auto xMin = pt->x;
auto xMax = pt->x;
auto yMin = pt->y;
auto yMax = pt->y;
++pt;
for(uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
if (xMin > pt->x) xMin = pt->x;
if (xMax < pt->x) xMax = pt->x;
if (yMin > pt->y) yMin = pt->y;
if (yMax < pt->y) yMax = pt->y;
}
bbox.min.x = xMin >> 6;
bbox.max.x = (xMax + 63) >> 6;
bbox.min.y = yMin >> 6;
bbox.max.y = (yMax + 63) >> 6;
if (xMax - xMin < 1 && yMax - yMin < 1) return false;
return true;
}
static bool _checkValid(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip)
{
if (outline->ptsCnt == 0 || outline->cntrsCnt <= 0) return false;
//Check boundary
if (bbox.min.x >= clip.w || bbox.min.y >= clip.h || bbox.max.x <= 0 || bbox.max.y <= 0) return false;
return true;
}
static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform)
{
_growOutlinePoint(*dash.outline, dash.outline->ptsCnt >> 1);
@ -423,10 +370,7 @@ bool _fastTrack(const SwOutline* outline)
bool shapePrepare(SwShape* shape, const Shape* sdata, unsigned tid, const SwSize& clip, const Matrix* transform, SwBBox& bbox)
{
if (!shapeGenOutline(shape, sdata, tid, transform)) return false;
if (!_updateBBox(shape->outline, shape->bbox)) return false;
if (!_checkValid(shape->outline, shape->bbox, clip)) return false;
if (!mathUpdateOutlineBBox(shape->outline, shape->bbox, clip)) return false;
bbox = shape->bbox;
@ -440,7 +384,7 @@ bool shapePrepared(const SwShape* shape)
}
bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, const SwSize& clip, bool antiAlias, bool hasComposite)
bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, bool antiAlias, bool hasComposite)
{
//FIXME: Should we draw it?
//Case: Stroke Line
@ -449,7 +393,7 @@ bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, const SwSize& cl
//Case A: Fast Track Rectangle Drawing
if (!hasComposite && (shape->rect = _fastTrack(shape->outline))) return true;
//Case B: Normale Shape RLE Drawing
if ((shape->rle = rleRender(shape->rle, shape->outline, shape->bbox, clip, antiAlias))) return true;
if ((shape->rle = rleRender(shape->rle, shape->outline, shape->bbox, antiAlias))) return true;
return false;
}
@ -467,7 +411,7 @@ void shapeReset(SwShape* shape)
rleReset(shape->rle);
rleReset(shape->strokeRle);
shape->rect = false;
_initBBox(shape->bbox);
shape->bbox.reset();
}
@ -622,14 +566,12 @@ bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, unsigned tid, const M
goto fail;
}
_updateBBox(strokeOutline, bbox);
if (!_checkValid(strokeOutline, bbox, clip)) {
if (!mathUpdateOutlineBBox(strokeOutline, bbox, clip)) {
ret = false;
goto fail;
}
shape->strokeRle = rleRender(shape->strokeRle, strokeOutline, bbox, clip, true);
shape->strokeRle = rleRender(shape->strokeRle, strokeOutline, bbox, true);
fail:
if (freeOutline) {
@ -689,5 +631,4 @@ void shapeDelStrokeFill(SwShape* shape)
if (!shape->stroke->fill) return;
fillFree(shape->stroke->fill);
shape->stroke->fill = nullptr;
}
}