sw_engine raster: code refactoring & optimize code.

* sw_engine raster: code refactoring & optimize code.

1. move the computation out of rolling if possible.
2. renamed internal variables & function prototypes.
This commit is contained in:
Hermet Park 2020-12-02 16:49:53 +09:00 committed by GitHub
parent 2c78945483
commit 1743db705b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 100 deletions

View file

@ -391,4 +391,4 @@ public:
}
#endif
#endif //_THORVG_H_
#endif //_THORVG_H_

View file

@ -218,8 +218,7 @@ struct SwImage
SwRleData* rle = nullptr;
uint32_t* data = nullptr;
SwBBox bbox;
uint32_t width;
uint32_t height;
uint32_t w, h;
};
struct SwCompositor
@ -325,7 +324,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, uint8_t opacity, const Matrix* transform);
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, uint8_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

@ -133,13 +133,13 @@ void imageReset(SwImage* image)
bool imageGenOutline(SwImage* image, const Picture* pdata, unsigned tid, const Matrix* transform)
{
image->outline = mpoolReqOutline(tid);
auto outline = image->outline;
float w, h;
pdata->viewbox(nullptr, nullptr, &w, &h);
if (w == 0 || h == 0) return false;
image->outline = mpoolReqOutline(tid);
auto outline = image->outline;
outline->reservedPtsCnt = 5;
outline->pts = static_cast<SwPoint*>(realloc(outline->pts, outline->reservedPtsCnt * sizeof(SwPoint)));
outline->types = static_cast<uint8_t*>(realloc(outline->types, outline->reservedPtsCnt * sizeof(uint8_t)));
@ -162,14 +162,15 @@ bool imageGenOutline(SwImage* image, const Picture* pdata, unsigned tid, const M
++outline->cntrsCnt;
outline->opened = false;
image->outline = outline;
image->width = w;
image->height = h;
image->outline = outline;
image->w = w;
image->h = h;
return true;
}
void imageFree(SwImage* image)
{
rleFree(image->rle);
}
}

View file

