sw_engine: optimize raster image.

added a routine that draw non-transformed translucent image.
composition images will use this routine to draw faster.

Also added optimization point comments in raster image.
This commit is contained in:
Hermet Park 2021-01-10 19:54:05 +09:00 committed by Hermet Park
parent dc70920b40
commit 581e33b954
2 changed files with 43 additions and 15 deletions

View file

@ -337,7 +337,7 @@ void mpoolRetStrokeOutline(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 rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, SwBBox& bbox, uint8_t opacity);
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, SwBBox& bbox, uint32_t opacity);
bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
bool rasterClear(SwSurface* surface);

View file

@ -69,11 +69,13 @@ static void _inverse(const Matrix* transform, Matrix* invM)
static bool _identify(const Matrix* transform)
{
if (!transform ||
transform->e11 != 1.0f || transform->e12 != 0.0f || transform->e13 != 0.0f ||
transform->e21 != 0.0f || transform->e22 != 1.0f || transform->e23 != 0.0f ||
transform->e31 != 0.0f || transform->e32 != 0.0f || transform->e33 != 1.0f)
return false;
if (transform) {
if (transform->e11 != 1.0f || transform->e12 != 0.0f || transform->e13 != 0.0f ||
transform->e21 != 0.0f || transform->e22 != 1.0f || transform->e23 != 0.0f ||
transform->e31 != 0.0f || transform->e32 != 0.0f || transform->e33 != 1.0f) {
return false;
}
}
return true;
}
@ -290,6 +292,20 @@ static bool _rasterTranslucentImage(SwSurface* surface, uint32_t *img, uint32_t
}
static bool _rasterTranslucentImage(SwSurface* surface, uint32_t *img, uint32_t w, uint32_t h, uint32_t opacity, const SwBBox& region)
{
for (auto y = region.min.y; y < region.max.y; ++y) {
auto dst = &surface->buffer[y * surface->stride + region.min.x];
auto src = img + region.min.x + (y * w); //TODO: need to use image's stride
for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) {
auto p = ALPHA_BLEND(*src, opacity);
*dst = p + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(p));
}
}
return true;
}
static bool _rasterImage(SwSurface* surface, uint32_t *img, uint32_t w, uint32_t h, const SwBBox& region)
{
for (auto y = region.min.y; y < region.max.y; ++y) {
@ -586,7 +602,7 @@ bool rasterClear(SwSurface* surface)
}
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, SwBBox& bbox, uint8_t opacity)
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, SwBBox& bbox, uint32_t opacity)
{
Matrix invTransform;
@ -594,17 +610,29 @@ bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, Sw
else invTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
if (image->rle) {
if (opacity < 255) return _rasterTranslucentImageRle(surface, image->rle, image->data, image->w, image->h, opacity, &invTransform);
return _rasterImageRle(surface, image->rle, image->data, image->w, image->h, &invTransform);
//Fast track
if (_identify(transform)) {
//OPTIMIZE ME: Support non transformed image. Only shifted image can use these routines.
#ifdef THORVG_LOG_ENABLED
printf("SW_ENGINE: implementation is missing!\n");
#endif
//if (opacity < 255) return _rasterTranslucentImageRle(surface, image->rle, image->data, image->w, image->h, opacity);
//return _rasterImageRle(surface, image->rle, image->data, image->w, image->h);
return false;
} else {
if (opacity < 255) return _rasterTranslucentImageRle(surface, image->rle, image->data, image->w, image->h, opacity, &invTransform);
return _rasterImageRle(surface, image->rle, image->data, image->w, image->h, &invTransform);
}
}
else {
// Fast track
//Fast track
if (_identify(transform)) {
return _rasterImage(surface, image->data, image->w, image->h, bbox);
}
else {
//OPTIMIZE ME: Support non transformed image. Only shifted image can use these routines.
if (opacity < 255) return _rasterTranslucentImage(surface, image->data, image->w, image->h, opacity, bbox);
else return _rasterImage(surface, image->data, image->w, image->h, bbox);
} else {
if (opacity < 255) return _rasterTranslucentImage(surface, image->data, image->w, image->h, opacity, bbox, &invTransform);
return _rasterImage(surface, image->data, image->w, image->h, bbox, &invTransform);
else return _rasterImage(surface, image->data, image->w, image->h, bbox, &invTransform);
}
}
}
}