int uterm_fbdev_display_blit(struct uterm_display *disp,
const struct uterm_video_buffer *buf,
unsigned int x, unsigned int y);
-int uterm_fbdev_display_blend(struct uterm_display *disp,
- const struct uterm_video_buffer *buf,
- unsigned int x, unsigned int y,
- uint8_t fr, uint8_t fg, uint8_t fb,
- uint8_t br, uint8_t bg, uint8_t bb);
int uterm_fbdev_display_fake_blendv(struct uterm_display *disp,
const struct uterm_video_blend_req *req,
size_t num);
return 0;
}
-int uterm_fbdev_display_blend(struct uterm_display *disp,
- const struct uterm_video_buffer *buf,
- unsigned int x, unsigned int y,
- uint8_t fr, uint8_t fg, uint8_t fb,
- uint8_t br, uint8_t bg, uint8_t bb)
-{
- unsigned int tmp;
- uint8_t *dst, *src;
- unsigned int width, height, i;
- unsigned int r, g, b;
- uint32_t val;
- struct fbdev_display *fbdev = disp->data;
-
- if (!disp->video || !(disp->flags & DISPLAY_ONLINE))
- return -EINVAL;
- if (!buf || !video_is_awake(disp->video))
- return -EINVAL;
- if (buf->format != UTERM_FORMAT_GREY)
- return -EINVAL;
-
- tmp = x + buf->width;
- if (tmp < x || x >= fbdev->xres)
- return -EINVAL;
- if (tmp > fbdev->xres)
- width = fbdev->xres - x;
- else
- width = buf->width;
-
- tmp = y + buf->height;
- if (tmp < y || y >= fbdev->yres)
- return -EINVAL;
- if (tmp > fbdev->yres)
- height = fbdev->yres - y;
- else
- height = buf->height;
-
- if (!(disp->flags & DISPLAY_DBUF) || fbdev->bufid)
- dst = fbdev->map;
- else
- dst = &fbdev->map[fbdev->yres * fbdev->stride];
- dst = &dst[y * fbdev->stride + x * fbdev->Bpp];
- src = buf->data;
-
- /* Division by 256 instead of 255 increases
- * speed by like 20% on slower machines.
- * Downside is, full white is 254/254/254
- * instead of 255/255/255. */
- if (fbdev->xrgb32) {
- while (height--) {
- for (i = 0; i < width; ++i) {
- if (src[i] == 0) {
- r = br;
- g = bg;
- b = bb;
- } else if (src[i] == 255) {
- r = fr;
- g = fg;
- b = fb;
- } else {
- r = fr * src[i] +
- br * (255 - src[i]);
- r /= 256;
- g = fg * src[i] +
- bg * (255 - src[i]);
- g /= 256;
- b = fb * src[i] +
- bb * (255 - src[i]);
- b /= 256;
- }
- val = (r << 16) | (g << 8) | b;
- ((uint32_t*)dst)[i] = val;
- }
- dst += fbdev->stride;
- src += buf->stride;
- }
- } else if (fbdev->Bpp == 2) {
- while (height--) {
- for (i = 0; i < width; ++i) {
- if (src[i] == 0) {
- r = br;
- g = bg;
- b = bb;
- } else if (src[i] == 255) {
- r = fr;
- g = fg;
- b = fb;
- } else {
- r = fr * src[i] +
- br * (255 - src[i]);
- r /= 256;
- g = fg * src[i] +
- bg * (255 - src[i]);
- g /= 256;
- b = fb * src[i] +
- bb * (255 - src[i]);
- b /= 256;
- }
- val = (r << 16) | (g << 8) | b;
- ((uint16_t*)dst)[i] = xrgb32_to_device(disp,
- val);
- }
- dst += fbdev->stride;
- src += buf->stride;
- }
- } else if (fbdev->Bpp == 4) {
- while (height--) {
- for (i = 0; i < width; ++i) {
- if (src[i] == 0) {
- r = br;
- g = bg;
- b = bb;
- } else if (src[i] == 255) {
- r = fr;
- g = fg;
- b = fb;
- } else {
- r = fr * src[i] +
- br * (255 - src[i]);
- r /= 256;
- g = fg * src[i] +
- bg * (255 - src[i]);
- g /= 256;
- b = fb * src[i] +
- bb * (255 - src[i]);
- b /= 256;
- }
- val = (r << 16) | (g << 8) | b;
- ((uint32_t*)dst)[i] = xrgb32_to_device(disp,
- val);
- }
- dst += fbdev->stride;
- src += buf->stride;
- }
- } else {
- log_warning("invalid Bpp");
- }
-
- return 0;
-}
-
int uterm_fbdev_display_fake_blendv(struct uterm_display *disp,
const struct uterm_video_blend_req *req,
size_t num)
.use = NULL,
.swap = display_swap,
.blit = uterm_fbdev_display_blit,
- .blend = uterm_fbdev_display_blend,
- .blendv = uterm_fbdev_display_fake_blendv,
.fake_blendv = uterm_fbdev_display_fake_blendv,
.fill = uterm_fbdev_display_fill,
};
.use = display_use,
.swap = display_swap,
.blit = display_blit,
- .blend = display_blend,
- .blendv = display_fake_blendv,
.fake_blendv = display_fake_blendv,
.fill = display_fill,
};
return 0;
}
-static int display_blend(struct uterm_display *disp,
- const struct uterm_video_buffer *buf,
- unsigned int x, unsigned int y,
- uint8_t fr, uint8_t fg, uint8_t fb,
- uint8_t br, uint8_t bg, uint8_t bb)
-{
- unsigned int tmp;
- uint8_t *dst, *src;
- struct dumb_rb *rb;
- unsigned int width, height, i;
- unsigned int sw, sh;
- unsigned int r, g, b;
-
- if (!disp->video || !display_is_online(disp))
- return -EINVAL;
- if (!buf || !video_is_awake(disp->video))
- return -EINVAL;
-
- rb = &disp->dumb.rb[disp->dumb.current_rb ^ 1];
- sw = disp->current_mode->dumb.info.hdisplay;
- sh = disp->current_mode->dumb.info.vdisplay;
-
- tmp = x + buf->width;
- if (tmp < x || x >= sw)
- return -EINVAL;
- if (tmp > sw)
- width = sw - x;
- else
- width = buf->width;
-
- tmp = y + buf->height;
- if (tmp < y || y >= sh)
- return -EINVAL;
- if (tmp > sh)
- height = sh - y;
- else
- height = buf->height;
-
- dst = rb->map;
- dst = &dst[y * rb->stride + x * 4];
- src = buf->data;
-
- if (buf->format == UTERM_FORMAT_GREY) {
- while (height--) {
- for (i = 0; i < width; ++i) {
- /* Division by 256 instead of 255 increases
- * speed by like 20% on slower machines.
- * Downside is, full white is 254/254/254
- * instead of 255/255/255. */
- if (src[i] == 0) {
- r = br;
- g = bg;
- b = bb;
- } else if (src[i] == 255) {
- r = fr;
- g = fg;
- b = fb;
- } else {
- r = fr * src[i] +
- br * (255 - src[i]);
- r /= 256;
- g = fg * src[i] +
- bg * (255 - src[i]);
- g /= 256;
- b = fb * src[i] +
- bb * (255 - src[i]);
- b /= 256;
- }
- ((uint32_t*)dst)[i] = (r << 16) | (g << 8) | b;
- }
- dst += rb->stride;
- src += buf->stride;
- }
- } else {
- log_warning("using unsupported buffer format for blending");
- }
-
- return 0;
-}
-
static int display_fake_blendv(struct uterm_display *disp,
const struct uterm_video_blend_req *req,
size_t num)
.use = NULL,
.swap = display_swap,
.blit = display_blit,
- .blend = display_blend,
- .blendv = display_fake_blendv,
.fake_blendv = display_fake_blendv,
.fill = display_fill,
};
int (*blit) (struct uterm_display *disp,
const struct uterm_video_buffer *buf,
unsigned int x, unsigned int y);
- int (*blend) (struct uterm_display *disp,
- const struct uterm_video_buffer *buf,
- unsigned int x, unsigned int y,
- uint8_t fr, uint8_t fg, uint8_t fb,
- uint8_t br, uint8_t bg, uint8_t bb);
- int (*blendv) (struct uterm_display *disp,
- const struct uterm_video_blend_req *req, size_t num);
int (*fake_blendv) (struct uterm_display *disp,
const struct uterm_video_blend_req *req,
size_t num);