@ -142,25 +142,21 @@ static bool _rasterTranslucentRle(SwSurface* surface, SwRleData* rle, uint32_t c
}
static bool _rasterTranslucentImageRle(SwSurface* surface, SwRleData* rle, uint32_t *img, uint32_t opacity, const Matrix* invTransform, uint32_t w, uint32_t h)
static bool _rasterTranslucentImageRle(SwSurface* surface, SwRleData* rle, uint32_t *img, uint32_t w, uint32_t h, uint32_t opacity, const Matrix* invTransform)
{
auto span = rle->spans;
for (uint32_t i = 0; i < rle->size; ++i) {
for (uint32_t x = 0; x < span->len; ++x) {
auto rX = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e11 + span->y * invTransform->e12 + invTransform->e13));
auto rY = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e21 + span->y * invTransform->e22 + invTransform->e23));
auto ey1 = span->y * invTransform->e12 + invTransform->e13;
auto ey2 = span->y * invTransform->e22 + invTransform->e23;
auto dst = &surface->buffer[span->y * surface->stride + span->x];
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
auto rX = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e11 + ey1));
auto rY = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e21 + ey2));
if (rX < 0 || rX >= w || rY < 0 || rY >= h) continue;
auto dst = &surface->buffer[span->y * surface->stride + span->x + x];
auto index = rY * w + rX; //TODO: need to use image's stride
if (dst && img && img[index]) {
auto alpha = ALPHA_MULTIPLY(span->coverage, opacity);
auto src = ALPHA_BLEND(img[index], alpha);
auto invAlpha = 255 - surface->comp.alpha(src);
*dst = src + ALPHA_BLEND(*dst, invAlpha);
}
auto alpha = ALPHA_MULTIPLY(span->coverage, opacity);
auto src = ALPHA_BLEND(img[rY * w + rX], alpha); //TODO: need to use image's stride
*dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src));
}
++span;
}
@ -168,26 +164,20 @@ static bool _rasterTranslucentImageRle(SwSurface* surface, SwRleData* rle, uint3
}
static bool _rasterImageRle(SwSurface* surface, SwRleData* rle, uint32_t *img, const Matrix* invTransform, uint32_t w, uint32_t h)
static bool _rasterImageRle(SwSurface* surface, SwRleData* rle, uint32_t *img, uint32_t w, uint32_t h, const Matrix* invTransform)
{
if (!rle) return false;
auto span = rle->spans;
for (uint32_t i = 0; i < rle->size; ++i) {
for (uint32_t x = 0; x < span->len; ++x) {
auto rX = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e11 + span->y * invTransform->e12 + invTransform->e13));
auto rY = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e21 + span->y * invTransform->e22 + invTransform->e23));
auto ey1 = span->y * invTransform->e12 + invTransform->e13;
auto ey2 = span->y * invTransform->e22 + invTransform->e23;
auto dst = &surface->buffer[span->y * surface->stride + span->x];
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
auto rX = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e11 + ey1));
auto rY = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e21 + ey2));
if (rX < 0 || rX >= w || rY < 0 || rY >= h) continue;
auto dst = &surface->buffer[span->y * surface->stride + span->x + x];
auto index = rY * w + rX; //TODO: need to use image's stride
if (dst && img && img[index]) {
auto src = ALPHA_BLEND(img[index], span->coverage);
auto invAlpha = 255 - surface->comp.alpha(src);
*dst = src + ALPHA_BLEND(*dst, invAlpha);
}
auto src = ALPHA_BLEND(img[rY * w + rX], span->coverage); //TODO: need to use image's stride
*dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src));
}
++span;
}
@ -195,88 +185,55 @@ static bool _rasterImageRle(SwSurface* surface, SwRleData* rle, uint32_t *img, c
}
static bool _rasterTranslucentImage(SwSurface* surface, uint32_t *img, uint32_t opacity,const SwBBox& region, const Matrix* invTransform, uint32_t w, uint32_t h)
static bool _rasterTranslucentImage(SwSurface* surface, uint32_t *img, uint32_t w, uint32_t h, uint32_t opacity, const SwBBox& region, const Matrix* invTransform)
{
for (auto y = region.min.y; y < region.max.y; y++) {
for (auto x = region.min.x; x < region.max.x; x++) {
auto rX = static_cast<uint32_t>(roundf(x * invTransform->e11 + y * invTransform->e12 + invTransform->e13));
auto rY = static_cast<uint32_t>(roundf(x * invTransform->e21 + y * invTransform->e22 + invTransform->e23));
for (auto y = region.min.y; y < region.max.y; ++y) {
auto dst = &surface->buffer[y * surface->stride + region.min.x];
auto ey1 = y * invTransform->e12 + invTransform->e13;
auto ey2 = y * invTransform->e22 + invTransform->e23;
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
auto rX = static_cast<uint32_t>(roundf(x * invTransform->e11 + ey1));
auto rY = static_cast<uint32_t>(roundf(x * invTransform->e21 + ey2));
if (rX < 0 || rX >= w || rY < 0 || rY >= h) continue;
auto dst = &surface->buffer[y * surface->stride + x];
auto index = rX + (rY * w); //TODO: need to use image's stride
if (dst && img && img[index]) {
auto src = ALPHA_BLEND(img[index], opacity);
auto invAlpha = 255 - surface->comp.alpha(src);
*dst = src + ALPHA_BLEND(*dst, invAlpha);
}
auto src = ALPHA_BLEND(img[rX + (rY * w)], opacity); //TODO: need to use image's stride
*dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src));
}
}
return true;
}
static bool _rasterImage(SwSurface* surface, uint32_t *img, const SwBBox& region, uint32_t w, uint32_t h)
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++) {
for (auto x = region.min.x; x < region.max.x; x++) {
auto dst = &surface->buffer[y * surface->stride + x];
auto index = x + (y * w); //TODO: need to use image's stride
if (dst && img && img[index]) {
auto src = img[index];
auto invAlpha = 255 - surface->comp.alpha(src);
*dst = src + ALPHA_BLEND(*dst, invAlpha);
}
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++) {
*dst = *src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(*src));
}
}
return true;
}
static bool _rasterImage(SwSurface* surface, uint32_t *img, const SwBBox& region, const Matrix* invTransform, uint32_t w, uint32_t h)
static bool _rasterImage(SwSurface* surface, uint32_t *img, uint32_t w, uint32_t h, const SwBBox& region, const Matrix* invTransform)
{
for (auto y = region.min.y; y < region.max.y; y++) {
for (auto x = region.min.x; x < region.max.x; x++) {
auto rX = static_cast<uint32_t>(roundf(x * invTransform->e11 + y * invTransform->e12 + invTransform->e13));
auto rY = static_cast<uint32_t>(roundf(x * invTransform->e21 + y * invTransform->e22 + invTransform->e23));
for (auto y = region.min.y; y < region.max.y; ++y) {
auto dst = &surface->buffer[y * surface->stride + region.min.x];
auto ey1 = y * invTransform->e12 + invTransform->e13;
auto ey2 = y * invTransform->e22 + invTransform->e23;
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
auto rX = static_cast<uint32_t>(roundf(x * invTransform->e11 + ey1));
auto rY = static_cast<uint32_t>(roundf(x * invTransform->e21 + ey2));
if (rX < 0 || rX >= w || rY < 0 || rY >= h) continue;
auto dst = &surface->buffer[y * surface->stride + x];
auto index = rX + (rY * w); //TODO: need to use image's stride
if (dst && img && img[index]) {
auto src = img[index];
auto invAlpha = 255 - surface->comp.alpha(src);
*dst = src + ALPHA_BLEND(*dst, invAlpha);
}
auto src = img[rX + (rY * w)]; //TODO: need to use image's stride
*dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src));
}
}
return true;
}
bool rasterImage(SwSurface* surface, SwImage* image, uint8_t opacity, const Matrix* transform)
{
Matrix invTransform = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
if (transform) _inverse(transform, &invTransform);
if (image->rle) {
if (opacity < 255) return _rasterTranslucentImageRle(surface, image->rle, image->data, opacity, &invTransform, image->width, image->height );
return _rasterImageRle(surface, image->rle, image->data, &invTransform, image->width, image->height );
}
else {
// Fast track
if (_identify(transform)) {
return _rasterImage(surface, image->data, image->bbox, image->width, image->height);
}
else {
if (opacity < 255) return _rasterTranslucentImage(surface, image->data, opacity, image->bbox, &invTransform, image->width, image->height);
return _rasterImage(surface, image->data, image->bbox, &invTransform, image->width, image->height);
}
}
}
static bool _rasterSolidRle(SwSurface* surface, SwRleData* rle, uint32_t color)
{
if (!rle) return false;
@ -538,3 +495,27 @@ bool rasterClear(SwSurface* surface)
}
return true;
}
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, uint8_t opacity)
{
Matrix invTransform;
if (transform) _inverse(transform, &invTransform);
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);
}
else {
// Fast track
if (_identify(transform)) {
return _rasterImage(surface, image->data, image->w, image->h, image->bbox);
}
else {
if (opacity < 255) return _rasterTranslucentImage(surface, image->data, image->w, image->h, opacity, image->bbox, &invTransform);
return _rasterImage(surface, image->data, image->w, image->h, image->bbox, &invTransform);
}
}
}

View file

@ -243,7 +243,7 @@ bool SwRenderer::render(TVG_UNUSED const Picture& picture, void *data)
auto task = static_cast<SwImageTask*>(data);
task->done();
return rasterImage(surface, &task->image, task->opacity, task->transform);
return rasterImage(surface, &task->image, task->transform, task->opacity);
}
bool SwRenderer::render(TVG_UNUSED const Shape& shape, void *data)