On Wed, 20 Feb 2013 17:10:29 +0000 Daniel Willmann <d.willm...@samsung.com>
said:

> Hello raster and other evas gurus,
> 
> last week we were confronted with memory usage peaks when rotating a
> canvas through elm_win_rotation_with_resize_set.
> 
> We didn't really understand what was going on and so we came up with a
> patch which seemed to fix the problem:
> 
> http://git.enlightenment.org/core/efl.git/commit/?id=139737247d563f53a064c7f4a025a89ed64c2983
> 
> We now know that this fix was just stupid and doesn't really work (or
> fix anything). After some more digging into the render code we have
> learned so far (please correct any place where we're wrong):

looks so - either way u have to allocate temporary rgba image buffers to render
data into BEFORE its rotated out to the real upload buffer...

> * Only changed regions get rendered

correct. evas figures out update regions and evas render walks thru these
asking the engine for each... and then renders to eac, then pushes it back
when done leaving it up to the engine to rotate it to the putput and upload to
display when done (it gets deferred until flush for less artifacts).

> * For each region a new region_for_update is allocated with
>   evas_software_xlib_outbuf_new_region_for_update()

correct.

> * The image returned by this function is updated with the image data
>   for the region

correct. by the render code.

> * evas_software_xlib_outbuf_push_updated_region() takes care of any
>   conversion (colorspace, rotation) that might be necessary

correct. it converts here and leaves in the shm buffer.

> * evas_software_xlib_outbuf_flush() sends the updated regions to X

correct.

> * After the rendering is done the stuff allocated through
>   *outbuf_new_region_for_update is freed again

correct. :)

> In the common case (rotation is 0, display depth is 32bit):
> * outbuf_new_region_for_update() allocates an
>   XShmImage and attaches its data directly to the evas_image data.

allocates and/or looks in its shm cache of existing shm segments, but correct.
this becomes a zero "copy/convert" path. it still is a copy up to display by x,
but within evas then no copies are done.

> * outbuf_push_updated_region() detects this case
>   ( -> if (data == (unsigned char *)src_data) ) and skips any convert
>   function

correct. :)

> In any other case (i.e. rotation is 90, 180 or 270):
> * outbuf_new_region_for_update() allocates data for
>   the evas_image. This is where the updates will get rendered into.
>   It also allocates an XShmImage which is what will be pushed to X in
>   outbuf_flush(). The dimensions of the XShmImage is transposed if
>   the rotation is 90 or 270.

correct.

> * outbuf_push_updated_region() selects the appropriate conversion
>   function and updates the XShmImage with the rotated image.

correct.

> What now happens if we rotate a large window is that the complete canvas
> needs to be redrawn - resulting in a large allocation of both the
> original image and the rotated XShmImage. After that initial large
> update we only have to update smaller regions so this is a one-time spike.

correct. though if u "scroll" a list filling most of the window.. it'll be
large regions too. at any point in time you need both the rendered data and its
converted/rotated output version (as at some point u have to do this
rotate/convert and both src and dest have to exist at once). evas just keeps
the whole "set" of them - and the whole set can in theory add up to a whole
window in size with both the unrotated/unconverted src and rotated/converted
output.

> The question is now how do we reduce the allocation peaks when rotating
> large windows? One possibility we see is breaking up the one large
> fullscreen update into smaller ones and rendering those sequentially.
> Does that make sense? Is there another/better way?

that leads to artifacts. it leads to SEEING the window update tile/region by
region. it also creates inefficiencies as you do the clipping and rendering of
many more smaller regions. you will pay a price in speed and artifacts. the set
is kept around and flushed in 1 go to minimize visible artifacts as x then
hopefully copies all the shm segments up in a very short timeframe as the
requests are temporally right next to eachother.

basically the answer is... "you can't". not without creating other problems.

let me give you an extreme example:

you COULD cut down the buffer memory needed to just 1 pixel... if you update
the whole canvas 1 pixel at a time. technically evas itself allows for this. it
is, in theory, possible to make an engine that works this way. this is actually
similar to postscript printers from what i know, but they keep just 1 scanline
around at a time. they literally just keep a "high resolution pixel buffer" of
scaline and then scan that out with a laser (for inkjet i assume they keep
maybe 8, 16 or 32 lines depending on the head size). in this extreme example
set you now can render with very little buffer memory needed, BUT.. you pay
price in performance as you basically re-render these small 1 pixel, 1 scanline
or "small set of 8, 16 or 32 scanlines" repeatedly with ALL your canvas
objects, each time walking all your objects and "clipping out the ones that
dont intersect the output". this adds cost/overhead and thus slows you down.
and... well.. adds artifacts as these regions get "copied over to the display"
over a much longer period of time thus you can "see" the frame redraw scanning
down the window (assuming now slow-ish rendering). for printers... this is just
fine as that is the nature of the beast. but for a live display... not so much.

-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
The Rasterman (Carsten Haitzler)    ras...@rasterman.com


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to