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