[haiku-appserver] Re: update code.

  • From: Adi Oanca <adioanca@xxxxxxxxxxxxxx>
  • To: haiku-appserver@xxxxxxxxxxxxx
  • Date: Fri, 01 Apr 2005 14:20:58 +0300

Hi Stephan,

Stephan Assmus wrote:
> Read in BeBook BView::CopyBits().
> 
> MyView::ScrollBy(float x, float y)
> {
>       BRect bounds = (Bounds());
>       CopyBits(bounds, bounds.OffsetBySelf(x, y));
> }
> 
> Two things happen here. The BViews contents are shifted by x and y. BUT 
> what happens with the area, that was previously no within Bounds()? For 
> this area, the app_server triggers an invalidation and therefor Draw() 
> to be called (all automatically).

        Of course.
        As you might have already noticed there isn't support for that, yet.
        Not even BView::Bounds() is not working. :-P (Tried a quick fix, but
that didn't work)

> What I'm saying in my above paragraph 
> is, that DisplayDriver cannot do this job for you.

        Yes, I know/understand, app_server must copy up/down what remains
visible and then issue an update request for the region becoming visible.

> is something you cannot do anyways. I'm further saying that the 
> accelerant hook does not do the clipping, but it can however be done in 
> DisplayDriver before passing it on to the accelerant.
> 
> 
> 
>>>That is something the 
>>>DisplayDriver cannot do for app_server.
>>>Same goes for the other function with blitting all those regions. 
>>>If it 
>>>can be assumed by the DisplayDriver, that the regions are 
>>>preprocessed, 
>>>so that they a) don't overlap (so that the same area doesn't get 
>>>moved 
>>>twice or more), and b) that the destination rects don't overlap for 
>>>the 
>>>different offsets that they may have, this function could be 
>>>accelerated 3 times. If those requirements cannot be guaranteed, 
>>>then 
>>>indeed, your implementation is the fail save one. However, it would 
>>>draw areas on screen, which would have to be redrawn by the views 
>>>anyhow. Maybe I find some time to illustrate the problem. I 
>>>understand 
>>>perfectly well what you guys had in mind when designing this 
>>>function, 
>>>however, I'm saying it is not going to visually work without some 
>>>additional precautions.
>>
>>      :-) I did not understood much from the above paragraph, sorry.
>>
>>      What I did understood is that you complain this method CCR()
>>should not be inside DD because of clipping operations(?)
> 
> 
> No, read above. It can perform the clipping, but you need to be aware 
> of the BView regions that would need to be ivalidated inside app_server 
> anyways. So what you _cannot_ do is to just call the DisplayDriver 
> method with the parameters comming from the client, even if 
> DisplayDriver would perform the clipping for you. That's because then 
> you don't know which regions you need to trigger invalidation for.
> 
> 
>>and there are
>>performance issues if overlapping occurs.
> 
> 
> I hope it is clear now which kind of overlapping I mean. It would be 
> much easier if I draw this out on paper, I guess... :-))
> 
> 
>>      I think this function must stay in DD as the HW accelerated 
>>subclass
>>should pass the rectangles found in those regions to the accelerant, 
>>by
>>way of screen_to_screen_blit() hook function. (That HW accelerated 
>>subclass
>>should build a list of blit_params and pass to the accelerant) From 
>>this point
>>it's accelerant's job how to handle things. And he can do _a lot_ 
>>better than
>>what I did in CCR(). He has enough video memory at its disposal so 
>>that it can
>>copy really fast from on-screen to a part of free video memory and 
>>then back
>>again. And if I'm not wrong this is fast enough to be done during a 
>>retrace.
> 
> 
> I'm pretty sure it does an in-place copy. It just figures out in which 
> direction to read and write the bytes, so that it doesn't read from 
> locations that have already been written to during that operation. 
> Suppose this:
> 
> 12345678xxxxxxx
> 
> This is a row of pixels in memory. The numbers stand for colors. You 
> want to copy the pixels 4 coordinates to the right, this is what you 
> want:
> 
> 123412345678xxx
> 
> Suppose you do this in-place like this:
> 
> int32 xOffset = 4;
> 
> uint32* src = buffer;
> uint32* dst = src + xOffset;
> 
> for (uint32 x = 0; x < width; x++) {
>       *dst = *src;
>       dst++;
>       src++;
> }
> 
> What you get is this (in each iteration):
> 
> 12341678xxxxxxx
> 12341278xxxxxxx
> 12341238xxxxxxx
> 12341234xxxxxxx
> 123412341xxxxxx
> 1234123412xxxxx
> 12341234123xxxx
> 123412341234xxx
> 
> Ups? Where did 5678 go? You have overwritten them in the first for 
> iterations. That's why you need to do it smarter:
> 
> // xOffset is 4
> 
> int32 xIncrement;
> if (xOffset > 0) {
>       // copy right to left
>       src* += width;
>       xIncrement = -1;
> } else {
>       // copy left to right
>       xIncrement = 1;
> }
> 
> dst = src + xOffset;
> 
> for (uint32 x = 0; x < width; x++) {
>       *dst = *src;
>       dst += xIncrement;
>       src += xIncrement;
> }
> 
> And here is the result of each iteration:
> 
> 12345678xxx8xxx
> 12345678xx78xxx
> 12345678x678xxx
> 123456785678xxx
> 123456745678xxx
> 123456345678xxx
> 123452345678xxx
> 123412345678xxx
> 
> And that's correct. Ok, I hope you understand what I mean by in-place 
> copy and what I mean by overlapping. That is the one kind of 
> overlapping. In this case, the destination area overlaps the source 
> area in memory, but that is _no_ problem when you take that into 
> account in your copy algorithm. And I think this is what the graphics 
> engine in the accelerant is doing as well. It does not copy to out of 
> screen regions and then back into visible region at the offset. Unless 
> Rudolf convinces me otherwise... :-)
> 
> 
>>      We kinda' need CCR() although it doesn't fully comply with DD
>>specifications. :-)
> 
> 
> I'm not saying it should go away, I'm just saying that certain criteria 
> must be met for it to be implemented efficiently. Now, here is one 
> criterium: The regions that it gets passed should not overlap. And now 
> I'm talking about a different kind of overlapping. Let's suppose you 
> have a function:
> 
> void DisplayDriver::_MoveRect(BRect rect, BPoint offset);
> 
> This function handles all the magic of doing in-place moving of the 
> rect and it handles also the case where the rect at the offset overlaps 
> the original rect. I have shown above that this is possible.
> 
> What I'm saying now, is that in the cause of one CCR() call, as you 
> call it, this function (MoveRect()) should never have to be called for 
> the same source rect twice or more. Or else the graphics would be 
> completely screwed if you do in-place copying. Ensuring this by 
> app_server prior to calling CCR() is just much smarter. And I'm telling 
> you, you need this logic in app_server anyways, or else you don't know 
> which regions of BViews need to be invalidated, because of the resizing 
> or scrolling (for which this CCR() thing is meant to be in the first 
> place).
> 
> Uff. That's a long mail. Sorry, but I hope all is clear now.
> 
> Best regards,
> -Stephan
> 
> 
> 
> 
> 


Other related posts: