[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