canvas item design advice



well, after a couple of days of experimentation, i think i've worked
out most of what i need to know about the canvas. i've come up with a
design for my "waveview" item, and i'd appreciate any input from Havoc
or any other canvas users on it.

the basic problem, as noted by others, is that because of the
(potential) amount of data to be represented by the waveview item,
its not possible to take the approach used in other canvas items: plan
on having the whole thing in memory, and just render the relevant
parts. 

we also have the detail that we need to scale the waveview widget
independently of the rest of the canvas - when we zoom in on a wave,
we don't want the text label or other items stacked above it to zoom
as well.

these two things make our life a little harder, since the only way to
find out what to draw is to wait and see what the render item method
gets as an argument. my design right now works something like this. 

the item's x,y location and height are set by the usual item
arguments. its width is defined by the total size of the data it is
given to display.

the item also has args to set its samples:pixel ratio, the left-most
sample number and also the zoom factor for amplitude.

in the render method, we look at the buf->rect argument to get the
canvas pixel coordinates of the area we are being asked to render.
we convert these to item-local coordinates using an affine. then we
look at the item's own sample:pixel ratio to compute the range of
samples we should redraw.

the item keeps its own cache that most of the time will contain data
for the visible part of the wave. in the render method, we ensure
first that the cache is properly filled. then we use the data from the
cache to draw the wave into the RGB buffer passed in as an argument.

so, for rendering we have:

	canvas: compute need to redraw canvas pixel bbox (cX1,cY1)(cX2,cY2), so
		   call render method for relevant items.

	item: convert bbox to item coordinates (iX1,iY1)(iX2,iY2)
	item: compute sample range (S1,S2) using iX1..iX2 and
	 	samples:pixel plus the left-most sample value.
	item: ensure cache contains computed data for samples S1..S2
	item: render wave into canvas buffer from cache

now, it occurs to me that a nice optimization would be to maintain not
just the data cache, but to prerender the section of the wave
represented by the cache into a private RGB buffer in the item. this
would then allow the actual render-method to simply copy RGB directly
into the canvas' buffer. does this make any sense? i started thinking
this when i noticed that there can be many (10-20) render calls to the
item in order to just get it redraw once.

now, this isn't inline with the design of the canvas, which seems to
aim at the items using the "update" method to do the "expensive"
part. the problem is that until the canvas tells us exactly which
pixel coords we should be drawing on, we have no way to know how wide
the visible section of the item is. therefore, we can't do anything
useful in the update method.

if there was a way for an item to say "how much of me is visible?"
things would get a lot easier, but i couldn't see any way to do this
from anywhere but the render method. it makes sense, since most items
don't care about such things.

any comments?

oh, and before anybody asks. using 600 CanvasItemLine's in a canvas is
so unbelievably slow as to be essentially useless.

--p




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]