Re: clipmask of multiple rects in different angles

Theo Veenker <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
On 07/21/2016 01:22 AM, Enrico Weigelt, metux IT consult wrote:
> On 20.07.2016 23:46, Theo Veenker wrote:
>
>>> Maybe the damage tracking itself is slowing it down ... I'll now try
>>> to cache the matrices.
>
> Just implemented it - doesn't seem to have much effect.
>
> And still, on drm it's much slower than on xcb. The funny part here:
> it's not even deterministic - sometimes mouse movements (which in turn
> trigger two widgets to be repainted in my test program, as they show
> the positions and currently hover'ed widget) lags behind about 0.5..1s,
> but sometimes it's way faster - no idea what could cause that big
> indeterminism.

I suppose such a big lag can only happen if your system is too busy (drawing or something 
else). I use xlib, does that fall back on xcb these days?

>
>> Are you also saving the bounding boxes of your graphic objects?
>
> Just the rect (coordinates and angle) relative to the parent, but not
> the absolute positions.

Yeah that's what I mean.

>
> https://github.com/metux/twtk/blob/master/include/twtk/widget.h#L147
>
> I'm also caching the widget contents (including their subs's) as an
> cairo_pattern_t, rendered within an group. They get re-rendered when
> the widget gets a dirty flag - in that case the whole parent line also
> needs to be re-rendered.
>
> Haven't measured yet what's really eating up most of the time, whether
> it's the recursive rendering (within a group) or actual drawing onto
> screen. I'd suspect the latter, as xcb is magnitudes faster than xcb.

Using groups (as per cairo_{push|pop}_group) creates intermediate surfaces. I'd try to 
avoid that. The only situation I use cairo_{push|pop}_group() is when drawing a widget 
with alpha. (still dreaming about global alpha in cairo)

I only use surface patterns in case I need to paint something using an image as a fill or 
stroke pattern. I imagine that a simple case like drawing a rectangle is much faster with 
a color pattern then with a surface pattern. Maybe that's related to your problem?

>
> By the way: when exactly is the clipping applied (and clipped-out stuff
> dropped out) ? Is that device specific or generic ?

That should be in the docs somewhere I guess, I'm no cairo expert. I belive clipping is 
the last stage.

>
>> I suppose it is not efficient if you need recalculate the bbox (by drawing
>> onto a dummy surface) before each redraw.
>
> Actually, I'm not recalculating it by drawing. The (relative) rects
> and the matrices are stored within the widgets. For damage tracking,
> rect and matrix are passed upwards and transformed with the parent
> coordinates.

Sounds good too me.

>
> As I'm not using angles != 0 right now, I maybe could add a bypass that
> just adds positions w/o using matrices.
>
>> What also helps *a lot* is drawing only once every vertical retrace.
>
> hmm, in general, I'm always redrawing if an event caused the screen to
> become dirty (passed up the handler hierarchy as an result code flag)
> and on xcb when the server requests it.
>
> In any case, when a widget is dirty, it's parent is also marked dirty,
> so finally the root is always repainted when something changes. But in
> parallel the affected (absolute) rects are recorded and used as clip
> when the root's pattern is drawn onto screen.
>
> Theoretically, the clip should limit the actual draw operations on the
> underlying framebuffer to the dirty regions.

Maybe you could count per widget howmany times per second is gets redrawn. Ideally it 
should not be more than once per video frame.

>
>> In my setup all graphic objects have a current and a new state (this means
>> every attribute such as x or y, color etc. is doubled). Let's say we're
>> not using a back-buffer then a graphics expose will cause a redraw using
>> the current state of the objects. And only at vertical retrace the
>> drawing is updated to refrect the new state. In this aproach you can
>> change the state of objects as often as you want with nearly zero CPU
>> load. Only at retrace when changes are drawn you will have load. So if
>> you're the only process drawing you'll have almost a full video frame to
>> do the job; that should be plenty of time.
>
> hmm, how could an actual implementation look like ?
>
> Have a different thread sleeping on some lock, which is released as soon
> as there's something to repaint and then sleep until vsync event occours
> (sync read() on drm fd ...) ?

 From the top of my head (haven't worked on it for some time): I have a thread monitoring 
DRM vblank. This gives me the refresh interval and a way to tell when a the N'th video 
frame will start. From my main thread a let a timer fire at every vretrace (or even a 
little earlier). At each timer expiration I let the graphics stuff update itself. 
Something along that line.

>
>> Personally I don't use the cairo region type. I just create my own array
>> of integer rectangles (do floor on x, and y; ceil on w and h) from which
>> the clip mask is then created.
>
> Does your implementation also allow arbitrary angles ?
> For now, my test program doesn't use angles yet, but I wanna support it
> in the future. I'm also planning to support widget zooming (in that way
> that the widget class itself doesn't have to care about it - everything
> handled by the engine).

Arbitrary angles shouldn't be a problem (as it just causes bigger bounding boxes, that's 
all), but I don't allow them for gui elements. I make a distiction between gui elements 
which are always layed out othogonally and graphic shapes (which can appear in any angle) 
on a drawing canvas. Drawing things on a scaled window of course needs clipping to be 
adjusted too. In my case I sometimes need to show a smaller version of a full-screen 
window; works well.

Theo

-- 
cairo mailing list
[email protected]
https://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.