2 * uterm - Linux User-Space Terminal drm2d module
4 * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@googlemail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files
8 * (the "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * DRM2D Video backend rendering functions
39 #include <xf86drmMode.h>
42 #include "uterm_drm_shared_internal.h"
43 #include "uterm_drm2d_internal.h"
44 #include "uterm_video.h"
45 #include "uterm_video_internal.h"
47 #define LOG_SUBSYSTEM "uterm_drm2d_render"
49 int uterm_drm2d_display_blit(struct uterm_display *disp,
50 const struct uterm_video_buffer *buf,
51 unsigned int x, unsigned int y)
55 unsigned int width, height;
57 struct uterm_drm2d_rb *rb;
58 struct uterm_drm2d_display *d2d = uterm_drm_display_get_data(disp);
60 if (!buf || buf->format != UTERM_FORMAT_XRGB32)
63 rb = &d2d->rb[d2d->current_rb ^ 1];
64 sw = uterm_drm_mode_get_width(disp->current_mode);
65 sh = uterm_drm_mode_get_height(disp->current_mode);
68 if (tmp < x || x >= sw)
75 tmp = y + buf->height;
76 if (tmp < y || y >= sh)
84 dst = &dst[y * rb->stride + x * 4];
88 memcpy(dst, src, 4 * width);
96 int uterm_drm2d_display_fake_blendv(struct uterm_display *disp,
97 const struct uterm_video_blend_req *req,
102 unsigned int width, height, i, j;
104 uint_fast32_t r, g, b, out;
105 struct uterm_drm2d_rb *rb;
106 struct uterm_drm2d_display *d2d = uterm_drm_display_get_data(disp);
111 rb = &d2d->rb[d2d->current_rb ^ 1];
112 sw = uterm_drm_mode_get_width(disp->current_mode);
113 sh = uterm_drm_mode_get_height(disp->current_mode);
115 for (j = 0; j < num; ++j, ++req) {
119 if (req->buf->format != UTERM_FORMAT_GREY)
122 tmp = req->x + req->buf->width;
123 if (tmp < req->x || req->x >= sw)
128 width = req->buf->width;
130 tmp = req->y + req->buf->height;
131 if (tmp < req->y || req->y >= sh)
134 height = sh - req->y;
136 height = req->buf->height;
139 dst = &dst[req->y * rb->stride + req->x * 4];
140 src = req->buf->data;
143 for (i = 0; i < width; ++i) {
144 /* Division by 255 (t /= 255) is done with:
146 * t = (t + (t >> 8)) >> 8
147 * This speeds up the computation by ~20% as the
148 * division is not needed. */
153 out = (r << 16) | (g << 8) | b;
154 } else if (src[i] == 255) {
158 out = (r << 16) | (g << 8) | b;
160 r = req->fr * src[i] +
161 req->br * (255 - src[i]);
163 r = (r + (r >> 8)) >> 8;
165 g = req->fg * src[i] +
166 req->bg * (255 - src[i]);
168 g = (g + (g >> 8)) >> 8;
170 b = req->fb * src[i] +
171 req->bb * (255 - src[i]);
173 b = (b + (b >> 8)) >> 8;
174 out = (r << 16) | (g << 8) | b;
177 ((uint32_t*)dst)[i] = out;
180 src += req->buf->stride;
187 int uterm_drm2d_display_fill(struct uterm_display *disp,
188 uint8_t r, uint8_t g, uint8_t b,
189 unsigned int x, unsigned int y,
190 unsigned int width, unsigned int height)
195 struct uterm_drm2d_rb *rb;
196 struct uterm_drm2d_display *d2d = uterm_drm_display_get_data(disp);
198 rb = &d2d->rb[d2d->current_rb ^ 1];
199 sw = uterm_drm_mode_get_width(disp->current_mode);
200 sh = uterm_drm_mode_get_height(disp->current_mode);
203 if (tmp < x || x >= sw)
208 if (tmp < y || y >= sh)
214 dst = &dst[y * rb->stride + x * 4];
217 for (i = 0; i < width; ++i)
218 ((uint32_t*)dst)[i] = (r << 16) | (g << 8) | b;