Forum > Graphics

Flickering or what?

<< < (2/8) > >>

Martin_fr:
I single stepped the video and I can't see "flicker". Well...

I can't see the background being cleared. Though I don't know if that is happening, but missing in the video, or if it is not happening.

What I can see, is that the image is scrolled up, leaving only the bottom to be painted, and therefore the bottom showing the not-yet scrolled image. And as the scrolling is not smooth, but like a maybe 50+ pixel at a time => that is visible => so that could be called flicker.

That is to the best of my knowledge the way scrolling is supposed to be implemented.

But I can't say, if there is a delay before the paint. Normally the paint should be really fast. But if for some reason the image still has to be decompressed to be painted, then that would cause a delay.


There is a way to make sure this does not happen (though I don't have the implementation details at hand / and not sure it can easily be done with panels).
That would be:
- don't scroll
- paint the entire background in one go with the newly offset-ed image(s).

---

It is possible that the LCL does not deal optimal with the scrolling of all the panels at once (if you have lots of panels or TWinControl-descendants).

440bx:

--- Quote from: Martin_fr on November 13, 2023, 08:04:02 pm --- as the scrolling is not smooth, but like a maybe 50+ pixel at a time => that is visible => so that could be called flicker.

--- End quote ---
That's also what I'm guessing he is calling flicker.  I'm not sure but, I do believe the bottom part is cleared someway and then painted but, I could be wrong about it being cleared because I didn't step the scrolling frame by frame.

There is usually a slight delay before painting which is mostly due to the fact that WM_PAINT is a low priority message (in Windows, I don't know about its equivalent in other OSs) and that can create flicker or an effect that is similar.


phoenix27:
Before i try to make a little project, best to show the paint routine

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TfrmMediaStore.pb_onPaint(sender: TObject);label loop, there;var i: integer; mi: TMediaItem; maxTopPos, minTopPos: integer; pb: TMediaCanvas; marr: array of TMediaItem; sb: TScrollBox; bmp, bmpTitle: TBGRABitmap; pCanvas: TCanvas; mcount:integer; Y, hei:integer; mt:MediaType; title:string=''; pmi: ^TMediaItem; sz: TSize;begin  pb := TMediaCanvas(sender);  marr:= pb.getMarrItems(mcount);  i:= 0;  sb := TScrollBox(pb.parent);  minTopPos := sb.VertScrollBar.position;  maxTopPos := sb.VertScrollBar.position + sb.ClientHeight;  pCanvas:= pb.canvas;  mt:=pb.mtype;  pmi:= @marr[0];  loop:    if i >= mcount then goto there;    mi:= pmi^;    inc(pmi);    inc(i);    if mi = nil then goto loop;      Y:=mi.top + mi.yOffset;      if (mi.bottom + mi.yOffset >= minTopPos) and (Y <= maxTopPos) then begin          if mi.bmp <> nil then              pCanvas.Draw(mi.left, Y, mi.bmp);      end;    goto loop;  there:  if pb.hoveringItem <> nil  then begin    //hovering item         mi := pb.hoveringItem;         bmp := TBGRABitmap.Create(mi.width, mi.height, BGRA(5,5,120,90));//from 0 to 255, higher means more opaque//0,0,0,100         try           // bmp.Rectangle(0, 0, mi.right, mi.yOffset + mi.bottom, BGRA(255,0,0,200), dmDrawWithTransparency); //e' il contorno             //title bar             if mt = video then                   title:= TVideoItem(mi).title             else if mt = image then                   title:= TImageItem(mi).title             else if mt = web then                   title:= TWebItem(mi).title;              if title <> '' then begin                 hei := 25;                 bmp.FontStyle:= [fsBold];                 sz := bmp.TextSize(capitalize(title));                 if sz.width > bmp.width then hei := 50;                 bmpTitle:= TBGRABitmap.create(mi.width, hei, bgra(0,0,0,120));                 try                    bmpTitle.FontStyle:= [fsBold];                    bmpTitle.FontHeight:=13;                    bmpTitle.TextRect(Rect(0,0, mi.Width, hei), capitalize(title), taCenter, tlCenter, CSSOrangeRed);                    bmp.PutImage(0, bmp.Height - hei, bmpTitle, dmDrawWithTransparency);                 finally                   bmpTitle.Free;                 end;             end;             bmp.Draw(pCanvas, mi.left, mi.yOffset + mi.top, False);         finally            bmp.Free;         end;    end;    marr:= pb.getSelectedItems(mcount);    if mcount > 0 then begin       for mi in marr do begin   //selected items         if assigned(mi) then begin             bmp := TBGRABitmap.Create(mi.width, mi.height, BGRA(255,192,50, 90));//from 0 to 255, higher means more opaque//0,0,0,100            // bmp.Rectangle(0, 0, mi.right, mi.yOffset + mi.bottom, BGRA(0,0,0,100), dmDrawWithTransparency);             bmp.Draw(pCanvas, mi.left, mi.yOffset + mi.top, False);             bmp.Free;         end;       end;    end;end;  

phoenix27:
@Martin_fr Yes, for example when i scroll the page down(and the images are going up) with the mouse wheel i feel like it's taking time to paint the bottom part of the appearing images whereas when i scroll using the scroll bar the bottom part appears watery so to speak

--- Quote ---  There is a way to make sure this does not happen (though I don't have the implementation details at hand / and not sure it can easily be done with panels).
That would be:
- don't scroll
- paint the entire background in one go with the newly offset-ed image(s).

--- End quote ---
What do you mean do not scroll? Everything should appear in the viewport at once.  I don't like that.
Paint the entire background? How? I paint image by image by first checking if it's in view as you can see in the paint routine

Martin_fr:

--- Quote from: phoenix27 on November 13, 2023, 09:15:05 pm ---@Martin_fr Yes, for example when i scroll the page down(and the images are going up) with the mouse wheel i feel like it's taking time to paint the bottom part of the appearing images whereas when i scroll using the scroll bar the bottom part appears watery so to speak

--- Quote ---  There is a way to make sure this does not happen (though I don't have the implementation details at hand / and not sure it can easily be done with panels).
That would be:
- don't scroll
- paint the entire background in one go with the newly offset-ed image(s).

--- End quote ---
What do you mean do not scroll? Everything should appear in the viewport at once.  I don't like that.
Paint the entire background? How? I paint image by image by first checking if it's in view as you can see in the paint routine

--- End quote ---

I should have made it clear, that this is not a good replacement. Right now you have the "split screen" issue, where part is awaiting its paint... And the other part shows what had already been there, it was just scrolled (moved on the screen, without repaint) using ScrollWindowEx from the Win kernel.


If  you don't use ScrollWindowEx => and instead paint the entire visible are with a single BltBitmap (using a fully prepared source bitmap), then you are always that fast, that you shouldn't get the split effect  (o.k. in theory you can hit the screen refresh, and get tearing).
However full update every time is no good. It will be slow, really slow. It wont flicker, but it can easily start stuttering.

----
So the real question (and I don't have the answer) is why does it take that long to update.

The mouse wheel vs scrollbar is of interest. Because if it works with the scrollbar, then your paint method is fast enough.

Unless ...

--- Quote ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- if pb.hoveringItem <> nil  then begin    //hovering item         mi := pb.hoveringItem;         bmp := TBGRABitmap.Create(mi.width, mi.height, BGRA(5,5,120,90));//from 0 to 255, higher means more opaque//0,0,0,100         try
--- End quote ---

Maybe the hovering slows your paint down?

Actually that could be it.

I first though, bad idea to create new bitmaps in paint, better have prepared ones, that can be used. But maybe its not that.
Maybe it is still fast enough, maybe it would better be created outside paint, and kept -- not sure, you may need to try.

But there is another issue.

It looks like the image under the mouse is darkened? So it gets invalidated.

Each time an image gets invalidated, then that entire image needs repaint => Except, the actual repaint will be much more.
If you invalidate 2 small rects, then the area to repaint is the rectangle including both of them (and everything inbetween).
(WIthin one single WinControl, eg. one Panel)

So if you darken (and invalidate) an image in the upper half, and scrolling invalidates the entire width of the lower area (few pixels height, but full width), then the containing repaint rect, will be 80% of the screen. And that could slow think down, and the if a paint event took to long, all the scroll event get combined, do one big scroll before the next paint. And that might indeed flicker.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version