[interfacekit] Re: Clipping - what to do, what to do?
- From: Adi Oanca <adioanca@xxxxxxxxx>
- To: interfacekit@xxxxxxxxxxxxx
- Date: Thu, 15 Apr 2004 23:55:23 +0300
Hi Gabe!
Gabe Yoder wrote:
Here is a problem for you all: How can we clip drawing instructions?
Are you talking about for the BDirectWindow, or app_server clipping in
general? Believe it or not, I am actually working on the regular app_server
clipping.
In general. instruction clipping for our app_server.
A filled ellipse really isn't that much harder since it is drawn as a series
of horizontal lines which can be clipped individually.
How do you clip a line with a region full of holes?
Working at the pixel level is definitely overworking the CPU. It is a
relatively simple procedure to transform figures into lines and then clip
each of the lines.
Please, explain us how are you planning to do low level clipping. This
is a complex thing and it must be as fast as possible.
The second proposal, and the one that I vote for, is by using a memory
region equal to BRegion::Bounds(). Every layer that needs a part of it
to be redrawn has a valid fUpdateReg region. This is the region in which,
this layer is allowed to draw - the clipping region. It is a part of the
visible region, and it is the minimum region required to be updated. When
an update is required(of forced: by calling ::Invalidate()) the following
happens:
* [fUpdateReg already is valid]
-> an _UPDATE_ message is sent to client side(BeApp)
-> just before calling BView::Draw() BWindows inserts a _WILL_DRAW_ to
be sent to the server.
-> ::Draw() gets called and all drawing is done.
-> when ::Draw() finishes, _END_DRAW_ is added to queued messages to be
sent, and a Sync() is made.
What do you say if, when we receive _WILL_DRAW_ we allocate(with malloc)
a memory region the size of fUpdateReg.Bounds()/8, and we set every bit to
1 if that (x,y) coordinate is in the region, 0 if not.
Please _do not_ start wondering "Why not use one byte per pixel to
achieve transparency (0-255)?" This _only_ concerns clipping, so leave
transparency aside!
When we want to paint a pixel, we can determine very quickly if it is
visible or not. Using this method, all drawing instructions(d.i.) found
inside BView::Draw() are executed, and when app_server receives
_END_DRAW_, the allocated memory region is deleted. OK, maybe not
deleted if there are still views that need to be updated, and we could use
realloc() for them.
I am not sure I am following you here. Are you talking about still checking
on a pixel by pixel basis for clipping, but precomputing which pixels are
visible to reduce CPU usage?
Yes, and you can still use fill_rect where you can.
Draw a line from 50,50 to 250,50 with holes at 100,50-125,50 and
175,50-200,50. check for every pixel if visible and then issue 3
draw_line() calls.
Memory used for this operation is not that much as you might have
thought. Every surface is managed by an app_server thread, and at a given
moment, it only draws for _one_ surface, and only one memory region is used
by all surfaces associated with that specific thread.
Now you would say: OK that was for the update mechanism, what if drawing
is made from outside ::Draw() of from another thread? IMO, the answer is
quite simple. Because BWindow thread must be locked, all drawing
instructions are serialized so all d.i. are from outside ::Draw(). When
the first d.i arrives at server, a memory region equal to
layer::_visibleRegion.Bounds() is allocated to help with the clipping
process. The second, third,... d.i. still use this memory region
assuming layer's visible region was not modified. If it was, the memory
region is freed and a new one will be created when the next d.i. arrives.
Finally, if no d.i. is received in half a second, it is deleted(freed).
[how???] There is a concern about Resize/Move methods inside ::Draw(), but
this a problem that is not of immediate priority.
Well, what do you think? Is this algorithm good enough? Other ideas?
Improvements?
I think we can avoid low-level clipping altogether by doing the appropriate
work at higher levels.
What do you mean? High-level clipping only determines the visible
regions which is in place and working. Low-level clipping is responsible
for "cutting" instructions to the visible area. But you already know
that, so what do you mean?
If you are intending this for general app_server
clipping, don't worry about it since, contrary to appearances, I am actually
working on it and have the hard issues worked out (I just need to get them
into the code). I hope to have all of the clipping code (except for text)
implemented and checked in within the next couple weeks.
Please tell us how are you going to do the low-level clipping!
Adi.
---------------------------------------------------------------
Trimite celor dragi cele mai frumoase felicitari de Paste prin
http://felicitari.acasa.ro
- Follow-Ups:
- [interfacekit] Re: Clipping - what to do, what to do?
- From: Gabe Yoder
- References:
- [interfacekit] Re: Clipping - what to do, what to do?
- From: Gabe Yoder
Other related posts:
- » [interfacekit] Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
- » [interfacekit] Re: Clipping - what to do, what to do?
Here is a problem for you all: How can we clip drawing instructions?
Are you talking about for the BDirectWindow, or app_server clipping in general? Believe it or not, I am actually working on the regular app_server clipping.
The second proposal, and the one that I vote for, is by using a memory region equal to BRegion::Bounds(). Every layer that needs a part of it to be redrawn has a valid fUpdateReg region. This is the region in which, this layer is allowed to draw - the clipping region. It is a part of the visible region, and it is the minimum region required to be updated. When an update is required(of forced: by calling ::Invalidate()) the following happens: * [fUpdateReg already is valid] -> an _UPDATE_ message is sent to client side(BeApp) -> just before calling BView::Draw() BWindows inserts a _WILL_DRAW_ to be sent to the server. -> ::Draw() gets called and all drawing is done. -> when ::Draw() finishes, _END_DRAW_ is added to queued messages to be sent, and a Sync() is made.
What do you say if, when we receive _WILL_DRAW_ we allocate(with malloc) a memory region the size of fUpdateReg.Bounds()/8, and we set every bit to 1 if that (x,y) coordinate is in the region, 0 if not. Please _do not_ start wondering "Why not use one byte per pixel to achieve transparency (0-255)?" This _only_ concerns clipping, so leave transparency aside! When we want to paint a pixel, we can determine very quickly if it is visible or not. Using this method, all drawing instructions(d.i.) found inside BView::Draw() are executed, and when app_server receives _END_DRAW_, the allocated memory region is deleted. OK, maybe not deleted if there are still views that need to be updated, and we could use realloc() for them.
I am not sure I am following you here. Are you talking about still checking on a pixel by pixel basis for clipping, but precomputing which pixels are visible to reduce CPU usage?
Memory used for this operation is not that much as you might have thought. Every surface is managed by an app_server thread, and at a given moment, it only draws for _one_ surface, and only one memory region is used by all surfaces associated with that specific thread. Now you would say: OK that was for the update mechanism, what if drawing is made from outside ::Draw() of from another thread? IMO, the answer is quite simple. Because BWindow thread must be locked, all drawing instructions are serialized so all d.i. are from outside ::Draw(). When the first d.i arrives at server, a memory region equal to layer::_visibleRegion.Bounds() is allocated to help with the clipping process. The second, third,... d.i. still use this memory region assuming layer's visible region was not modified. If it was, the memory region is freed and a new one will be created when the next d.i. arrives. Finally, if no d.i. is received in half a second, it is deleted(freed). [how???] There is a concern about Resize/Move methods inside ::Draw(), but this a problem that is not of immediate priority.
Well, what do you think? Is this algorithm good enough? Other ideas? Improvements?
I think we can avoid low-level clipping altogether by doing the appropriate work at higher levels.
- [interfacekit] Re: Clipping - what to do, what to do?
- From: Gabe Yoder
- [interfacekit] Re: Clipping - what to do, what to do?
- From: Gabe Yoder