Skip to content

Commit

Permalink
A few blitting changes for better BB8 performance (#816)
Browse files Browse the repository at this point in the history
* Avoid a temporary copy & conversion for 8bpp fbs in mupdf.scaleBlitBuffer

Now that we can tell MuPDF the exact stride and whether an alpha channel
is present, this *should* behave.

We still have a few BB types that needs the temporary copy, mostly
because they're terrible to begin with, so we can't blame mupdf for not
supporting 'em ;).
(4bpp, because it's, err, fun to address...)
(RGB565, because HAHAHAHAHAHAHAHAHAH).

* Bump LodePNG to 20190210

* Treat PNGs paletted to 16c as grayscale

There's a good chance they're properly dithered to the eInk palette.

(Otherwise, paletted PNGs are expanded to RGB/RGBA).
  • Loading branch information
NiLuJe authored and Frenzie committed Feb 21, 2019
1 parent 45e96d3 commit 7233305
Show file tree
Hide file tree
Showing 11 changed files with 441 additions and 99 deletions.
185 changes: 129 additions & 56 deletions blitbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,13 +850,14 @@ void BB_alpha_blit_from(BlitBuffer *dst, BlitBuffer *src,
}
o_y += 1;
}
} else if (dbb_type == TYPE_BB8A && sbb_type == TYPE_BB8A) {
Color8A *dstptr, *srcptr;
} else if (dbb_type == TYPE_BB8 && sbb_type == TYPE_BB8A) {
Color8A *srcptr;
Color8 *dstptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, Color8A, d_x, d_y, &dstptr);
BB_GET_PIXEL(dst, dbb_rotation, Color8, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, Color8A, o_x, o_y, &srcptr);
alpha = srcptr->alpha;
ainv = 0xFF - alpha;
Expand All @@ -865,124 +866,109 @@ void BB_alpha_blit_from(BlitBuffer *dst, BlitBuffer *src,
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB16 && sbb_type == TYPE_BBRGB16) {
ColorRGB16 *dstptr, *srcptr;
} else if (dbb_type == TYPE_BB8 && sbb_type == TYPE_BBRGB16) {
ColorRGB16 *srcptr;
Color8 *dstptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB16, d_x, d_y, &dstptr);
BB_GET_PIXEL(dst, dbb_rotation, Color8, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, ColorRGB16, o_x, o_y, &srcptr);
*dstptr = *srcptr;
dstptr->a = ColorRGB16_To_A(srcptr->v);
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB24 && sbb_type == TYPE_BBRGB24) {
ColorRGB24 *dstptr, *srcptr;
} else if (dbb_type == TYPE_BB8 && sbb_type == TYPE_BBRGB24) {
ColorRGB24 *srcptr;
Color8 *dstptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB24, d_x, d_y, &dstptr);
BB_GET_PIXEL(dst, dbb_rotation, Color8, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, ColorRGB24, o_x, o_y, &srcptr);
*dstptr = *srcptr;
dstptr->a = RGB_To_A(srcptr->r, srcptr->g, srcptr->b);
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BBRGB32) {
ColorRGB32 *dstptr, *srcptr;
} else if (dbb_type == TYPE_BB8 && sbb_type == TYPE_BBRGB32) {
ColorRGB32 *srcptr;
Color8 *dstptr;
uint8_t srca;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB32, d_x, d_y, &dstptr);
BB_GET_PIXEL(dst, dbb_rotation, Color8, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, ColorRGB32, o_x, o_y, &srcptr);
alpha = srcptr->alpha;
ainv = 0xFF - alpha;
dstptr->r = DIV_255(dstptr->r * ainv + srcptr->r * alpha);
dstptr->g = DIV_255(dstptr->g * ainv + srcptr->g * alpha);
dstptr->b = DIV_255(dstptr->b * ainv + srcptr->b * alpha);
srca = RGB_To_A(srcptr->r, srcptr->g, srcptr->b);
dstptr->a = DIV_255(dstptr->a * ainv + srca * alpha);
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BBRGB24) {
ColorRGB32 *dstptr;
ColorRGB24 *srcptr;
} else if (dbb_type == TYPE_BB8A && sbb_type == TYPE_BB8A) {
Color8A *dstptr, *srcptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB32, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, ColorRGB24, o_x, o_y, &srcptr);
dstptr->r = srcptr->r;
dstptr->g = srcptr->g;
dstptr->b = srcptr->b;
dstptr->alpha = 0xFF;
BB_GET_PIXEL(dst, dbb_rotation, Color8A, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, Color8A, o_x, o_y, &srcptr);
alpha = srcptr->alpha;
ainv = 0xFF - alpha;
dstptr->a = DIV_255(dstptr->a * ainv + srcptr->a * alpha);
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BB8) {
ColorRGB32 *dstptr;
} else if (dbb_type == TYPE_BBRGB16 && sbb_type == TYPE_BB8) {
Color8 *srcptr;
ColorRGB16 *dstptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB32, d_x, d_y, &dstptr);
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB16, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, Color8, o_x, o_y, &srcptr);
dstptr->r = srcptr->a;
dstptr->g = srcptr->a;
dstptr->b = srcptr->a;
dstptr->alpha = 0xFF;
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BB8A) {
ColorRGB32 *dstptr;
Color8A *srcptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB32, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, Color8A, o_x, o_y, &srcptr);
dstptr->r = srcptr->a;
dstptr->g = srcptr->a;
dstptr->b = srcptr->a;
dstptr->alpha = srcptr->alpha; // if bad result, try: 0xFF - srcptr->alpha
dstptr->v = RGB_To_RGB16(srcptr->a, srcptr->a, srcptr->a);
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB16 && sbb_type == TYPE_BB8A) {
Color8A *srcptr;
ColorRGB16 *dstptr;
uint8_t dsta, bdsta;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB16, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, Color8A, o_x, o_y, &srcptr);
dstptr->v = RGB_To_RGB16(srcptr->a, srcptr->a, srcptr->a);
alpha = srcptr->alpha;
ainv = 0xFF - alpha;
dsta = ColorRGB16_To_A(dstptr->v);
bdsta = DIV_255(dsta * ainv + srcptr->a * alpha);
dstptr->v = RGB_To_RGB16(bdsta, bdsta, bdsta);
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB16 && sbb_type == TYPE_BB8) {
Color8 *srcptr;
ColorRGB16 *dstptr;
} else if (dbb_type == TYPE_BBRGB16 && sbb_type == TYPE_BBRGB16) {
ColorRGB16 *dstptr, *srcptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB16, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, Color8, o_x, o_y, &srcptr);
dstptr->v = RGB_To_RGB16(srcptr->a, srcptr->a, srcptr->a);
BB_GET_PIXEL(src, sbb_rotation, ColorRGB16, o_x, o_y, &srcptr);
*dstptr = *srcptr;
o_x += 1;
}
o_y += 1;
Expand Down Expand Up @@ -1021,6 +1007,93 @@ void BB_alpha_blit_from(BlitBuffer *dst, BlitBuffer *src,
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB24 && sbb_type == TYPE_BBRGB24) {
ColorRGB24 *dstptr, *srcptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB24, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, ColorRGB24, o_x, o_y, &srcptr);
*dstptr = *srcptr;
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BBRGB32) {
ColorRGB32 *dstptr, *srcptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB32, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, ColorRGB32, o_x, o_y, &srcptr);
alpha = srcptr->alpha;
ainv = 0xFF - alpha;
dstptr->r = DIV_255(dstptr->r * ainv + srcptr->r * alpha);
dstptr->g = DIV_255(dstptr->g * ainv + srcptr->g * alpha);
dstptr->b = DIV_255(dstptr->b * ainv + srcptr->b * alpha);
//dstptr->alpha = dstptr->alpha;
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BBRGB24) {
ColorRGB32 *dstptr;
ColorRGB24 *srcptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB32, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, ColorRGB24, o_x, o_y, &srcptr);
dstptr->r = srcptr->r;
dstptr->g = srcptr->g;
dstptr->b = srcptr->b;
//dstptr->alpha = dstptr->alpha;
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BB8) {
ColorRGB32 *dstptr;
Color8 *srcptr;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB32, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, Color8, o_x, o_y, &srcptr);
dstptr->r = srcptr->a;
dstptr->g = srcptr->a;
dstptr->b = srcptr->a;
//dstptr->alpha = dstptr->alpha;
o_x += 1;
}
o_y += 1;
}
} else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BB8A) {
ColorRGB32 *dstptr;
Color8A *srcptr;
uint8_t dsta, bdsta;
o_y = offs_y;
for (d_y = dest_y; d_y < dest_y + h; d_y++) {
o_x = offs_x;
for (d_x = dest_x; d_x < dest_x + w; d_x++) {
BB_GET_PIXEL(dst, dbb_rotation, ColorRGB32, d_x, d_y, &dstptr);
BB_GET_PIXEL(src, sbb_rotation, Color8A, o_x, o_y, &srcptr);
alpha = srcptr->alpha;
ainv = 0xFF - alpha;
dsta = RGB_To_A(dstptr->r, dstptr->g, dstptr->b);
bdsta = DIV_255(dsta * ainv + srcptr->a * alpha);
dstptr->r = bdsta;
dstptr->g = bdsta;
dstptr->b = bdsta;
//dstptr->alpha = dstptr->alpha;
o_x += 1;
}
o_y += 1;
}
} else {
fprintf(stderr, "incompatible bb (dst: %d, src: %d) in file %s, line %d!\r\n",
dbb_type, sbb_type, __FILE__, __LINE__); exit(1);
Expand Down
26 changes: 25 additions & 1 deletion ffi-cdecl/lodepng_decl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,26 @@

#include "ffi-cdecl.h"

cdecl_type(LodePNGColorType)
cdecl_enum(LodePNGColorType)
cdecl_type(LodePNGColorType)
cdecl_type(LodePNGDecompressSettings)
cdecl_struct(LodePNGDecompressSettings)
cdecl_struct(LodePNGDecoderSettings)
cdecl_type(LodePNGDecoderSettings)
cdecl_enum(LodePNGFilterStrategy)
cdecl_type(LodePNGFilterStrategy)
cdecl_type(LodePNGCompressSettings)
cdecl_struct(LodePNGCompressSettings)
cdecl_struct(LodePNGEncoderSettings)
cdecl_type(LodePNGEncoderSettings)
cdecl_struct(LodePNGColorMode)
cdecl_type(LodePNGColorMode)
cdecl_struct(LodePNGTime)
cdecl_type(LodePNGTime)
cdecl_struct(LodePNGInfo)
cdecl_type(LodePNGInfo)
cdecl_struct(LodePNGState)
cdecl_type(LodePNGState)
cdecl_func(lodepng_error_text)
cdecl_func(lodepng_decode32_file)
cdecl_func(lodepng_decode32)
Expand All @@ -12,3 +30,9 @@ cdecl_func(lodepng_decode24)
cdecl_func(lodepng_decode_memory)
cdecl_func(lodepng_decode_file)
cdecl_func(lodepng_encode32_file)
cdecl_func(lodepng_state_init)
cdecl_func(lodepng_state_cleanup)
cdecl_func(lodepng_state_copy)
cdecl_func(lodepng_decode)
cdecl_func(lodepng_inspect)
cdecl_func(lodepng_encode)
2 changes: 1 addition & 1 deletion ffi/SDL2_0.lua
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ function S.setWindowIcon(icon)
if not icon then error("setWindowIcon: no icon path given") end

local Png = require("ffi/png")
local ok, re = Png.decodeFromFile(icon)
local ok, re = Png.decodeFromFile(icon, 4)
if not ok then
error(re.." ("..icon..")")
end
Expand Down
2 changes: 1 addition & 1 deletion ffi/framebuffer_linux.lua
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ function framebuffer:clear(w, h)
-- and regions of memory outside of the visible screen *may* be used by other things in the system,
-- for performance reasons, and we do not want to screw them over ;).
-- NOTE: This should be equivalent to line_length * yres
C.memset(self.data, 0xFF, w * (self.fb_bpp / 8) * h)
ffi.fill(self.data, w * (self.fb_bpp / 8) * h, 0xFF)
end
end
Expand Down

0 comments on commit 7233305

Please sign in to comment.