| Index: lib/gfx/gfx.c
|
| diff --git a/lib/gfx/gfx.c b/lib/gfx/gfx.c
|
| index d76e61269602f388aeb376878905a34fda3f1866..621c20bb50ad5ebc031b1cb13e99d424193eeb77 100644
|
| --- a/lib/gfx/gfx.c
|
| +++ b/lib/gfx/gfx.c
|
| @@ -46,13 +46,13 @@
|
|
|
| static uint16_t ARGB8888_to_RGB565(uint32_t in)
|
| {
|
| - uint16_t out;
|
| + uint16_t out;
|
|
|
| - out = (in >> 3) & 0x1f; // b
|
| - out |= ((in >> 10) & 0x3f) << 5; // g
|
| - out |= ((in >> 19) & 0x1f) << 11; // r
|
| + out = (in >> 3) & 0x1f; // b
|
| + out |= ((in >> 10) & 0x3f) << 5; // g
|
| + out |= ((in >> 19) & 0x1f) << 11; // r
|
|
|
| - return out;
|
| + return out;
|
| }
|
|
|
| /**
|
| @@ -60,31 +60,31 @@ static uint16_t ARGB8888_to_RGB565(uint32_t in)
|
| */
|
| void gfx_copyrect(gfx_surface *surface, uint x, uint y, uint width, uint height, uint x2, uint y2)
|
| {
|
| - // trim
|
| - if (x >= surface->width)
|
| - return;
|
| - if (x2 >= surface->width)
|
| - return;
|
| - if (y >= surface->height)
|
| - return;
|
| - if (y2 >= surface->height)
|
| - return;
|
| - if (width == 0 || height == 0)
|
| - return;
|
| -
|
| - // clip the width to src or dest
|
| - if (x + width > surface->width)
|
| - width = surface->width - x;
|
| - if (x2 + width > surface->width)
|
| - width = surface->width - x2;
|
| -
|
| - // clip the height to src or dest
|
| - if (y + height > surface->height)
|
| - height = surface->height - y;
|
| - if (y2 + height > surface->height)
|
| - height = surface->height - y2;
|
| -
|
| - surface->copyrect(surface, x, y, width, height, x2, y2);
|
| + // trim
|
| + if (x >= surface->width)
|
| + return;
|
| + if (x2 >= surface->width)
|
| + return;
|
| + if (y >= surface->height)
|
| + return;
|
| + if (y2 >= surface->height)
|
| + return;
|
| + if (width == 0 || height == 0)
|
| + return;
|
| +
|
| + // clip the width to src or dest
|
| + if (x + width > surface->width)
|
| + width = surface->width - x;
|
| + if (x2 + width > surface->width)
|
| + width = surface->width - x2;
|
| +
|
| + // clip the height to src or dest
|
| + if (y + height > surface->height)
|
| + height = surface->height - y;
|
| + if (y2 + height > surface->height)
|
| + height = surface->height - y2;
|
| +
|
| + surface->copyrect(surface, x, y, width, height, x2, y2);
|
| }
|
|
|
| /**
|
| @@ -92,24 +92,24 @@ void gfx_copyrect(gfx_surface *surface, uint x, uint y, uint width, uint height,
|
| */
|
| void gfx_fillrect(gfx_surface *surface, uint x, uint y, uint width, uint height, uint color)
|
| {
|
| - LTRACEF("surface %p, x %u y %u w %u h %u c %u\n", surface, x, y, width, height, color);
|
| - // trim
|
| - if (unlikely(x >= surface->width))
|
| - return;
|
| - if (y >= surface->height)
|
| - return;
|
| - if (width == 0 || height == 0)
|
| - return;
|
| -
|
| - // clip the width
|
| - if (x + width > surface->width)
|
| - width = surface->width - x;
|
| -
|
| - // clip the height
|
| - if (y + height > surface->height)
|
| - height = surface->height - y;
|
| -
|
| - surface->fillrect(surface, x, y, width, height, color);
|
| + LTRACEF("surface %p, x %u y %u w %u h %u c %u\n", surface, x, y, width, height, color);
|
| + // trim
|
| + if (unlikely(x >= surface->width))
|
| + return;
|
| + if (y >= surface->height)
|
| + return;
|
| + if (width == 0 || height == 0)
|
| + return;
|
| +
|
| + // clip the width
|
| + if (x + width > surface->width)
|
| + width = surface->width - x;
|
| +
|
| + // clip the height
|
| + if (y + height > surface->height)
|
| + height = surface->height - y;
|
| +
|
| + surface->fillrect(surface, x, y, width, height, color);
|
| }
|
|
|
| /**
|
| @@ -117,168 +117,220 @@ void gfx_fillrect(gfx_surface *surface, uint x, uint y, uint width, uint height,
|
| */
|
| void gfx_putpixel(gfx_surface *surface, uint x, uint y, uint color)
|
| {
|
| - if (unlikely(x >= surface->width))
|
| - return;
|
| - if (y >= surface->height)
|
| - return;
|
| + if (unlikely(x >= surface->width))
|
| + return;
|
| + if (y >= surface->height)
|
| + return;
|
|
|
| - surface->putpixel(surface, x, y, color);
|
| + surface->putpixel(surface, x, y, color);
|
| }
|
|
|
| static void putpixel16(gfx_surface *surface, uint x, uint y, uint color)
|
| {
|
| - uint16_t *dest = &((uint16_t *)surface->ptr)[x + y * surface->stride];
|
| + uint16_t *dest = &((uint16_t *)surface->ptr)[x + y * surface->stride];
|
|
|
| - // colors come in in ARGB 8888 form, flatten them
|
| - *dest = ARGB8888_to_RGB565(color);
|
| + // colors come in in ARGB 8888 form, flatten them
|
| + *dest = ARGB8888_to_RGB565(color);
|
| }
|
|
|
| static void putpixel32(gfx_surface *surface, uint x, uint y, uint color)
|
| {
|
| - uint32_t *dest = &((uint32_t *)surface->ptr)[x + y * surface->stride];
|
| + uint32_t *dest = &((uint32_t *)surface->ptr)[x + y * surface->stride];
|
|
|
| - *dest = color;
|
| + *dest = color;
|
| }
|
|
|
| static void copyrect16(gfx_surface *surface, uint x, uint y, uint width, uint height, uint x2, uint y2)
|
| {
|
| - // copy
|
| - const uint16_t *src = &((const uint16_t *)surface->ptr)[x + y * surface->stride];
|
| - uint16_t *dest = &((uint16_t *)surface->ptr)[x2 + y2 * surface->stride];
|
| - uint stride_diff = surface->stride - width;
|
| -
|
| - if (dest < src) {
|
| - uint i, j;
|
| - for (i=0; i < height; i++) {
|
| - for (j=0; j < width; j++) {
|
| - *dest = *src;
|
| - dest++;
|
| - src++;
|
| - }
|
| - dest += stride_diff;
|
| - src += stride_diff;
|
| - }
|
| - } else {
|
| - // copy backwards
|
| - src += height * surface->stride + width;
|
| - dest += height * surface->stride + width;
|
| -
|
| - uint i, j;
|
| - for (i=0; i < height; i++) {
|
| - for (j=0; j < width; j++) {
|
| - *dest = *src;
|
| - dest--;
|
| - src--;
|
| - }
|
| - dest -= stride_diff;
|
| - src -= stride_diff;
|
| - }
|
| - }
|
| + // copy
|
| + const uint16_t *src = &((const uint16_t *)surface->ptr)[x + y * surface->stride];
|
| + uint16_t *dest = &((uint16_t *)surface->ptr)[x2 + y2 * surface->stride];
|
| + uint stride_diff = surface->stride - width;
|
| +
|
| + if (dest < src) {
|
| + uint i, j;
|
| + for (i=0; i < height; i++) {
|
| + for (j=0; j < width; j++) {
|
| + *dest = *src;
|
| + dest++;
|
| + src++;
|
| + }
|
| + dest += stride_diff;
|
| + src += stride_diff;
|
| + }
|
| + } else {
|
| + // copy backwards
|
| + src += height * surface->stride + width;
|
| + dest += height * surface->stride + width;
|
| +
|
| + uint i, j;
|
| + for (i=0; i < height; i++) {
|
| + for (j=0; j < width; j++) {
|
| + *dest = *src;
|
| + dest--;
|
| + src--;
|
| + }
|
| + dest -= stride_diff;
|
| + src -= stride_diff;
|
| + }
|
| + }
|
| }
|
|
|
| static void fillrect16(gfx_surface *surface, uint x, uint y, uint width, uint height, uint color)
|
| {
|
| - uint16_t *dest = &((uint16_t *)surface->ptr)[x + y * surface->stride];
|
| - uint stride_diff = surface->stride - width;
|
| -
|
| - uint16_t color16 = ARGB8888_to_RGB565(color);
|
| -
|
| - uint i, j;
|
| - for (i=0; i < height; i++) {
|
| - for (j=0; j < width; j++) {
|
| - *dest = color16;
|
| - dest++;
|
| - }
|
| - dest += stride_diff;
|
| - }
|
| + uint16_t *dest = &((uint16_t *)surface->ptr)[x + y * surface->stride];
|
| + uint stride_diff = surface->stride - width;
|
| +
|
| + uint16_t color16 = ARGB8888_to_RGB565(color);
|
| +
|
| + uint i, j;
|
| + for (i=0; i < height; i++) {
|
| + for (j=0; j < width; j++) {
|
| + *dest = color16;
|
| + dest++;
|
| + }
|
| + dest += stride_diff;
|
| + }
|
| }
|
|
|
| static void copyrect32(gfx_surface *surface, uint x, uint y, uint width, uint height, uint x2, uint y2)
|
| {
|
| - // copy
|
| - const uint32_t *src = &((const uint32_t *)surface->ptr)[x + y * surface->stride];
|
| - uint32_t *dest = &((uint32_t *)surface->ptr)[x2 + y2 * surface->stride];
|
| - uint stride_diff = surface->stride - width;
|
| -
|
| - if (dest < src) {
|
| - uint i, j;
|
| - for (i=0; i < height; i++) {
|
| - for (j=0; j < width; j++) {
|
| - *dest = *src;
|
| - dest++;
|
| - src++;
|
| - }
|
| - dest += stride_diff;
|
| - src += stride_diff;
|
| - }
|
| - } else {
|
| - // copy backwards
|
| - src += height * surface->stride + width;
|
| - dest += height * surface->stride + width;
|
| -
|
| - uint i, j;
|
| - for (i=0; i < height; i++) {
|
| - for (j=0; j < width; j++) {
|
| - *dest = *src;
|
| - dest--;
|
| - src--;
|
| - }
|
| - dest -= stride_diff;
|
| - src -= stride_diff;
|
| - }
|
| - }
|
| + // copy
|
| + const uint32_t *src = &((const uint32_t *)surface->ptr)[x + y * surface->stride];
|
| + uint32_t *dest = &((uint32_t *)surface->ptr)[x2 + y2 * surface->stride];
|
| + uint stride_diff = surface->stride - width;
|
| +
|
| + if (dest < src) {
|
| + uint i, j;
|
| + for (i=0; i < height; i++) {
|
| + for (j=0; j < width; j++) {
|
| + *dest = *src;
|
| + dest++;
|
| + src++;
|
| + }
|
| + dest += stride_diff;
|
| + src += stride_diff;
|
| + }
|
| + } else {
|
| + // copy backwards
|
| + src += height * surface->stride + width;
|
| + dest += height * surface->stride + width;
|
| +
|
| + uint i, j;
|
| + for (i=0; i < height; i++) {
|
| + for (j=0; j < width; j++) {
|
| + *dest = *src;
|
| + dest--;
|
| + src--;
|
| + }
|
| + dest -= stride_diff;
|
| + src -= stride_diff;
|
| + }
|
| + }
|
| }
|
|
|
| static void fillrect32(gfx_surface *surface, uint x, uint y, uint width, uint height, uint color)
|
| {
|
| - uint32_t *dest = &((uint32_t *)surface->ptr)[x + y * surface->stride];
|
| - uint stride_diff = surface->stride - width;
|
| -
|
| - uint i, j;
|
| - for (i=0; i < height; i++) {
|
| - for (j=0; j < width; j++) {
|
| - *dest = color;
|
| - dest++;
|
| - }
|
| - dest += stride_diff;
|
| - }
|
| + uint32_t *dest = &((uint32_t *)surface->ptr)[x + y * surface->stride];
|
| + uint stride_diff = surface->stride - width;
|
| +
|
| + uint i, j;
|
| + for (i=0; i < height; i++) {
|
| + for (j=0; j < width; j++) {
|
| + *dest = color;
|
| + dest++;
|
| + }
|
| + dest += stride_diff;
|
| + }
|
| +}
|
| +
|
| +void gfx_line(gfx_surface* surface, uint x1, uint y1, uint x2, uint y2, uint color)
|
| +{
|
| + if (unlikely(x1 >= surface->width))
|
| + return;
|
| + if (unlikely(x2 >= surface->width))
|
| + return;
|
| +
|
| + if (y1 >= surface->height)
|
| + return;
|
| + if (y2 >= surface->height)
|
| + return;
|
| +
|
| + int dx = x2 - x1;
|
| + int dy = y2 - y1;
|
| +
|
| + int sdx = (0 < dx) - (dx < 0);
|
| + int sdy = (0 < dy) - (dy < 0);
|
| +
|
| + uint dxabs = (dx > 0) ? dx : -dx;
|
| + uint dyabs = (dy > 0) ? dy : -dy;
|
| +
|
| + uint x = dyabs >> 1;
|
| + uint y = dxabs >> 1;
|
| +
|
| + uint px = x1;
|
| + uint py = y1;
|
| +
|
| + if (dxabs >= dyabs) {
|
| + // mostly horizontal line.
|
| + for(uint i = 0; i < dxabs; i++) {
|
| + y += dyabs;
|
| + if (y >= dxabs) {
|
| + y -= dxabs;
|
| + py += sdy;
|
| + }
|
| + px += sdx;
|
| + surface->putpixel(surface, px, py, color);
|
| + }
|
| + } else {
|
| + // mostly vertical line.
|
| + for(uint i = 0; i < dyabs; i++) {
|
| + x += dxabs;
|
| + if (x >= dyabs) {
|
| + x -= dyabs;
|
| + px += sdx;
|
| + }
|
| + py += sdy;
|
| + surface->putpixel(surface, px, py, color);
|
| + }
|
| + }
|
| }
|
|
|
| uint32_t alpha32_add_ignore_destalpha(uint32_t dest, uint32_t src)
|
| {
|
| - uint32_t cdest[3];
|
| - uint32_t csrc[3];
|
| + uint32_t cdest[3];
|
| + uint32_t csrc[3];
|
|
|
| - uint32_t srca;
|
| - uint32_t srcainv;
|
| + uint32_t srca;
|
| + uint32_t srcainv;
|
|
|
| - srca = (src >> 24) & 0xff;
|
| - if (srca == 0) {
|
| - return dest;
|
| - } else if (srca == 255) {
|
| - return src;
|
| - }
|
| - srca++;
|
| - srcainv = (255 - srca);
|
| + srca = (src >> 24) & 0xff;
|
| + if (srca == 0) {
|
| + return dest;
|
| + } else if (srca == 255) {
|
| + return src;
|
| + }
|
| + srca++;
|
| + srcainv = (255 - srca);
|
|
|
| - cdest[0] = (dest >> 16) & 0xff;
|
| - cdest[1] = (dest >> 8) & 0xff;
|
| - cdest[2] = (dest >> 0) & 0xff;
|
| + cdest[0] = (dest >> 16) & 0xff;
|
| + cdest[1] = (dest >> 8) & 0xff;
|
| + cdest[2] = (dest >> 0) & 0xff;
|
|
|
| - csrc[0] = (src >> 16) & 0xff;
|
| - csrc[1] = (src >> 8) & 0xff;
|
| - csrc[2] = (src >> 0) & 0xff;
|
| + csrc[0] = (src >> 16) & 0xff;
|
| + csrc[1] = (src >> 8) & 0xff;
|
| + csrc[2] = (src >> 0) & 0xff;
|
|
|
| -// if (srca > 0)
|
| -// printf("s %d %d %d d %d %d %d a %d ai %d\n", csrc[0], csrc[1], csrc[2], cdest[0], cdest[1], cdest[2], srca, srcainv);
|
| +// if (srca > 0)
|
| +// printf("s %d %d %d d %d %d %d a %d ai %d\n", csrc[0], csrc[1], csrc[2], cdest[0], cdest[1], cdest[2], srca, srcainv);
|
|
|
| - uint32_t cres[3];
|
| + uint32_t cres[3];
|
|
|
| - cres[0] = ((csrc[0] * srca) / 256) + ((cdest[0] * srcainv) / 256);
|
| - cres[1] = ((csrc[1] * srca) / 256) + ((cdest[1] * srcainv) / 256);
|
| - cres[2] = ((csrc[2] * srca) / 256) + ((cdest[2] * srcainv) / 256);
|
| + cres[0] = ((csrc[0] * srca) / 256) + ((cdest[0] * srcainv) / 256);
|
| + cres[1] = ((csrc[1] * srca) / 256) + ((cdest[1] * srcainv) / 256);
|
| + cres[2] = ((csrc[2] * srca) / 256) + ((cdest[2] * srcainv) / 256);
|
|
|
| - return (srca << 24) | (cres[0] << 16) | (cres[1] << 8) | (cres[2]);
|
| + return (srca << 24) | (cres[0] << 16) | (cres[1] << 8) | (cres[2]);
|
| }
|
|
|
| /**
|
| @@ -288,85 +340,85 @@ uint32_t alpha32_add_ignore_destalpha(uint32_t dest, uint32_t src)
|
| */
|
| void gfx_surface_blend(struct gfx_surface *target, struct gfx_surface *source, uint destx, uint desty)
|
| {
|
| - DEBUG_ASSERT(target->format == source->format);
|
| -
|
| - LTRACEF("target %p, source %p, destx %u, desty %u\n", target, source, destx, desty);
|
| -
|
| - if (destx >= target->width)
|
| - return;
|
| - if (desty >= target->height)
|
| - return;
|
| -
|
| - uint width = source->width;
|
| - if (destx + width > target->width)
|
| - width = target->width - destx;
|
| -
|
| - uint height = source->height;
|
| - if (desty + height > target->height)
|
| - height = target->height - desty;
|
| -
|
| - // XXX total hack to deal with various blends
|
| - if (source->format == GFX_FORMAT_RGB_565 && target->format == GFX_FORMAT_RGB_565) {
|
| - // 16 bit to 16 bit
|
| - const uint16_t *src = (const uint16_t *)source->ptr;
|
| - uint16_t *dest = &((uint16_t *)target->ptr)[destx + desty * target->stride];
|
| - uint dest_stride_diff = target->stride - width;
|
| - uint source_stride_diff = source->stride - width;
|
| -
|
| - LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff, source_stride_diff);
|
| -
|
| - uint i, j;
|
| - for (i=0; i < height; i++) {
|
| - for (j=0; j < width; j++) {
|
| - *dest = *src;
|
| - dest++;
|
| - src++;
|
| - }
|
| - dest += dest_stride_diff;
|
| - src += source_stride_diff;
|
| - }
|
| - } else if (source->format == GFX_FORMAT_ARGB_8888 && target->format == GFX_FORMAT_ARGB_8888) {
|
| - // both are 32 bit modes, both alpha
|
| - const uint32_t *src = (const uint32_t *)source->ptr;
|
| - uint32_t *dest = &((uint32_t *)target->ptr)[destx + desty * target->stride];
|
| - uint dest_stride_diff = target->stride - width;
|
| - uint source_stride_diff = source->stride - width;
|
| -
|
| - LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff, source_stride_diff);
|
| -
|
| - uint i, j;
|
| - for (i=0; i < height; i++) {
|
| - for (j=0; j < width; j++) {
|
| - // XXX ignores destination alpha
|
| - *dest = alpha32_add_ignore_destalpha(*dest, *src);
|
| - dest++;
|
| - src++;
|
| - }
|
| - dest += dest_stride_diff;
|
| - src += source_stride_diff;
|
| - }
|
| - } else if (source->format == GFX_FORMAT_RGB_x888 && target->format == GFX_FORMAT_RGB_x888) {
|
| - // both are 32 bit modes, no alpha
|
| - const uint32_t *src = (const uint32_t *)source->ptr;
|
| - uint32_t *dest = &((uint32_t *)target->ptr)[destx + desty * target->stride];
|
| - uint dest_stride_diff = target->stride - width;
|
| - uint source_stride_diff = source->stride - width;
|
| -
|
| - LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff, source_stride_diff);
|
| -
|
| - uint i, j;
|
| - for (i=0; i < height; i++) {
|
| - for (j=0; j < width; j++) {
|
| - *dest = *src;
|
| - dest++;
|
| - src++;
|
| - }
|
| - dest += dest_stride_diff;
|
| - src += source_stride_diff;
|
| - }
|
| - } else {
|
| - panic("gfx_surface_blend: unimplemented colorspace combination (source %d target %d)\n", source->format, target->format);
|
| - }
|
| + DEBUG_ASSERT(target->format == source->format);
|
| +
|
| + LTRACEF("target %p, source %p, destx %u, desty %u\n", target, source, destx, desty);
|
| +
|
| + if (destx >= target->width)
|
| + return;
|
| + if (desty >= target->height)
|
| + return;
|
| +
|
| + uint width = source->width;
|
| + if (destx + width > target->width)
|
| + width = target->width - destx;
|
| +
|
| + uint height = source->height;
|
| + if (desty + height > target->height)
|
| + height = target->height - desty;
|
| +
|
| + // XXX total hack to deal with various blends
|
| + if (source->format == GFX_FORMAT_RGB_565 && target->format == GFX_FORMAT_RGB_565) {
|
| + // 16 bit to 16 bit
|
| + const uint16_t *src = (const uint16_t *)source->ptr;
|
| + uint16_t *dest = &((uint16_t *)target->ptr)[destx + desty * target->stride];
|
| + uint dest_stride_diff = target->stride - width;
|
| + uint source_stride_diff = source->stride - width;
|
| +
|
| + LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff, source_stride_diff);
|
| +
|
| + uint i, j;
|
| + for (i=0; i < height; i++) {
|
| + for (j=0; j < width; j++) {
|
| + *dest = *src;
|
| + dest++;
|
| + src++;
|
| + }
|
| + dest += dest_stride_diff;
|
| + src += source_stride_diff;
|
| + }
|
| + } else if (source->format == GFX_FORMAT_ARGB_8888 && target->format == GFX_FORMAT_ARGB_8888) {
|
| + // both are 32 bit modes, both alpha
|
| + const uint32_t *src = (const uint32_t *)source->ptr;
|
| + uint32_t *dest = &((uint32_t *)target->ptr)[destx + desty * target->stride];
|
| + uint dest_stride_diff = target->stride - width;
|
| + uint source_stride_diff = source->stride - width;
|
| +
|
| + LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff, source_stride_diff);
|
| +
|
| + uint i, j;
|
| + for (i=0; i < height; i++) {
|
| + for (j=0; j < width; j++) {
|
| + // XXX ignores destination alpha
|
| + *dest = alpha32_add_ignore_destalpha(*dest, *src);
|
| + dest++;
|
| + src++;
|
| + }
|
| + dest += dest_stride_diff;
|
| + src += source_stride_diff;
|
| + }
|
| + } else if (source->format == GFX_FORMAT_RGB_x888 && target->format == GFX_FORMAT_RGB_x888) {
|
| + // both are 32 bit modes, no alpha
|
| + const uint32_t *src = (const uint32_t *)source->ptr;
|
| + uint32_t *dest = &((uint32_t *)target->ptr)[destx + desty * target->stride];
|
| + uint dest_stride_diff = target->stride - width;
|
| + uint source_stride_diff = source->stride - width;
|
| +
|
| + LTRACEF("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff, source_stride_diff);
|
| +
|
| + uint i, j;
|
| + for (i=0; i < height; i++) {
|
| + for (j=0; j < width; j++) {
|
| + *dest = *src;
|
| + dest++;
|
| + src++;
|
| + }
|
| + dest += dest_stride_diff;
|
| + src += source_stride_diff;
|
| + }
|
| + } else {
|
| + panic("gfx_surface_blend: unimplemented colorspace combination (source %d target %d)\n", source->format, target->format);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -374,10 +426,10 @@ void gfx_surface_blend(struct gfx_surface *target, struct gfx_surface *source, u
|
| */
|
| void gfx_flush(gfx_surface *surface)
|
| {
|
| - arch_clean_cache_range((addr_t)surface->ptr, surface->len);
|
| + arch_clean_cache_range((addr_t)surface->ptr, surface->len);
|
|
|
| - if (surface->flush)
|
| - surface->flush(0, surface->height-1);
|
| + if (surface->flush)
|
| + surface->flush(0, surface->height-1);
|
| }
|
|
|
| /**
|
| @@ -385,22 +437,21 @@ void gfx_flush(gfx_surface *surface)
|
| */
|
| void gfx_flush_rows(struct gfx_surface *surface, uint start, uint end)
|
| {
|
| - if (start > end) {
|
| - uint temp = start;
|
| - start = end;
|
| - end = temp;
|
| - }
|
| -
|
| - if (start >= surface->height)
|
| - return;
|
| - if (end >= surface->height)
|
| - end = surface->height - 1;
|
| + if (start > end) {
|
| + uint temp = start;
|
| + start = end;
|
| + end = temp;
|
| + }
|
|
|
| - arch_clean_cache_range((addr_t)surface->ptr + start * surface->stride * surface->pixelsize, (end - start + 1) * surface->stride * surface->pixelsize);
|
| + if (start >= surface->height)
|
| + return;
|
| + if (end >= surface->height)
|
| + end = surface->height - 1;
|
|
|
| - if (surface->flush)
|
| - surface->flush(start, end);
|
| + arch_clean_cache_range((addr_t)surface->ptr + start * surface->stride * surface->pixelsize, (end - start + 1) * surface->stride * surface->pixelsize);
|
|
|
| + if (surface->flush)
|
| + surface->flush(start, end);
|
| }
|
|
|
|
|
| @@ -409,53 +460,53 @@ void gfx_flush_rows(struct gfx_surface *surface, uint start, uint end)
|
| */
|
| gfx_surface *gfx_create_surface(void *ptr, uint width, uint height, uint stride, gfx_format format)
|
| {
|
| - DEBUG_ASSERT(width > 0);
|
| - DEBUG_ASSERT(height > 0);
|
| - DEBUG_ASSERT(stride >= width);
|
| - DEBUG_ASSERT(format < GFX_FORMAT_MAX);
|
| -
|
| - gfx_surface *surface = malloc(sizeof(gfx_surface));
|
| -
|
| - surface->free_on_destroy = false;
|
| - surface->format = format;
|
| - surface->width = width;
|
| - surface->height = height;
|
| - surface->stride = stride;
|
| - surface->alpha = MAX_ALPHA;
|
| -
|
| - // set up some function pointers
|
| - switch (format) {
|
| - case GFX_FORMAT_RGB_565:
|
| - surface->copyrect = ©rect16;
|
| - surface->fillrect = &fillrect16;
|
| - surface->putpixel = &putpixel16;
|
| - surface->pixelsize = 2;
|
| - surface->len = surface->height * surface->stride * surface->pixelsize;
|
| - break;
|
| - case GFX_FORMAT_RGB_x888:
|
| - case GFX_FORMAT_ARGB_8888:
|
| - surface->copyrect = ©rect32;
|
| - surface->fillrect = &fillrect32;
|
| - surface->putpixel = &putpixel32;
|
| - surface->pixelsize = 4;
|
| - surface->len = surface->height * surface->stride * surface->pixelsize;
|
| - break;
|
| - default:
|
| - dprintf(INFO, "invalid graphics format\n");
|
| - DEBUG_ASSERT(0);
|
| - free(surface);
|
| - return NULL;
|
| - }
|
| -
|
| - if (ptr == NULL) {
|
| - // allocate a buffer
|
| - ptr = malloc(surface->len);
|
| - DEBUG_ASSERT(ptr);
|
| - surface->free_on_destroy = true;
|
| - }
|
| - surface->ptr = ptr;
|
| -
|
| - return surface;
|
| + DEBUG_ASSERT(width > 0);
|
| + DEBUG_ASSERT(height > 0);
|
| + DEBUG_ASSERT(stride >= width);
|
| + DEBUG_ASSERT(format < GFX_FORMAT_MAX);
|
| +
|
| + gfx_surface *surface = malloc(sizeof(gfx_surface));
|
| +
|
| + surface->free_on_destroy = false;
|
| + surface->format = format;
|
| + surface->width = width;
|
| + surface->height = height;
|
| + surface->stride = stride;
|
| + surface->alpha = MAX_ALPHA;
|
| +
|
| + // set up some function pointers
|
| + switch (format) {
|
| + case GFX_FORMAT_RGB_565:
|
| + surface->copyrect = ©rect16;
|
| + surface->fillrect = &fillrect16;
|
| + surface->putpixel = &putpixel16;
|
| + surface->pixelsize = 2;
|
| + surface->len = surface->height * surface->stride * surface->pixelsize;
|
| + break;
|
| + case GFX_FORMAT_RGB_x888:
|
| + case GFX_FORMAT_ARGB_8888:
|
| + surface->copyrect = ©rect32;
|
| + surface->fillrect = &fillrect32;
|
| + surface->putpixel = &putpixel32;
|
| + surface->pixelsize = 4;
|
| + surface->len = surface->height * surface->stride * surface->pixelsize;
|
| + break;
|
| + default:
|
| + dprintf(INFO, "invalid graphics format\n");
|
| + DEBUG_ASSERT(0);
|
| + free(surface);
|
| + return NULL;
|
| + }
|
| +
|
| + if (ptr == NULL) {
|
| + // allocate a buffer
|
| + ptr = malloc(surface->len);
|
| + DEBUG_ASSERT(ptr);
|
| + surface->free_on_destroy = true;
|
| + }
|
| + surface->ptr = ptr;
|
| +
|
| + return surface;
|
| }
|
|
|
| /**
|
| @@ -463,25 +514,25 @@ gfx_surface *gfx_create_surface(void *ptr, uint width, uint height, uint stride,
|
| */
|
| gfx_surface *gfx_create_surface_from_display(struct display_info *info)
|
| {
|
| - gfx_surface* surface;
|
| - surface = gfx_create_surface(info->framebuffer, info->width, info->height, info->stride, info->format);
|
| + gfx_surface* surface;
|
| + surface = gfx_create_surface(info->framebuffer, info->width, info->height, info->stride, info->format);
|
|
|
| - surface->flush = info->flush;
|
| + surface->flush = info->flush;
|
|
|
| - return surface;
|
| + return surface;
|
| }
|
|
|
| /**
|
| * @brief Destroy a graphics surface and free all resources allocated to it.
|
| *
|
| * @param surface Surface to destroy. This pointer is no longer valid after
|
| - * this call.
|
| + * this call.
|
| */
|
| void gfx_surface_destroy(struct gfx_surface *surface)
|
| {
|
| - if (surface->free_on_destroy)
|
| - free(surface->ptr);
|
| - free(surface);
|
| + if (surface->free_on_destroy)
|
| + free(surface->ptr);
|
| + free(surface);
|
| }
|
|
|
| /**
|
| @@ -489,28 +540,28 @@ void gfx_surface_destroy(struct gfx_surface *surface)
|
| */
|
| void gfx_draw_pattern(void)
|
| {
|
| - struct display_info info;
|
| - if (display_get_info(&info) < 0)
|
| - return;
|
| + struct display_info info;
|
| + if (display_get_info(&info) < 0)
|
| + return;
|
|
|
| - gfx_surface *surface = gfx_create_surface_from_display(&info);
|
| + gfx_surface *surface = gfx_create_surface_from_display(&info);
|
|
|
| - uint x, y;
|
| - for (y = 0; y < surface->height; y++) {
|
| - for (x = 0; x < surface->width; x++) {
|
| - uint scaledx;
|
| - uint scaledy;
|
| + uint x, y;
|
| + for (y = 0; y < surface->height; y++) {
|
| + for (x = 0; x < surface->width; x++) {
|
| + uint scaledx;
|
| + uint scaledy;
|
|
|
| - scaledx = x * 256 / surface->width;
|
| - scaledy = y * 256 / surface->height;
|
| + scaledx = x * 256 / surface->width;
|
| + scaledy = y * 256 / surface->height;
|
|
|
| - gfx_putpixel(surface, x, y, (0xff << 24) | (scaledx * scaledy) << 16 | (scaledx >> 1) << 8 | scaledy >> 1);
|
| - }
|
| - }
|
| + gfx_putpixel(surface, x, y, (0xff << 24) | (scaledx * scaledy) << 16 | (scaledx >> 1) << 8 | scaledy >> 1);
|
| + }
|
| + }
|
|
|
| - gfx_flush(surface);
|
| + gfx_flush(surface);
|
|
|
| - gfx_surface_destroy(surface);
|
| + gfx_surface_destroy(surface);
|
| }
|
|
|
| /**
|
| @@ -518,22 +569,22 @@ void gfx_draw_pattern(void)
|
| */
|
| void gfx_draw_pattern_white(void)
|
| {
|
| - struct display_info info;
|
| - if (display_get_info(&info) < 0)
|
| - return;
|
| + struct display_info info;
|
| + if (display_get_info(&info) < 0)
|
| + return;
|
|
|
| - gfx_surface *surface = gfx_create_surface_from_display(&info);
|
| + gfx_surface *surface = gfx_create_surface_from_display(&info);
|
|
|
| - uint x, y;
|
| - for (y = 0; y < surface->height; y++) {
|
| - for (x = 0; x < surface->width; x++) {
|
| - gfx_putpixel(surface, x, y, 0xFFFFFFFF);
|
| - }
|
| - }
|
| + uint x, y;
|
| + for (y = 0; y < surface->height; y++) {
|
| + for (x = 0; x < surface->width; x++) {
|
| + gfx_putpixel(surface, x, y, 0xFFFFFFFF);
|
| + }
|
| + }
|
|
|
| - gfx_flush(surface);
|
| + gfx_flush(surface);
|
|
|
| - gfx_surface_destroy(surface);
|
| + gfx_surface_destroy(surface);
|
| }
|
|
|
| #if defined(WITH_LIB_CONSOLE)
|
| @@ -549,77 +600,77 @@ STATIC_COMMAND_END(gfx);
|
|
|
| static int gfx_draw_rgb_bars(gfx_surface *surface)
|
| {
|
| - uint x, y;
|
| -
|
| - uint step = surface->height*100 / 256;
|
| - uint color;
|
| -
|
| - for (y = 0; y < surface->height; y++) {
|
| - //R
|
| - for (x = 0; x < surface->width/3; x++) {
|
| - color = y*100 / step;
|
| - gfx_putpixel(surface, x, y, 0xff << 24 | color << 16);
|
| - }
|
| - //G
|
| - for (; x < 2*(surface->width/3); x++) {
|
| - color = y*100 / step;
|
| - gfx_putpixel(surface, x, y, 0xff << 24 | color << 8);
|
| - }
|
| - //B
|
| - for (; x < surface->width; x++) {
|
| - color = y*100 / step;
|
| - gfx_putpixel(surface, x, y, 0xff << 24 | color);
|
| - }
|
| - }
|
| -
|
| - return 0;
|
| + uint x, y;
|
| +
|
| + uint step = surface->height*100 / 256;
|
| + uint color;
|
| +
|
| + for (y = 0; y < surface->height; y++) {
|
| + //R
|
| + for (x = 0; x < surface->width/3; x++) {
|
| + color = y*100 / step;
|
| + gfx_putpixel(surface, x, y, 0xff << 24 | color << 16);
|
| + }
|
| + //G
|
| + for (; x < 2*(surface->width/3); x++) {
|
| + color = y*100 / step;
|
| + gfx_putpixel(surface, x, y, 0xff << 24 | color << 8);
|
| + }
|
| + //B
|
| + for (; x < surface->width; x++) {
|
| + color = y*100 / step;
|
| + gfx_putpixel(surface, x, y, 0xff << 24 | color);
|
| + }
|
| + }
|
| +
|
| + return 0;
|
| }
|
|
|
| static int cmd_gfx(int argc, const cmd_args *argv)
|
| {
|
| - if (argc < 2) {
|
| - printf("not enough arguments:\n");
|
| - printf("%s display_info : output information bout the current display\n", argv[0].str);
|
| - printf("%s rgb_bars : Fill frame buffer with rgb bars\n", argv[0].str);
|
| - printf("%s test_pattern : Fill frame with test pattern\n", argv[0].str);
|
| - printf("%s fill r g b : Fill frame buffer with RGB888 value and force update\n", argv[0].str);
|
| -
|
| - return -1;
|
| - }
|
| -
|
| - struct display_info info;
|
| - if (display_get_info(&info) < 0) {
|
| - printf("no display to draw on!\n");
|
| - return -1;
|
| - }
|
| -
|
| - gfx_surface *surface = gfx_create_surface_from_display(&info);
|
| -
|
| - if (!strcmp(argv[1].str, "display_info")) {
|
| - printf("display:\n");
|
| - printf("\tframebuffer %p\n", info.framebuffer);
|
| - printf("\twidth %u height %u stride %u\n", info.width, info.height, info.stride);
|
| - printf("\tformat %u\n", info.format);
|
| - } else if (!strcmp(argv[1].str, "rgb_bars")) {
|
| - gfx_draw_rgb_bars(surface);
|
| - } else if (!strcmp(argv[1].str, "test_pattern")) {
|
| - gfx_draw_pattern();
|
| - } else if (!strcmp(argv[1].str, "fill")) {
|
| - uint x, y;
|
| -
|
| - for (y = 0; y < surface->height; y++) {
|
| - for (x = 0; x < surface->width; x++) {
|
| - /* write pixel to frame buffer */
|
| - gfx_putpixel(surface, x, y, (0xff << 24) | (argv[2].i << 16) | (argv[3].i << 8) | argv[4].i);
|
| - }
|
| - }
|
| - }
|
| -
|
| - gfx_flush(surface);
|
| -
|
| - gfx_surface_destroy(surface);
|
| -
|
| - return 0;
|
| + if (argc < 2) {
|
| + printf("not enough arguments:\n");
|
| + printf("%s display_info : output information bout the current display\n", argv[0].str);
|
| + printf("%s rgb_bars : Fill frame buffer with rgb bars\n", argv[0].str);
|
| + printf("%s test_pattern : Fill frame with test pattern\n", argv[0].str);
|
| + printf("%s fill r g b : Fill frame buffer with RGB888 value and force update\n", argv[0].str);
|
| +
|
| + return -1;
|
| + }
|
| +
|
| + struct display_info info;
|
| + if (display_get_info(&info) < 0) {
|
| + printf("no display to draw on!\n");
|
| + return -1;
|
| + }
|
| +
|
| + gfx_surface *surface = gfx_create_surface_from_display(&info);
|
| +
|
| + if (!strcmp(argv[1].str, "display_info")) {
|
| + printf("display:\n");
|
| + printf("\tframebuffer %p\n", info.framebuffer);
|
| + printf("\twidth %u height %u stride %u\n", info.width, info.height, info.stride);
|
| + printf("\tformat %u\n", info.format);
|
| + } else if (!strcmp(argv[1].str, "rgb_bars")) {
|
| + gfx_draw_rgb_bars(surface);
|
| + } else if (!strcmp(argv[1].str, "test_pattern")) {
|
| + gfx_draw_pattern();
|
| + } else if (!strcmp(argv[1].str, "fill")) {
|
| + uint x, y;
|
| +
|
| + for (y = 0; y < surface->height; y++) {
|
| + for (x = 0; x < surface->width; x++) {
|
| + /* write pixel to frame buffer */
|
| + gfx_putpixel(surface, x, y, (0xff << 24) | (argv[2].i << 16) | (argv[3].i << 8) | argv[4].i);
|
| + }
|
| + }
|
| + }
|
| +
|
| + gfx_flush(surface);
|
| +
|
| + gfx_surface_destroy(surface);
|
| +
|
| + return 0;
|
| }
|
|
|
| #endif
|
|
|