Sunday, July 26, 2009

On screen tearing

The final display device, your LCD, works at a fixed frequency which results in a certain refresh rate. Think of it as the screen being "painted" a lot of times per seconds. The "painting" of the screen is an standalone process that is performed by a chip on the LCD itself from its own memory. Think of what would happen if you change the memory contents while the screen is being painted. The only way to do this is to have some kind of syncronization signal from the LCD chip. That way, you wait until the right moment and update the memory contens while they are not being used.

Now think that things are even more complex: actually there are at least three processes and three memory buffers involved: an application normally has an internal buffer where it writes a whole screen before sending it to display. Then the framebuffer driver in the linux kernel has another buffer where contents sent by the application are stored, and finally there is the already mentioned LCD internal buffer. Transfers from one buffer to the next must all be synchronized somehow to the screen painting in order to avoid the tearing effect.

Now for the bad news: I'm yet to confirm it, but the A320 hardware design is... well, let's say it's not the best I've seen. I believe there is no way to read the "repaint" status of the LCD or get a synchronization signal which would allow the linux kernel framebuffer driver to transfer contents to the LCD memory in a way that would not cause some tearing. The LCD controller has registers that expose this information, but they cannot be read because the R/W signal is just not connected to the display. The CPU has a dedicated R/W signal for the LCD but the designers ignored it and just left the LCD stuck in write mode. You can write the registers but you cannot read them. This is also the cause of the impossibility of autodetecting the LCD type: again, both known LCD types have specific registers to identify the model, but we just can't read them !!!. There are some other blatant design mistakes for which they had to implement a workaround, but they are not related to tearing.

It is a shame: LCD synchronization is perfectly possible but they seem to have taken all steps to make it impossible. There might be a very twisted way to somewhat achieve synchronization, but I'm yet to investigate it.

Anyway, you may be wondering: why do some games/emulators show tearing in the original firmware and not in dingux or just the opposite?. It has to do with frequency mixing. The math behind it is far from simple, but it can be summarized this way: when you mix two frequencies you obtain both the sum and the substraction. If the framebuffer driver is refreshing the LCD at 70Hz and the LCD is refreshing the pixels at 50Hz you get both 20Hz and 120Hz. In this case you won't probably see any tearing because both frequencies are high enough, but now think what would happen if an application happens to refresh the framebuffer at 55Hz. You get 5Hz and 105Hz, and you bet the 5Hz are pretty visible.

Now think that as I said earlier, there are at least three processes/buffers involved and that each one works at its own frequency.

We can program the LCD refresh rate. We can set it higher or lower, it doesn't matter. What matters is its relation to the refresh rate of the application that is using the screen at a given time, and that, of course, changes from one application to another.

I'll keep on investigating about the whole LCD subsystem and find a way to mitigate the tearing effect, but bear in mind that with current hardware it might be impossible. Note also that as a last resort the LCD refresh rate could be changed in a per-application basis to minimize the tearing in each case.

7 comments:

  1. Muy interesante boo boo, es una pena que el problema del tearing sea del diseño como tal hardware, pero en dingux hasta el momento el efecto tearing no ha sido muy notorio.
    Gracias por tu esfuerzo y trabajo.

    ReplyDelete
  2. Wow your very smart:) thank you for the detailed answer

    ReplyDelete
  3. Well, maybe you will find the answer in Gemei X760+ (maybe not!). The hardware is similar, but not equal. At least the Gemei LCD dont have problems in original firmware, and the SDK is the same! Only the time will bring light to this.

    ReplyDelete
  4. I found a pixel underclocker app I ran LCD 11 then retested Zelda for the gba. The game I'm currently playing. It seems the screen tear is gone. The only reason I noticed cause the screen tear was making me dizzy:) not anymore. Now would this be a solution all around I'm not sure.

    ReplyDelete
  5. Is it possible to do a hardware mod and connect the R/W of the LCD controller? Or is there more involved than just soldering a wire?
    I know, it is not a solution for most of us.

    ReplyDelete
  6. @Robert

    In theory it could be possible but you'd need special equipment to remove the CPU, patch the PCB, reball the CPU and solder it again. Impossible (or anyway far far far from beign worth the trouble).

    BTW: the CPU is literally glued with epoxy to the PCB, I guess for making the whole A30 sturdier. No way you can desolder it even with an infrared station without destroying something.

    ReplyDelete
  7. lcd panel datasheet : http://www.pdfsea.com/down/down.php?downid=38235&id=0

    ReplyDelete