mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-23 14:48:24 +00:00
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:
parent
2c78945483
commit
1743db705b
5 changed files with 81 additions and 100 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,10 +162,11 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue