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

  • From: "Axel Dörfler" <axeld@xxxxxxxxxxxxxxxx>
  • To: haiku-appserver@xxxxxxxxxxxxx
  • Date: Thu, 21 Apr 2005 01:19:14 +0200 CEST

Hi Stephan,

"Stephan Assmus" <superstippi@xxxxxx> wrote:
> > > 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?

I don't think so, but I can't proof it :-)
In fact when you're scrolling or moving a window, you'll see that the 
tearing is moving over the screen from back to top - it's highly 
unlikely that this would happen if the drawing itself is synchronized 
with the screen's refresh rate.

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

It's not really a waste of RAM, but it would definitely require quite 
some changes.
And I really don't know if it is worth it either.

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

I think you're doing this at the wrong end. The views itself now 
exactly where they are, and it would be simple for them to create a 
drawing context that can do intelligent double buffering. The drawing 
engine itself is the dumb end - it shouldn't be concerned with these 
things at all.

IIRC the accelerant engine even has an interface for that: every change 
gets a token, and you can sync to them. Only then the rendering 
pipeline will be guaranteed to be empty. IOW that looks like a good 
time to do the back-to-front buffer copy.

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

I think this would be a serious design problem, even for R1.

> 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 

Sure, that's working more or less good, but that's not what we should 
ask for.

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

Sure, that pretty much removes any flickering (besides tearing of 
course).

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

Well, you showed me the 10 times slow down, I didn't know about that 
before :-)

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

Sure, scrolling in particular would be better moved to the graphics 
card, although I don't see a big problem with it, anyway (even for the 
back buffer case), since you should only update the rectangles that you 
change.
That of course requires the "only draw from the looper's thread" design 
we already have.

> 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

Okay, we'll see about that :-)

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

Definitely. But I hope this is not the last call anyway :-)
We should get the thing working first, and if we're not happy with the 
results, we can still rework the details (or more). I don't want to 
slow you down, I want to see the results :-)

Bye,
   Axel.


Other related posts: