Recent

Author Topic: Flickering or what?  (Read 5794 times)

phoenix27

  • Jr. Member
  • **
  • Posts: 92
Flickering or what?
« on: November 13, 2023, 06:35:54 pm »
In the attached video(i had to keep it within the maximum admitted size so the quality is not good) you can see the problem. When i scroll up or down there is flickering(is that the way it's called?) on the top or bottom edge.  The images are painted in a TPanel contained in a TScrollBox contained into a TTabSheet contained in a TPageControl. I did set the doubleBuffered property of Tpanel and TScrollBox to true but it didn't help. I just do not know how to solve it. Does somebody have any idea?

wp

  • Hero Member
  • *****
  • Posts: 12696
Re: Flickering or what?
« Reply #1 on: November 13, 2023, 06:57:38 pm »
It would be better if you'd prepare a small demo project showing the issue. Pack the .pas, .lfm, .lpi and .lpr files into a shared zip which you can upload here (do not add files generated by the compiler because this may exceed the upload size limit). Specifiy the size and count of the images to be displayed so that I can use similar images of my own. Do not upload your full project, remove everything needed, ideally begin a new project from scratch - please understand that I am not inclined to debug a huge project which i do not understand.

phoenix27

  • Jr. Member
  • **
  • Posts: 92
Re: Flickering or what?
« Reply #2 on: November 13, 2023, 07:16:51 pm »
Thank you for you answer. I thought that too although it will require a bit of work because my programming style is messy, to say the least. But from just watching the video did you get any idea on what it could be? I tried, using the same algorithm(only translated to c++) with wxWidgets and c++ and it works well, no flickering. Keep in mind that the images are not TImage instances, they are painted in the onpaint event of the TPanel.A while ago i tried to translate the program in Delphi but using TImage for the images and it worked well. Anyway i'll try to make a little project.

wp

  • Hero Member
  • *****
  • Posts: 12696
Re: Flickering or what?
« Reply #3 on: November 13, 2023, 07:34:37 pm »
But from just watching the video did you get any idea on what it could be?
No, I did not even see any flicker at all...

440bx

  • Hero Member
  • *****
  • Posts: 5080
Re: Flickering or what?
« Reply #4 on: November 13, 2023, 07:37:52 pm »
When i scroll up or down there is flickering(is that the way it's called?) on the top or bottom edge.  The images are painted in a TPanel contained in a TScrollBox contained into a TTabSheet contained in a TPageControl. I did set the doubleBuffered property of Tpanel and TScrollBox to true but it didn't help. I just do not know how to solve it. Does somebody have any idea?
My knowledge of TPanel, TScrollbox and other LCL controls is nil but, I'm going to presume you're doing this app in Windows.

What happens is that somewhere in all that code (whatever LCL code controls/does the scrolling) when scrolling happens the bottom part (which got scrolled up) is cleared by the default window handler.    The way to avoid the flickering is to have the background _not_ be cleared when the window is scrolled up.   The easiest way is to have a WM_BACKGROUND message handler that returns "true" indicating the newly exposed part of the window has been erased (even though it hasn't been) and then "overwritten" with the new part of the image (which you are doing but, you are overwriting the cleared background instead of what's left there of the old piciture.)

As far as where in the LCL the WM_BACKGROUND should be processed, I simply don't have a clue.  (I only know pure Windows API and message handlers.)

HTH.



But from just watching the video did you get any idea on what it could be?
No, I did not even see any flicker at all...
I think he is referring to the slight amount of flicker visible at the bottom of the screen window when the images are scrolled up.

« Last Edit: November 13, 2023, 07:48:01 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10921
  • Debugger - SynEdit - and more
    • wiki
Re: Flickering or what?
« Reply #5 on: November 13, 2023, 08:04:02 pm »
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

  • Hero Member
  • *****
  • Posts: 5080
Re: Flickering or what?
« Reply #6 on: November 13, 2023, 08:28:59 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.
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.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

phoenix27

  • Jr. Member
  • **
  • Posts: 92
Re: Flickering or what?
« Reply #7 on: November 13, 2023, 08:41:14 pm »
Before i try to make a little project, best to show the paint routine
Code: Pascal  [Select][+][-]
  1. procedure TfrmMediaStore.pb_onPaint(sender: TObject);
  2. label loop, there;
  3. var
  4.  i: integer;
  5.  mi: TMediaItem;
  6.  maxTopPos, minTopPos: integer;
  7.  pb: TMediaCanvas;
  8.  marr: array of TMediaItem;
  9.  sb: TScrollBox;
  10.  bmp, bmpTitle: TBGRABitmap;
  11.  pCanvas: TCanvas;
  12.  mcount:integer;
  13.  Y, hei:integer;
  14.  mt:MediaType;
  15.  title:string='';
  16.  pmi: ^TMediaItem;
  17.  sz: TSize;
  18. begin
  19.   pb := TMediaCanvas(sender);
  20.   marr:= pb.getMarrItems(mcount);
  21.   i:= 0;
  22.   sb := TScrollBox(pb.parent);
  23.   minTopPos := sb.VertScrollBar.position;
  24.   maxTopPos := sb.VertScrollBar.position + sb.ClientHeight;
  25.   pCanvas:= pb.canvas;
  26.   mt:=pb.mtype;
  27.   pmi:= @marr[0];
  28.   loop:
  29.     if i >= mcount then goto there;
  30.     mi:= pmi^;
  31.     inc(pmi);
  32.     inc(i);
  33.     if mi = nil then goto loop;
  34.       Y:=mi.top + mi.yOffset;
  35.       if (mi.bottom + mi.yOffset >= minTopPos) and (Y <= maxTopPos) then begin
  36.           if mi.bmp <> nil then
  37.               pCanvas.Draw(mi.left, Y, mi.bmp);
  38.       end;
  39.     goto loop;
  40.   there:
  41.   if pb.hoveringItem <> nil  then begin    //hovering item
  42.          mi := pb.hoveringItem;
  43.          bmp := TBGRABitmap.Create(mi.width, mi.height, BGRA(5,5,120,90));//from 0 to 255, higher means more opaque//0,0,0,100
  44.          try
  45.            // bmp.Rectangle(0, 0, mi.right, mi.yOffset + mi.bottom, BGRA(255,0,0,200), dmDrawWithTransparency); //e' il contorno
  46.              //title bar
  47.              if mt = video then
  48.                    title:= TVideoItem(mi).title
  49.              else if mt = image then
  50.                    title:= TImageItem(mi).title
  51.              else if mt = web then
  52.                    title:= TWebItem(mi).title;
  53.               if title <> '' then begin
  54.                  hei := 25;
  55.                  bmp.FontStyle:= [fsBold];
  56.                  sz := bmp.TextSize(capitalize(title));
  57.                  if sz.width > bmp.width then hei := 50;
  58.                  bmpTitle:= TBGRABitmap.create(mi.width, hei, bgra(0,0,0,120));
  59.                  try
  60.                     bmpTitle.FontStyle:= [fsBold];
  61.                     bmpTitle.FontHeight:=13;
  62.                     bmpTitle.TextRect(Rect(0,0, mi.Width, hei), capitalize(title), taCenter, tlCenter, CSSOrangeRed);
  63.                     bmp.PutImage(0, bmp.Height - hei, bmpTitle, dmDrawWithTransparency);
  64.                  finally
  65.                    bmpTitle.Free;
  66.                  end;
  67.              end;
  68.              bmp.Draw(pCanvas, mi.left, mi.yOffset + mi.top, False);
  69.          finally
  70.             bmp.Free;
  71.          end;
  72.     end;
  73.     marr:= pb.getSelectedItems(mcount);
  74.     if mcount > 0 then begin
  75.        for mi in marr do begin   //selected items
  76.          if assigned(mi) then begin
  77.              bmp := TBGRABitmap.Create(mi.width, mi.height, BGRA(255,192,50, 90));//from 0 to 255, higher means more opaque//0,0,0,100
  78.             // bmp.Rectangle(0, 0, mi.right, mi.yOffset + mi.bottom, BGRA(0,0,0,100), dmDrawWithTransparency);
  79.              bmp.Draw(pCanvas, mi.left, mi.yOffset + mi.top, False);
  80.              bmp.Free;
  81.          end;
  82.        end;
  83.     end;
  84. end;
  85.  

phoenix27

  • Jr. Member
  • **
  • Posts: 92
Re: Flickering or what?
« Reply #8 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).
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

  • Administrator
  • Hero Member
  • *
  • Posts: 10921
  • Debugger - SynEdit - and more
    • wiki
Re: Flickering or what?
« Reply #9 on: November 14, 2023, 02:38:41 am »
@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).
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

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  [Select][+][-]
  1.  if pb.hoveringItem <> nil  then begin    //hovering item
  2.          mi := pb.hoveringItem;
  3.          bmp := TBGRABitmap.Create(mi.width, mi.height, BGRA(5,5,120,90));//from 0 to 255, higher means more opaque//0,0,0,100
  4.          try

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.

Handoko

  • Hero Member
  • *****
  • Posts: 5396
  • My goal: build my own game engine using Lazarus
Re: Flickering or what?
« Reply #10 on: November 14, 2023, 05:56:56 am »
I didn't see any flicker, maybe the video quality wasn't good enough to capture it. But I did see some paint delay.

I ever animated several hires images at a same time and displayed them in much smaller sizes on the screen, I got noticeable paint delay. My workaround was to resize all the images to match its display sizes before the starting the animation, it worked for my case. Perhaps you can try my solution.
« Last Edit: November 14, 2023, 06:01:57 am by Handoko »

phoenix27

  • Jr. Member
  • **
  • Posts: 92
Re: Flickering or what?
« Reply #11 on: November 14, 2023, 04:26:09 pm »
@Martin_fr "Maybe the hovering slows your paint down?" I removed the code from the paint event and the problem is still there with all its ugliness.
Anyway i prepared a little project for all of you to try and then tell me what's going on. Put in a folder 50 images(size is not important) launch the app then maximize the program window to see better what the problem is, finally open that folder and when the images appear start scrolling down with the mouse wheel and see for yourself. I ported the same program in c++(wxWidgets) and even in Lua and found no problem whatsoever.  Forgot to say that you must include lazgdiplus and BGRABitmappack in the project inspector for the app to work
« Last Edit: November 14, 2023, 04:27:48 pm by phoenix27 »

phoenix27

  • Jr. Member
  • **
  • Posts: 92
Re: Flickering or what?
« Reply #12 on: November 14, 2023, 05:35:24 pm »
I just loaded 687 images with the app attached in the prev post(i've never done this in my original app), it took a while to load but it can be clearly seen that it's the painting the problem, really slow!! But why? I just draw the visible images, not all of them. It can be seen in the OnPaint routine. Or It's not correct?
« Last Edit: November 14, 2023, 05:36:59 pm by phoenix27 »

phoenix27

  • Jr. Member
  • **
  • Posts: 92
Re: Flickering or what?
« Reply #13 on: November 14, 2023, 05:43:02 pm »
In the program attached at the line 304 change
Code: Pascal  [Select][+][-]
  1.    freeAndNil(imgsArr[i]);
  2.  
to
Code: Pascal  [Select][+][-]
  1. freeAndNil(imgsArr[i].bmp);
  2.  

balazsszekely

  • Guest
Re: Flickering or what?
« Reply #14 on: November 14, 2023, 08:01:34 pm »
@phoenix27

Try attached project.


 

TinyPortal © 2005-2018