<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 12 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EstiloCorreo17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 3.0cm 70.85pt 3.0cm;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=ES link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span lang=EN-US>Hi,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Two patches that improve performance in my case. <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> 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:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>diff -rup a/libweston/compositor-rdp.c b/libweston/compositor-rdp.c<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>--- a/libweston/compositor-</span>rdp.c           2018-02-22 11:35:14.000000000 +0100<o:p></o:p></p><p class=MsoNormal>+++ b/libweston/compositor-rdp.c        2018-02-22 11:37:20.312159332 +0100<o:p></o:p></p><p class=MsoNormal><span lang=EN-US>@@ -592,6 +592,8 @@ parse_gbm_format(const char *s, uint32_t<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               *gbm_format = default_value;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                else if (strcmp(s, "xrgb8888") == 0)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               *gbm_format = GBM_FORMAT_XRGB8888;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             else if (strcmp(s, "argb8888") == 0)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             *gbm_format = GBM_FORMAT_ARGB8888;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                else if (strcmp(s, "rgb565") == 0)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               *gbm_format = GBM_FORMAT_RGB565;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                else if (strcmp(s, "xrgb2101010") == 0)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Second, reading just the damaged pixels and y-flipping back the image:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>diff -rup a/libweston/compositor-rdp.c b/libweston/compositor-rdp.c<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>--- a/libweston/compositor-rdp.c           2018-02-20 16:04:20.000000000 +0100<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+++ b/libweston/compositor-rdp.c        2018-02-20 16:10:37.575768246 +0100<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>@@ -146,6 +146,12 @@ struct rdp_output {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                struct gbm_surface *gbm_surface;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                pixman_image_t *shadow_surface;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             int format;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             int stride;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             int height;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             uint32_t *tmpdata, *image;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             uint32_t tmpdata_size;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                struct wl_list peers;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> };<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>@@ -391,12 +397,25 @@ rdp_output_repaint(struct weston_output<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                if (pixman_region32_not_empty(damage)) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               if (!b->use_pixman) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                               /* TODO: Performance: Only read pixels that was actually repained by renderer->repaint_output. */<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>-                                             ec->renderer->read_pixels(output_base,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+/*                                        ec->renderer->read_pixels(output_base,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                                                              pixman_image_get_format(output->shadow_surface),<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                                                              pixman_image_get_data(output->shadow_surface),<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                                                              0, 0,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                                                              pixman_image_get_width(output->shadow_surface),<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>-                                                                             pixman_image_get_height(output->shadow_surface));<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                                                            pixman_image_get_height(output->shadow_surface));*/<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                            int                                                         i, nrects;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                            int                                                         x, y, width, height;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                            pixman_box32_t             *rect=pixman_region32_rectangles(damage, &nrects);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                            for (i=0; i<nrects; ++i) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                                            x = rect[i].x1;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                                            y = rect[i].y1;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                                            width = rect[i].x2 - x;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                                            height = rect[i].y2 - y;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                                            // It's y-flipped<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                                            ec->renderer->read_pixels(output_base, output->format, output->tmpdata, x, output->height-rect[i].y2, width, height);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                                            pixman_blt(output->tmpdata, output->image, -width, output->stride, 32, 32, 0, 1-height, x, y, width, height);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                            }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               wl_list_for_each(outputPeer, &output->peers, link) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>@@ -650,6 +669,30 @@ rdp_output_fini_egl(struct rdp_output *o<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> static int<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+rdp_get_image_size(struct rdp_output *output)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+{<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             uint32_t              image_size=pixman_image_get_width(output->shadow_surface)*pixman_image_get_height(output->shadow_surface)*sizeof(uint32_t);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+    <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             if (output->tmpdata_size < image_size) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             free(output->tmpdata);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             output->tmpdata = malloc(image_size);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             if (output->tmpdata == NULL) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                            output->tmpdata_size = 0;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                            errno = ENOMEM;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                                            return -1;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             output->tmpdata_size = image_size;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             output->stride = pixman_image_get_stride(output->shadow_surface) / sizeof(uint32_t);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             output->format = pixman_image_get_format(output->shadow_surface);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             output->height = pixman_image_get_height(output->shadow_surface);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             output->image = pixman_image_get_data(output->shadow_surface);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             return 0;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+}<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+static int<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> rdp_switch_mode(struct weston_output *output, struct weston_mode *target_mode)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                struct rdp_output *rdpOutput = container_of(output, struct rdp_output, base);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>@@ -696,6 +739,10 @@ rdp_switch_mode(struct weston_output *ou<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                pixman_image_unref(rdpOutput->shadow_surface);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                rdpOutput->shadow_surface = new_shadow_buffer;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             if (!b->use_pixman) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             if (rdp_get_image_size(rdpOutput) < 0)  return -1;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                wl_list_for_each(rdpPeer, &rdpOutput->peers, link) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               settings = rdpPeer->peer->settings;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               if (settings->DesktopWidth == (UINT32)target_mode->width &&<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>@@ -794,6 +841,10 @@ rdp_output_enable(struct weston_output *<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               return -1;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             if (!b->use_pixman) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+                             if (rdp_get_image_size(output) < 0)  return -1;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+             }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                loop = wl_display_get_event_loop(b->compositor->wl_display);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Raimun.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div></body></html>