sw_engine image: optimized image rendering.

Applied the fast-track routine for axis-aligned images.
This helps to remove outline generation if no clips.
This commit is contained in:
Hermet Park 2021-11-12 14:55:04 +09:00 committed by Hermet Park
parent d7973e9330
commit d520da2db8
5 changed files with 44 additions and 23 deletions

View file

@ -300,6 +300,7 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw
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 shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite);
@ -322,7 +323,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
void strokeFree(SwStroke* stroke);
bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool outline);
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);

View file

@ -19,7 +19,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <algorithm>
#include "tvgMath.h"
#include "tvgSwCommon.h"
/************************************************************************/
@ -72,10 +72,19 @@ static bool _genOutline(SwImage* image, const Matrix* transform, SwMpool* mpool,
/************************************************************************/
bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid)
bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool outline)
{
if (outline || mathRotated(transform)) {
if (!_genOutline(image, transform, mpool, tid)) return false;
return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, false);
//Fast Track, don't need outlines.
} else {
renderRegion.min.x = static_cast<SwCoord>(round(transform->e13));
renderRegion.max.x = renderRegion.min.x + static_cast<SwCoord>(image->w);
renderRegion.min.y = static_cast<SwCoord>(round(transform->e23));
renderRegion.max.y= renderRegion.min.y + static_cast<SwCoord>(image->h);
return mathClipBBox(clipRegion, renderRegion);
}
}

View file

@ -442,6 +442,24 @@ SwPoint mathTransform(const Point* to, const Matrix* transform)
}
bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee)
{
clipee.max.x = (clipee.max.x < clipper.max.x) ? clipee.max.x : clipper.max.x;
clipee.max.y = (clipee.max.y < clipper.max.y) ? clipee.max.y : clipper.max.y;
clipee.min.x = (clipee.min.x > clipper.min.x) ? clipee.min.x : clipper.min.x;
clipee.min.y = (clipee.min.y > clipper.min.y) ? clipee.min.y : clipper.min.y;
//Check valid region
if (clipee.max.x - clipee.min.x < 1 && clipee.max.y - clipee.min.y < 1) return false;
//Check boundary
if (clipee.min.x >= clipper.max.x || clipee.min.y >= clipper.max.y ||
clipee.max.x <= clipper.min.x || clipee.max.y <= clipper.min.y) return false;
return true;
}
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack)
{
if (!outline) return false;
@ -466,7 +484,6 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
if (yMin > pt->y) yMin = pt->y;
if (yMax < pt->y) yMax = pt->y;
}
//Since no antialiasing is applied in the Fast Track case,
//the rasterization region has to be rearranged.
//https://github.com/Samsung/thorvg/issues/916
@ -481,18 +498,5 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
renderRegion.min.y = yMin >> 6;
renderRegion.max.y = (yMax + 63) >> 6;
}
renderRegion.max.x = (renderRegion.max.x < clipRegion.max.x) ? renderRegion.max.x : clipRegion.max.x;
renderRegion.max.y = (renderRegion.max.y < clipRegion.max.y) ? renderRegion.max.y : clipRegion.max.y;
renderRegion.min.x = (renderRegion.min.x > clipRegion.min.x) ? renderRegion.min.x : clipRegion.min.x;
renderRegion.min.y = (renderRegion.min.y > clipRegion.min.y) ? renderRegion.min.y : clipRegion.min.y;
//Check valid region
if (renderRegion.max.x - renderRegion.min.x < 1 && renderRegion.max.y - renderRegion.min.y < 1) return false;
//Check boundary
if (renderRegion.min.x >= clipRegion.max.x || renderRegion.min.y >= clipRegion.max.y ||
renderRegion.max.x <= clipRegion.min.x || renderRegion.max.y <= clipRegion.min.y) return false;
return true;
return mathClipBBox(clipRegion, renderRegion);
}

View file

@ -192,10 +192,11 @@ struct SwImageTask : SwTask
if (!image.data || image.w == 0 || image.h == 0) goto end;
image.stride = image.w; //same, pixel buffer size.
if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid)) goto end;
auto clipPath = (clips.count > 0) ? true : false;
//Clip Path?
if (clips.count > 0) {
if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid, clipPath)) goto end;
if (clipPath) {
if (!imageGenRle(&image, pdata, bbox, false)) goto end;
if (image.rle) {
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {

View file

@ -28,6 +28,12 @@
#include <math.h>
#include "tvgCommon.h"
static inline bool mathRotated(const Matrix* m)
{
if (fabs(m->e12) > FLT_EPSILON || fabs(m->e21 > FLT_EPSILON)) return true;
else return false;
}
static inline bool mathIdentity(const Matrix* m)
{