[interfacekit] Re: Clipping - what to do, what to do?

>> 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.

>It's really simple for rectangular areas, but how else would you handle 
>arbitrary shapes? With rectangular areas and transparency?
>
>Bye,
>   Axel.

Treat everthing as a rectangular area. What is a rounded window corner? It's a 
square corner with
a alpha-transparent paint to soften the corner.

It's then up to the window compositing algorithm to lay the windows on top of 
each other so the
stuff under the corner shows through.

Then comes the hack, which is for the app_server to pass mouse clicks on fully 
transparent areas
on to a lower window. One pixel check per click is low overhead. [but what 
about MOUSE_MOVED?]

I had done some experimental code 3 years ago for a general virtual frame 
buffer after I had
ported Microwindows (never released). I was going to give it to Darkwyrm but he 
seemed to be
methodical about designing first then implementing, so I didn't want to blinker 
his exploration of
the solution space.

There are two versions, one runs in a BWindow,  the other a full-screen 
BDirectWindow using the
real frame-buffer. You should be running in 16 or 32-bit color, iirc.

[I'm having trouble uploading (too many hops?) and Freelists will remove the 
attachment so I've
cc'd Axel, Adi, Gabe, and DarkWyrm via @users.sourceforge.net. E-mail me 
pahtz@xxxxxxxx if you
want it also.]

cOSApplication.cpp line 34 can be modified to compile in a different DemoXX 
function. Demo08 is
the nifty alpha-translucent windows demo.

RFrameBuffer.cpp has some boiler-plate RDirectWindow code. It drives the 
referesh rate, not
necessarily what you want for OBOS, but it checks for dirty areas and then 
copies from the
offscreen buffer to the frame-buffer.  In the BWindow version it calls 
Invalidate() on the
onscreen BBitmap. This means the refresh rate is independent of how often the 
client invalidates.
It can reduce flicker and increase efficiency by grouping frame-buffer writes. 
It does chew CPU by
polling the dirty flag, but makes things easier to simulate by not having to 
synchronize with the
client.

RFBView.cpp is nothing important. It was for passing BeOS input events to the 
hosted environment
(Microwindows, JavaScript Engine).

RGraphicsServer.cpp has your basic drawing instructions clipped to the 
framebuffer size. Of note
is CopyArea(). The idea is that when you move a window, you don't want to call 
the client to
redraw the window. You can just copy the bits off the screen-buffer and move 
them to another part
of  the screen-buffer. Depending on which direction you are moving the area, 
you have to vary the
algorithm so as not to overwrite pixels your trying to copy from.

RWindowServer.cpp has a light-weight server-side window implementation 
RwsWindow, it just stores
the coordinates, a dirty region list, a alpha transparent region list, and some 
stuff to form a
linked list of windows to represent Z-order. The first window created is 
treated as the desktop.

It's a hack as it never asks the client window to draw. Instead it simulates 
drawing by
FillRect()'ing any dirty region with BeOS yellow. So you can recognize it in 
the code, there are
two places like this:

//update
if (w != ws->mDesktop)
        gs->FillRect(rect.left, rect.top, rect.right, rect.bottom, RALPHACOLOR 
+ debug_tint, 127);
else
        gs->FillRect(rect.left, rect.top, rect.right, rect.bottom, 
RDESKTOPCOLOR + debug_tint);

These would be replaced with calls to the client to draw their stuff. Currently 
you create 
differentiating window features by altering the size, designate regions of the 
window as
alpha-translucent, and moving the windows.

A plausible algorithm for window composition with alpha-blended windows is thus 
presented.

AFTERTHOUGHTS

You don't want to call the client to draw inside your compositing algorithm 
because the client
could lock up the whole loop. But, you need the client data to correctly 
compose alpha-blended
areas. So instead, you should buffer each Window's contents in an offscreen 
bitmap. The advantage
is you can move windows, put windows infront/behind/off-screen, reveal, etc. 
all without sending
expose/invalidate/redraw events to the client - and composition can be done 
with hardware
acceleration. This can be seen in DirectFB.

Another note, you need BEGIN_UPDATE and END_UPDATE appserver messages for 
BView::Draw() if you
want to be able to use buffered windows (different from buffering the screen). 
Because without
END_UPDATE the appserver won't know when to blit the invalidated window region. 
Note that Draw()
is suppose to paint every pixel in the region it is a given.

In the BeOS API you're not suppose to call BView::Draw() yourself, but call 
Invalidate() instead.
Furthermore, you shouldn't call drawing instructions outside Draw() as Pulse 
might do. Doing
either breaks (simple) offscreen buffering, i.e., the updates won't been seen.

Cheers,
Paul.


__________________________________
Do you Yahoo!?
Yahoo! Tax Center - File online by April 15th
http://taxes.yahoo.com/filing.html

Other related posts: