[haiku-appserver] Re: Going "back" to partially hardware accelerated drawing

  • From: "Stephan Assmus" <superstippi@xxxxxx>
  • To: haiku-appserver@xxxxxxxxxxxxx
  • Date: Wed, 20 Apr 2005 18:52:39 +0200 CEST

Hi Axel,

> > I don't know hard facts about how the drawing implementation 
> > changed 
> > in 
> > Dano, but I would think it simply syncs drawing commands with the 
> > refresh, as I can still observe "flickering" in some occasions. The 
> 
> I don't think it does that, as "tearing" is still visible when you're 
> moving around windows - and that shouldn't be visible if drawing 
> occurs 
> during the vertical blank.

I know what you mean, but maybe it's just that the syncing doesn't work 
perfectly?

> Since transparency is very slow in Dano and flickers a lot, 
> especially 
> when crossing window borders, I think they might have a per window 
> back 
> buffer. That would also reduce the update work when moving windows 
> around.

Possible. It would also mean alot of overhead when resizing windows 
though. And it is a "waste" of RAM, which I'm skeptical about, it being 
Be we're talking about and all. I would assume, that they 
"dramatically" increased overall drawing speed and are syncing the 
execution of the commands somewhat to the retrace. Well, yT would 
know... :-)

> > double buffering in our current implementation also has nothing to 
> > do 
> > with preventing flickering. That's two different things actually.
> 
> No, not really I think: I call it flickering when you ie. have to 
> clear 
> the background first, and then draw the text on top of it - that's 
> what 
> double buffering removes entirely. 
> When that change is copied back into the frame buffer at once, there 
> is 
> no flickering - what you might see is some "tearing" when the refresh 
> happens in the copied region.

I agree completely, but this is exactly the problem, the changes are 
not copied back in one go, but in two. That's because the drawing 
engine doesn't know if another change will be comming. I have put some 
work into "decoupling" the drawing from the frame buffer transfers 
(currently disabled again), which raises the chance of transmitting two 
or more changes in one go, but it is no definite solution to the 
problem. If somehow the drawing engine could be told to suspend updates 
in the front buffer in respond to BWindow::En-/DisableUpdates() or 
BWindow::Open-/CloseViewTransaction(), maybe this problem could be 
solved. However, as of now, the drawing engine has no idea, what area 
(including clipping) belongs to a certain window. I think because of 
the asynchronous nature of app_server (the window might draw and move 
at the same time), this problem becomes pretty tough to solve. Not for 
R1 at least.
One strategy for reducing flickering is making sure that the background 
clearing and text drawing are done very fast after another. For 
example, I usually SetViewColor(B_TRANSPARENT_COLOR), which disables 
app_server's automatic background clearing, and then do that myself all 
within Draw(), if I know I have to draw text on top of the background. 
I do this for the only reason that the text drawing happens much sooner 
after the background clearing in this setup, and it avoids flickering 
pretty effectively on R5 (just because it's too quick for the monitor 
to show the background without the text). Another strategy is to draw 
every pixel only once, which is - for example - an option for 
BSlider::Draw() (I think). At least I'm doing that for the sliders in 
WonderBrush, and I can see no flickering there.

> > I'm not against a double buffered screen update, but I would do it 
> > differently from how it's done right now - in order to be able to 
> > use 
> > hardware acceleration. This means the back buffer would have to be 
> > in 
> > graphics mem. It would mean no change to an existing single 
> > buffered 
> > design, only that there is an additional front buffer in the gfx 
> > mem, 
> > which is updated during the screen retrace. That would avoid 
> > flickering 
> > to some extend.
> 
> Yes, but that would make B_OP_OVER and friends again very expensive 
> and 
> slow, so that we might not want to do it this way (we'll see, I 
> guess).

Maybe you're right, but I think you're overestimating the performance 
hit. Right now, there is a huge perfomance hit by copying way too many 
pixels when drawing diagonal lines (the rect enclosing the line will be 
copied). The same goes for text. Not only the pixels having been 
touched will be copied, but all the pixels arround the actual glyphs as 
well. It could be avoided by drawing in the back and front buffer at 
the same time. Ie, calculate the blending from the backbuffer pixel, 
and draw the result into the back and front buffer at the same time. 
That would mean many changes to the drawing engine though. Maybe it is 
worth investigating.

The whole point of the hardware acceleration is to have a very fast 
path for 99% of the drawing that has to be done. As per the nature of 
most of the other drawing modes, they cannot be hardware accelerated on 
R5 either, and look how fast the normal drawing feels there. So this 
whole discussion boils down to weighting advantages and drawbacks 
against each other. I have come to the conclusion, that using hardware 
acclerated drawing for the most frequently used drawing functions is a 
"must have". Just imaging your browser window fullscreen at 1920x1200 
and then scrolling in software. This will be totally disappointing. 
Even if it would be somewhat smooth (very unlikely), it would be the 
CPU doing the work.

In a couple of years (when Haiku will be ready... hehe I couldn't 
resist), we will all have PCIe with real native PCIe GPUs and reading 
from framebuffer for anti-aliasing should be fast enough... :-P

> I meant drag&drop transparency a.k.a. alpha blending, ie. when moving 
> a 
> couple of icons around in Tracker. It's not as common as drawing text 
> with B_OP_COPY, but it happens very often nonetheless, and should 
> therefore be fast.
> That's actually one of the things that feels better in R5 as in Dano; 
> but of course, I'd like to have both good things on Haiku, double 
> buffering and fast alpha blending.

It is definitely a problem, and it would have been solved the easy way 
with the double buffering I had. It was in fact already done for the 
cursor, and the "cursor"
could have been any bitmap of any size. Ideally, it would have been 
alpha blended _during_ the back to front transfer (in my lame 
implementation, it was blended after the transfer...).
I will have to think about this, but this whole idea of scrolling the 
entire screen at 1920x1200 really scares the crap out of me, and I 
really think we will have to do this in hardware.

Best regards,
-Stephan


Other related posts: