<div dir="ltr">Hi<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 26, 2015 at 2:17 PM, Christophe Fergeau <span dir="ltr"><<a href="mailto:cfergeau@redhat.com" target="_blank">cfergeau@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I'm still a bit worried whether we are missing a more generic fix here<br>
:-/ the non-LE surfaces come from canvas_get_as_surface /<br>
canvas_put_image I guess?<span class=""><font color="#888888"><br>
</font></span></blockquote></div><br></div><div class="gmail_extra">So I was looking into this, and it turns out, that with my PPC fixes, I actually call the<br>surface_create function twice. Once from the canvas_get_(quic|lz|lz4...) wrapper functions<br>for the decoders, and once again in the canvas_get_image_internal() function, which handles<br>what type of compression to use, and whether to use the alpha channel.<br><br></div><div class="gmail_extra">What hapenns is basically this:<br>1. canvas_get_image_internal() decides which compression to use.<br></div><div class="gmail_extra">2. One of the wrapper functions decides what kind of image to use (ARGB, XRGB, 16bit etc...).<br></div><div class="gmail_extra">3. Inside the wrapper function, we create a BE order surface (FE PIXMAN_b8g8r8a8).<br></div><div class="gmail_extra">4. Just before returning from canvas_get_image_internal(), we check if the new surfaces format<br> matches the format we actually want.<br></div><div class="gmail_extra">5. The "wanted_format" is in LE, so it obviously doesn't match our BE "surface_format".<br></div><div class="gmail_extra">6. Because of this, a new LE order surface is created.<br></div><div class="gmail_extra">7. Then we copy the data from BE surface to LE surface using pixman_image_composite32(),<br> which byteswaps the data automatically using the surface's format.<br clear="all"></div><div class="gmail_extra"><br></div><div class="gmail_extra">The code that handles the conversion looks like this:<br>(spice-common, canvas_base.c, canvas_get_image_internal())<br><br> if (!saved_want_original) {<br> wanted_format = canvas_get_target_format(canvas,<br> surface_format == PIXMAN_a8r8g8b8);<br><br> if (surface_format != wanted_format) {<br> converted = surface_create(<br> wanted_format,<br> pixman_image_get_width(surface),<br> pixman_image_get_height(surface),<br> TRUE);<br> pixman_image_composite32 (PIXMAN_OP_SRC,<br> surface, NULL, converted,<br> 0, 0,<br> 0, 0,<br> 0, 0,<br> pixman_image_get_width(surface),<br> pixman_image_get_height(surface));<br> pixman_image_unref (surface);<br> surface = converted;<br> }<br> }<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Proper way to fix this would be to rewrite the decoders for every image compression, but I think<br>this is fine for the few cases someone actually needs to use a BE machine.<br><br></div><div class="gmail_extra">We have 2 possible ways to fix this:<br></div>1. Reuse this part of code, and just convert EVERY time on BE machine<br> (instead of checking for saved_want_original)<br>2. Create a new function, that converts the surface before this part of code.<br> (This could end up with surface_create being called 3 times)<br><div class="gmail_extra">-- <br><div class="gmail_signature">Lukas Venhoda</div>
</div></div>