No announcement yet.

Pixel refresh rates for Pixxi 44 and 28 screens

  • Filter
  • Time
  • Show
Clear All
new posts

  • Pixel refresh rates for Pixxi 44 and 28 screens

    I have seen threads of this nature for gen4 screens, but haven't seen any discussion of this for Pixxi based screens (please let me know if a thread does exist already).

    I am essentially trying to ascertain a safe pixel refresh rate for Pixxi 44 and Pixxi 28 screens so that I can avoid the image tearing that you see when you exceed the screen's capabilities. If I knew how many pixels/second these processors/screen could update without tearing the image, I could use the screen area of a video clip or an animated smart widget to determine how many frames per second I could safely request. This would be extremely helpful when pre-processing video files for Visi and designing smartwidget animations. Currently I am wasting a lot of time with trial and error to find refresh rates that safely work for smooth visual output.

    Thanks in advance.

  • #2
    The datasheet documents the pixel throughput for Pixxi as 1.1 million pixels per second.

    You don't normally need to worry about tearing, if images are coming from flash or uSD tearing will most likely not be visible.

    In some circumstances you can see tearing when rapidly updating the display using primitives, but a delay is not the solution in this (or any really) case.

    If you are seeing tearing the solution is often complex, and it changes depending on the display you are using as the 'internal' driver chip is different for almost every display.


    • #3
      I'm getting some very noticeable tearing on one of my smart widgets on a Pixxi 25P4. Posting a link to a video below.

      The widget is 240x150, so that's 36K pixels per frame, and the whole range of the speedometer (70mph) is 140 frames. This means every change in 1 MPH requires two frames. So in the video below, when the image is tearing badly between MPH=7 and MPH=10, the display is only putting out ~6 frames in roughly a second. So that equates to somewhere in the neighborhood of 200K pixels/sec, which you're saying is well within specs for the Pixxi. So is it the video driver chip that causing this? Or something else?

      More background: The widget is being driven by an Arduino Nano using the VisiGenie Library. The serial is running at 115200. Images are being stored on uSD, and program is running in RAM.

      Last edited by ironhalo; 17 March 2021, 02:01 PM.


      • #4
        So the reason the tearing is so visible here is because of the neat, but unusual, action of your smart gauge.

        The internal driver chip is reading from its ram and writing to the display as the ram is also being updated, the tearing appears because the ram has been updated after some lines on the screen have been drawn and before others have been drawn.

        The 'usual' solution is to not start the ram update until you can be sure that the ram you are going to update will not be written to the display before the ram update is complete.

        However, in this case the picture you are drawing is 240*150=36000 pixels, which calculates out to take just under 33ms. The display refreshes at 60Hz, meaning the display refresh takes 16.66ms, so there is no way we can completely draw the picture whilst the display is updating 'elsewhere'.

        The refresh rate of the internal driver chip can be adjusted from 39Hz(25.6ms) to 111Hz(9ms) (datasheet says 119Hz, but the display did not work at this rate), this doesn't appear to help much. The current scan line can be read off the internal driver chip, which is good, as not all chips support this.

        The measured frame draw time is 31ms, slightly better than the calculated value.

        The first thing to so is ensure the GCI file is contiguous on the uSD, this can be achieved by using
        chkdsk d:*.* (assuming d contains the uSD)
        from the command prompt, this will ensure that each frame will take the optimal time to display.

        I have implemented disp_Sync() for this display on a PmmC I have sent to you.

        I have written a Designer program that you can use to have a play with the 'two' adjustable settings to try and come up with a result that you are happy with. This program uses your GCI file, make sure the filename matches. The internal display driver 'thinks' it is writing to a 320(h)x240(w) display, so there are 80 lines missing, these are the top 80 lines, just FYI.

        The program can adjust the refresh rate of the display, see lines 26 to 29.

        It can also adjust the 'Sync line'. You can change the effect of this on the fly by opening the terminal program to the display and typing P to increase the sync line by 10, p to increase by 1, M to decrease by 10 and m to decrease by 1. The program keeps the gauge running at maximum speed so you can immediately see the effects of the change.

        At 111Hz refresh, there is, 'kind of' no tearing, but the appearance is quite different, a sync value above 250 looks best, but it is quite a different look.

        At the default 60Hz refresh sync values from 70 to 120 seem to look best

        At 39Hz values around 85 and 170 seem to best.

        Have a play and see what's best for you.

        Once you find the right settings, you will need to get them into your Genie program.

        For the disp_sync() value, if you chose to use it add
        if (i == iSmartGauge0) disp_Sync(xxx) ;
        after line 548 ("img_SetWord(....)") of C:\Program Files (x86)\4D Labs\4D Workshop 4 IDE\Genie\DIABLO\

        For the refresh rate, if you chose to change the default, add
        disp_SetReg(FRAME_RATE_CONTROL, 0x01);
        after line 30 (>?PreGenieInit?<) of C:\Program Files (x86)\4D Labs\4D Workshop 4 IDE\Genie\DIABLO\
        #constant FRAME_RATE_CONTROL 0xC6
        after line 27

        This will take effect for all Diablo Genie projects, not just this one
        Attached Files


        • #5
          Mark, thanks a ton for creating that file and trying to helping me learn what's really going on behind the scenes. First I want to make sure I understand what's causing us to have to go to these lengths to avoid the tearing. You said the unusual nature of my widget design is largely to blame. If this is a throughput issue of RAM<-->display, I'm curious why this tearing wouldn't be present on any widget (or video clip) that is fully refreshing ~36K pixels. What makes the design of this widget exacerbate the issue? I've certainly seen similar tearing on plenty of graphic elements in my other Genie projects that I run on Diablo16 screens. I assumed this simply an issue of the total number of pixels being refreshed, rather than a product of how the widget is designed.

          So I've played around with the two values you've given me access to. At 39Hz your suggested sync values do essentially make the tearing lines invisible, but the slow refresh rate makes the overall image look laggy. At 111Hz, I could not find any sync values that eliminate tearing. You are right that it looks "different", but no values are acceptable to my eye. At default 60Hz, as you suggested sync values 70-120 look good to me (even up to 170 looks good). I'm curious though, it seems that all we are doing is shifting the phase of the tearing lines up and down the screen by adjusting the sync value. And that the values that look good, they only look good because I have a region of blank background in the middle of the image to "hide" the tearing lines in. If my widget had no blank background area in the middle, I assume the tearing lines would be just as visible at these "optimal" values we've found? And this would no longer be a solution in that scenario?

          This is super helpful for me to understand what's going on with the display driver settings. However ideally I think I'd rather fully understand how to avoid causing the tearing in the first place, so that I don't have to go to these lengths to 'cover it up' every time I design a widget with heavy motion. So using this widget as an example, what dimensions would I need to reduce it down to in order to avoid the RAM read/display issue?

          Lastly, the last part of your instruction include editing the IDE's \Diablo\ files. Did you mean to say \Pixxi44\ files? And I replace the "xxx" with the sync value of 70? And for keeping the default refresh rate of 60Hz I can ignore the 2nd and 3rd code changes, I only have to make the first change?

          Thanks again for your help.


          • #6
            It will be present on any widget / video clip refreshing ~36k pixels. But normally the widget is mostly static with, say a rotary pointer. The static part won't tear, because it is static, when the pointer tears it isn't as obvious, mostly because it is smaller to the eye.

            You have quite a few non static things in your widget, hence the tearing is more noticeable.

            Hope that makes sense.

            Yes, because the refresh time is faster than the widget write time, what we are effectively doing (and all we can do) is moving the tearing 'issue' to a static part of the widget (eg a bit that is white right across the screen), so it is as you said.

            The issue is always there, it's just that it's not always obvious, I think in this case it is more obvious because of the 'large' numbers that are moving across the screen.

            As far as I can recall you are only the second person to raise this in over 10 years. Doesn't mean it's not an issue, just that it's not noticed much.

            All yeses for the second last paragraph.


            • #7
              Mark, I have edited my C:\Program Files (x86)\4D Labs\4D Workshop 4 IDE\Genie\Pixxi44\ file using the "
              if (i == iSmartGauge0) disp_Sync(70);" change you suggested. My intention was to leave the refresh rate at default, and change the sync line value to 70. Then I recompiled and reloaded my program.

              My observations:

              1) I'm not sure the change had any effect. As you can see from the video at the link below, I'm still getting the tearing. It looks to be the same amount of tearing as the first video I posted for you. Is there any way to test that the change I made to the file actually took effect?

              2) When I run my program the tearing lines do not stay at the same vertical height as they do on the Designer test file you made for me. They wander up and down the screen. I assume this is because the movement of my widget is not a constant speed. It accelerates and decelerates as a real speedometer does, whereas your test file used a constant animation speed. If this is true and the change in animation speed is always going to make the tearing lines move up and down the screen (even with the sync line value set), it seems like your method of hiding the tearing lines may not work for this.

              Again, I can't say for sure, but I feel like the sync line value may not have actually done anything. Either that, or it did take effect, but the tearing lines are moving up and down so much it doesn't really help. Not sure which is the case.

              I'll send you my edited file so you can see if the changes were made correctly. Instead of line 548 in the Diablo p2 file, it looks like it was after line 507 in the Pixxi44 p2 file.

              Video link:


              • #8
                Your P2 file seems fine. I replaced it in my Genie\Pixxi44 folder and rebuilt your project and the extra line ended up at line 508 in the .4dgenies file. Can you check yours?

                They drift up and down the screen because the writes are occurring at different scan line times, the disp_Sync ensures they all happen at the same time, and this ultimately solves the issue.

                To add many (most?) file types to the forum they need to be in a zip.


                • #9
                  Ah I see. So that means the disp_Sync command has not taken effect for my program yet since the lines are still drifting up and down? I’ll look at the files again tomorrow and let you know if/where the extra code is output. Is there any other reason it might not be taking effect for me?


                  • #10
                    I can't think of any atm. Can you give me a sequence of values to send to it and I'll set up a test with mine.


                    • #11
                      I would like to continue to troubleshoot this to know I can use the disp_Sync command properly to help hide the tearing effect. However I’d still also like to know how to design animated widgets and video clips that never cause the issue to begin with. Can you briefly elaborate on the math behind this issue once more, and how to arrive at a safe number of pixels/second (or some other measure) that can be used before the RAM/display throughput becomes a problem? For the sake of this he discussion, let’s assume i’m talking about a widget or video clip that has heavy motion, meaning most or all of its pixels are refreshed on every redraw. In theory, how large could it be before we run into this tearing issue?


                      • #12
                        Yes I think I have an array of values for testing in some old code. I’ll dig that up and send it to you tomorrow. Thanks.


                        • #13
                          Mark, the line ended up at line 230 in my .4DGenieS file. Maybe this is why I'm not seeing it take effect? I'll upload it to the support case.


                          • #14
                            The disp_Sync was pausing until the scan line was 'simply' greater than the specified value. Whilst this is fine for simple cases, and appeared fine on another display I was using that supported disp_Sync, it wasn't working here when there was a delay between the display of one frame and the next.

                            It can be seen in the attached, just run it 'asis' and in the Comms window press D to increase the delay between frames (d to decrease), it starts tearing pretty quickly.

                            The solution in this case is for disp_Sync to pause until the scan line is in a range, as for something that takes time to display, a low scan line is just as bad as a high scanline.

                            So I've sent you a PmmC that has effectively two parameters in one. It takes a scanline and a range. The scanline is in the lower 10 bits and the range (/4) is in the high 6 bits.

                            For me a scanline of 70 (as you found before) and a range of 35 (/4) worked with all delay values I tried.

                            Thus the disp_Sync will wait until the scanline is in the range of 70...70+35*4 or 70...210 before returning. This means passing a hex value of 0x8c46 to disp_Sync.

                            Hope that makes sense.

                            Attached Files


                            • #15
                              Mark, I've loaded the newest PMMC and changed the dish_Sync value to 0x8c46, and that seems to be working! Thanks for your continued help on this. Unfortunately despite your best efforts to educate me, I have to admit I only very superficially understand what's going on here. So my concern is that as I develop new animations going forward that have different dimensions and frame rates, I will have to revisit this and make adjustments for each one. That seems problematic for several reasons: A) As I use different displays, you would need to supply me with custom pmmc files for each display I'm using, and B) The various display_sync values for each project would have to be hard coded into the file, which means I would have to keep a running log of the widgets across each project and make sure none of them share similar widget names (or I would have to swap out the values in the file each time I re-compile a project).

                              To be honest, with all the various interfaces I have in development and with the various display types I plan on using, this approach doesn't seem sustainable for me. I'm going to again request some proper education on how to completely avoid this tearing so that I don't have to go to these lengths to hide it. Given the current 'full motion' widget, can you please explain to me what the maximum dimensions of the widget would have to be reduced to in order to prevent the RAM<->DISPLAY buffer issue we are dealing with? If you can help me understand this, and how that formula would translate to other displays, it will be much more sustainable for me to just design widgets/animations within those guidelines rather than have to troubleshoot the display_Sync issue in every case.

                              Thanks again for your help, I really appreciate it.