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
|
@ -391,4 +391,4 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif //_THORVG_H_
|
#endif //_THORVG_H_
|
|
@ -218,8 +218,7 @@ struct SwImage
|
||||||
SwRleData* rle = nullptr;
|
SwRleData* rle = nullptr;
|
||||||
uint32_t* data = nullptr;
|
uint32_t* data = nullptr;
|
||||||
SwBBox bbox;
|
SwBBox bbox;
|
||||||
uint32_t width;
|
uint32_t w, h;
|
||||||
uint32_t height;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SwCompositor
|
struct SwCompositor
|
||||||
|
@ -325,7 +324,7 @@ void mpoolRetStrokeOutline(unsigned idx);
|
||||||
bool rasterCompositor(SwSurface* surface);
|
bool rasterCompositor(SwSurface* surface);
|
||||||
bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id);
|
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 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 rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||||
bool rasterClear(SwSurface* surface);
|
bool rasterClear(SwSurface* surface);
|
||||||
|
|
||||||
|
|
|
@ -133,13 +133,13 @@ void imageReset(SwImage* image)
|
||||||
|
|
||||||
bool imageGenOutline(SwImage* image, const Picture* pdata, unsigned tid, const Matrix* transform)
|
bool imageGenOutline(SwImage* image, const Picture* pdata, unsigned tid, const Matrix* transform)
|
||||||
{
|
{
|
||||||
image->outline = mpoolReqOutline(tid);
|
|
||||||
auto outline = image->outline;
|
|
||||||
|
|
||||||
float w, h;
|
float w, h;
|
||||||
pdata->viewbox(nullptr, nullptr, &w, &h);
|
pdata->viewbox(nullptr, nullptr, &w, &h);
|
||||||
if (w == 0 || h == 0) return false;
|
if (w == 0 || h == 0) return false;
|
||||||
|
|
||||||
|
image->outline = mpoolReqOutline(tid);
|
||||||
|
auto outline = image->outline;
|
||||||
|
|
||||||
outline->reservedPtsCnt = 5;
|
outline->reservedPtsCnt = 5;
|
||||||
outline->pts = static_cast<SwPoint*>(realloc(outline->pts, outline->reservedPtsCnt * sizeof(SwPoint)));
|
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)));
|
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->cntrsCnt;
|
||||||
|
|
||||||
outline->opened = false;
|
outline->opened = false;
|
||||||
image->outline = outline;
|
|
||||||
|
|
||||||
image->width = w;
|
image->outline = outline;
|
||||||
image->height = h;
|
image->w = w;
|
||||||
|
image->h = h;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void imageFree(SwImage* image)
|
void imageFree(SwImage* image)
|
||||||
{
|
{
|
||||||
rleFree(image->rle);
|
rleFree(image->rle);
|
||||||
}
|
}
|
|
@ -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;
|
auto span = rle->spans;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rle->size; ++i) {
|
for (uint32_t i = 0; i < rle->size; ++i) {
|
||||||
for (uint32_t x = 0; x < span->len; ++x) {
|
auto ey1 = span->y * invTransform->e12 + invTransform->e13;
|
||||||
auto rX = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e11 + span->y * invTransform->e12 + invTransform->e13));
|
auto ey2 = span->y * invTransform->e22 + invTransform->e23;
|
||||||
auto rY = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e21 + 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;
|
if (rX < 0 || rX >= w || rY < 0 || rY >= h) continue;
|
||||||
|
auto alpha = ALPHA_MULTIPLY(span->coverage, opacity);
|
||||||
auto dst = &surface->buffer[span->y * surface->stride + span->x + x];
|
auto src = ALPHA_BLEND(img[rY * w + rX], alpha); //TODO: need to use image's stride
|
||||||
auto index = rY * w + rX; //TODO: need to use image's stride
|
*dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
++span;
|
++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;
|
auto span = rle->spans;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rle->size; ++i) {
|
for (uint32_t i = 0; i < rle->size; ++i) {
|
||||||
for (uint32_t x = 0; x < span->len; ++x) {
|
auto ey1 = span->y * invTransform->e12 + invTransform->e13;
|
||||||
auto rX = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e11 + span->y * invTransform->e12 + invTransform->e13));
|
auto ey2 = span->y * invTransform->e22 + invTransform->e23;
|
||||||
auto rY = static_cast<uint32_t>(roundf((span->x + x) * invTransform->e21 + 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;
|
if (rX < 0 || rX >= w || rY < 0 || rY >= h) continue;
|
||||||
|
auto src = ALPHA_BLEND(img[rY * w + rX], span->coverage); //TODO: need to use image's stride
|
||||||
auto dst = &surface->buffer[span->y * surface->stride + span->x + x];
|
*dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
++span;
|
++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 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 + region.min.x];
|
||||||
auto rX = static_cast<uint32_t>(roundf(x * invTransform->e11 + y * invTransform->e12 + invTransform->e13));
|
auto ey1 = y * invTransform->e12 + invTransform->e13;
|
||||||
auto rY = static_cast<uint32_t>(roundf(x * invTransform->e21 + y * invTransform->e22 + invTransform->e23));
|
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;
|
if (rX < 0 || rX >= w || rY < 0 || rY >= h) continue;
|
||||||
|
auto src = ALPHA_BLEND(img[rX + (rY * w)], opacity); //TODO: need to use image's stride
|
||||||
auto dst = &surface->buffer[y * surface->stride + x];
|
*dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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 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 + region.min.x];
|
||||||
auto dst = &surface->buffer[y * surface->stride + x];
|
auto src = img + region.min.x + (y * w); //TODO: need to use image's stride
|
||||||
auto index = x + (y * w); //TODO: need to use image's stride
|
for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) {
|
||||||
if (dst && img && img[index]) {
|
*dst = *src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(*src));
|
||||||
auto src = img[index];
|
|
||||||
auto invAlpha = 255 - surface->comp.alpha(src);
|
|
||||||
*dst = src + ALPHA_BLEND(*dst, invAlpha);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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 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 + region.min.x];
|
||||||
auto rX = static_cast<uint32_t>(roundf(x * invTransform->e11 + y * invTransform->e12 + invTransform->e13));
|
auto ey1 = y * invTransform->e12 + invTransform->e13;
|
||||||
auto rY = static_cast<uint32_t>(roundf(x * invTransform->e21 + y * invTransform->e22 + invTransform->e23));
|
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;
|
if (rX < 0 || rX >= w || rY < 0 || rY >= h) continue;
|
||||||
|
auto src = img[rX + (rY * w)]; //TODO: need to use image's stride
|
||||||
auto dst = &surface->buffer[y * surface->stride + x];
|
*dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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)
|
static bool _rasterSolidRle(SwSurface* surface, SwRleData* rle, uint32_t color)
|
||||||
{
|
{
|
||||||
if (!rle) return false;
|
if (!rle) return false;
|
||||||
|
@ -538,3 +495,27 @@ bool rasterClear(SwSurface* surface)
|
||||||
}
|
}
|
||||||
return true;
|
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);
|
auto task = static_cast<SwImageTask*>(data);
|
||||||
task->done();
|
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)
|
bool SwRenderer::render(TVG_UNUSED const Shape& shape, void *data)
|
||||||
|
|
Loading…
Add table
Reference in a new issue