[PATCH 3/3] rdp-backend.so: OpenGL hardware acceleration
Raimundo Sagarzazu
rsagarzazu at ulmapackaging.com
Fri Feb 23 15:08:00 UTC 2018
Hi,
Two patches that improve performance in my case.
First, supporting ARGB8888 gbm-format for the output allows a much better performance of the intelReadPixels function of the i965 driver of Mesa, which is my case:
diff -rup a/libweston/compositor-rdp.c b/libweston/compositor-rdp.c
--- a/libweston/compositor-rdp.c 2018-02-22 11:35:14.000000000 +0100
+++ b/libweston/compositor-rdp.c 2018-02-22 11:37:20.312159332 +0100
@@ -592,6 +592,8 @@ parse_gbm_format(const char *s, uint32_t
*gbm_format = default_value;
else if (strcmp(s, "xrgb8888") == 0)
*gbm_format = GBM_FORMAT_XRGB8888;
+ else if (strcmp(s, "argb8888") == 0)
+ *gbm_format = GBM_FORMAT_ARGB8888;
else if (strcmp(s, "rgb565") == 0)
*gbm_format = GBM_FORMAT_RGB565;
else if (strcmp(s, "xrgb2101010") == 0)
Second, reading just the damaged pixels and y-flipping back the image:
diff -rup a/libweston/compositor-rdp.c b/libweston/compositor-rdp.c
--- a/libweston/compositor-rdp.c 2018-02-20 16:04:20.000000000 +0100
+++ b/libweston/compositor-rdp.c 2018-02-20 16:10:37.575768246 +0100
@@ -146,6 +146,12 @@ struct rdp_output {
struct gbm_surface *gbm_surface;
pixman_image_t *shadow_surface;
+ int format;
+ int stride;
+ int height;
+ uint32_t *tmpdata, *image;
+ uint32_t tmpdata_size;
+
struct wl_list peers;
};
@@ -391,12 +397,25 @@ rdp_output_repaint(struct weston_output
if (pixman_region32_not_empty(damage)) {
if (!b->use_pixman) {
/* TODO: Performance: Only read pixels that was actually repained by renderer->repaint_output. */
- ec->renderer->read_pixels(output_base,
+/* ec->renderer->read_pixels(output_base,
pixman_image_get_format(output->shadow_surface),
pixman_image_get_data(output->shadow_surface),
0, 0,
pixman_image_get_width(output->shadow_surface),
- pixman_image_get_height(output->shadow_surface));
+ pixman_image_get_height(output->shadow_surface));*/
+ int i, nrects;
+ int x, y, width, height;
+ pixman_box32_t *rect=pixman_region32_rectangles(damage, &nrects);
+ for (i=0; i<nrects; ++i) {
+ x = rect[i].x1;
+ y = rect[i].y1;
+ width = rect[i].x2 - x;
+ height = rect[i].y2 - y;
+
+ // It's y-flipped
+ ec->renderer->read_pixels(output_base, output->format, output->tmpdata, x, output->height-rect[i].y2, width, height);
+ pixman_blt(output->tmpdata, output->image, -width, output->stride, 32, 32, 0, 1-height, x, y, width, height);
+ }
}
wl_list_for_each(outputPeer, &output->peers, link) {
@@ -650,6 +669,30 @@ rdp_output_fini_egl(struct rdp_output *o
}
static int
+rdp_get_image_size(struct rdp_output *output)
+{
+ uint32_t image_size=pixman_image_get_width(output->shadow_surface)*pixman_image_get_height(output->shadow_surface)*sizeof(uint32_t);
+
+ if (output->tmpdata_size < image_size) {
+ free(output->tmpdata);
+ output->tmpdata = malloc(image_size);
+ if (output->tmpdata == NULL) {
+ output->tmpdata_size = 0;
+ errno = ENOMEM;
+ return -1;
+ }
+
+ output->tmpdata_size = image_size;
+ output->stride = pixman_image_get_stride(output->shadow_surface) / sizeof(uint32_t);
+ output->format = pixman_image_get_format(output->shadow_surface);
+ output->height = pixman_image_get_height(output->shadow_surface);
+ output->image = pixman_image_get_data(output->shadow_surface);
+ }
+
+ return 0;
+}
+
+static int
rdp_switch_mode(struct weston_output *output, struct weston_mode *target_mode)
{
struct rdp_output *rdpOutput = container_of(output, struct rdp_output, base);
@@ -696,6 +739,10 @@ rdp_switch_mode(struct weston_output *ou
pixman_image_unref(rdpOutput->shadow_surface);
rdpOutput->shadow_surface = new_shadow_buffer;
+ if (!b->use_pixman) {
+ if (rdp_get_image_size(rdpOutput) < 0) return -1;
+ }
+
wl_list_for_each(rdpPeer, &rdpOutput->peers, link) {
settings = rdpPeer->peer->settings;
if (settings->DesktopWidth == (UINT32)target_mode->width &&
@@ -794,6 +841,10 @@ rdp_output_enable(struct weston_output *
return -1;
}
+ if (!b->use_pixman) {
+ if (rdp_get_image_size(output) < 0) return -1;
+ }
+
loop = wl_display_get_event_loop(b->compositor->wl_display);
output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output);
Raimun.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20180223/c21a7670/attachment-0001.html>
More information about the wayland-devel
mailing list