sw_engine: ++8bit grayscale rasterizer.

These rasterizers are added for 8bit maskings.
This commit is contained in:
Hermet Park 2023-05-05 23:57:47 +09:00 committed by Hermet Park
parent 737b89471a
commit 3376f44de5
8 changed files with 395 additions and 230 deletions

View file

@ -241,7 +241,7 @@ struct SwImage
struct SwBlender
{
uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
uint32_t (*lumaValue)(uint32_t c);
uint8_t (*luma)(uint8_t* c);
};
struct SwCompositor;

File diff suppressed because it is too large Load diff

View file

@ -82,8 +82,14 @@ static void avxRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_
}
static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (surface->channelSize != sizeof(uint32_t)) {
TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize);
return false;
}
auto color = surface->blender.join(r, g, b, a);
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
@ -125,8 +131,14 @@ static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, u
}
static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (surface->channelSize != sizeof(uint32_t)) {
TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize);
return false;
}
auto color = surface->blender.join(r, g, b, a);
auto span = rle->spans;
uint32_t src;

View file

@ -20,43 +20,70 @@
* SOFTWARE.
*/
static void inline cRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
template<typename PIXEL_T>
static void inline cRasterPixels(PIXEL_T* dst, uint32_t val, uint32_t offset, int32_t len)
{
dst += offset;
while (len--) *dst++ = val;
}
static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
auto span = rle->spans;
uint32_t src;
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf32[span->y * surface->stride + span->x];
if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
else src = color;
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = src + ALPHA_BLEND(*dst, _ialpha(src));
//32bit channels
if (surface->channelSize == sizeof(uint32_t)) {
auto color = surface->blender.join(r, g, b, a);
uint32_t src;
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf32[span->y * surface->stride + span->x];
if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
else src = color;
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = src + ALPHA_BLEND(*dst, _ialpha(src));
}
}
//8bit grayscale
} else if (surface->channelSize == sizeof(uint8_t)) {
uint8_t src;
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf8[span->y * surface->stride + span->x];
if (span->coverage < 255) src = _multiply<uint8_t>(span->coverage, a);
else src = a;
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = src + _multiply<uint8_t>(*dst, ~src);
}
}
}
return true;
}
static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto ialpha = _ialpha(color);
for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) {
*dst = color + ALPHA_BLEND(*dst, ialpha);
//32bits channels
if (surface->channelSize == sizeof(uint32_t)) {
auto color = surface->blender.join(r, g, b, a);
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
auto ialpha = _ialpha(color);
for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) {
*dst = color + ALPHA_BLEND(*dst, ialpha);
}
}
//8bit grayscale
} else if (surface->channelSize == sizeof(uint8_t)) {
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x;
for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) {
*dst = a + _multiply<uint8_t>(*dst, ~a);
}
}
}
return true;

View file

@ -49,8 +49,14 @@ static void neonRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32
}
static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (surface->channelSize != sizeof(uint32_t)) {
TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize);
return false;
}
auto color = surface->blender.join(r, g, b, a);
auto span = rle->spans;
uint32_t src;
uint8x8_t *vDst = nullptr;
@ -88,8 +94,14 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, u
}
static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (surface->channelSize != sizeof(uint32_t)) {
TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize);
return false;
}
auto color = surface->blender.join(r, g, b, a);
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x);

View file

@ -69,7 +69,7 @@ static bool _arrange(const SwImage* image, const SwBBox* region, int& yStart, in
}
static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity, uint32_t (*blender)(uint32_t), AASpans* aaSpans)
static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity, uint8_t(*blender)(uint8_t*), AASpans* aaSpans)
{
#define TEXMAP_TRANSLUCENT
#define TEXMAP_MASKING
@ -79,7 +79,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
}
static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t (*blender)(uint32_t), AASpans* aaSpans)
static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint8_t(*blender)(uint8_t*), AASpans* aaSpans)
{
#define TEXMAP_MASKING
#include "tvgSwRasterTexmapInternal.h"
@ -102,7 +102,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
/* This mapping algorithm is based on Mikael Kalms's. */
static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const SwBBox* region, uint32_t opacity, Polygon& polygon, uint32_t (*blender)(uint32_t), AASpans* aaSpans)
static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const SwBBox* region, uint32_t opacity, Polygon& polygon, uint8_t(*blender)(uint8_t*), AASpans* aaSpans)
{
float x[3] = {polygon.vertex[0].pt.x, polygon.vertex[1].pt.x, polygon.vertex[2].pt.x};
float y[3] = {polygon.vertex[0].pt.y, polygon.vertex[1].pt.y, polygon.vertex[2].pt.y};
@ -545,7 +545,7 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans)
| / |
3 -- 2
*/
static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint32_t (*blender)(uint32_t))
static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint8_t(*blender)(uint8_t*))
{
//Exceptions: No dedicated drawing area?
if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false;
@ -602,7 +602,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const
Should provide two Polygons, one for each triangle.
// TODO: region?
*/
static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint32_t (*blender)(uint32_t))
static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint8_t(*blender)(uint8_t*))
{
//Exceptions: No dedicated drawing area?
if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false;

View file

@ -37,7 +37,8 @@
SwSpan* span = nullptr; //used only when rle based.
#ifdef TEXMAP_MASKING
uint32_t* cmp;
uint8_t* cmp;
auto csize = surface->compositor->image.channelSize;
#endif
if (!_arrange(image, region, yStart, yEnd)) return;
@ -94,7 +95,7 @@
x = x1;
#ifdef TEXMAP_MASKING
cmp = &surface->compositor->image.buf32[y * surface->compositor->image.stride + x1];
cmp = &surface->compositor->image.buf8[(y * surface->compositor->image.stride + x1) * csize];
#endif
//Draw horizontal line
while (x++ < x2) {
@ -130,9 +131,9 @@
px = INTERPOLATE(ab, px, px2);
}
#if defined(TEXMAP_MASKING) && defined(TEXMAP_TRANSLUCENT)
auto src = ALPHA_BLEND(px, _multiplyAlpha(opacity, blender(*cmp)));
auto src = ALPHA_BLEND(px, _multiply<uint32_t>(opacity, blender(cmp)));
#elif defined(TEXMAP_MASKING)
auto src = ALPHA_BLEND(px, blender(*cmp));
auto src = ALPHA_BLEND(px, blender(cmp));
#elif defined(TEXMAP_TRANSLUCENT)
auto src = ALPHA_BLEND(px, opacity);
#else
@ -141,7 +142,7 @@
*buf = src + ALPHA_BLEND(*buf, _ialpha(src));
++buf;
#ifdef TEXMAP_MASKING
++cmp;
cmp += csize;
#endif
//Step UV horizontally
u += _dudx;

View file

@ -167,8 +167,7 @@ bool Paint::Impl::render(RenderMethod& renderer)
if (compData && compData->method != CompositeMethod::ClipPath && !(compData->target->pImpl->ctxFlag & ContextFlag::FastTrack)) {
auto region = smethod->bounds(renderer);
if (region.w == 0 || region.h == 0) return true;
//cmp = renderer.target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method));
cmp = renderer.target(region, renderer.colorSpace());
cmp = renderer.target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method));
if (renderer.beginComposite(cmp, CompositeMethod::None, 255)) {
compData->target->pImpl->render(renderer);
}