Reported display display size with 320x240 TFT on Raspberry Pi

#1

Smaller TFT displays for the Raspberry Pi like this 3.5" one from Adafruit
3.5" TFT

have smaller resolutions (this one is 320x240) and force the console size by using the framebuffer_width and framebuffer_height values in /boot/config.txt. Strangely when running an oF application with these displays, oF reports a display size of 720x480:

[…]
[notice ] ofAppEGLWindow: setupRPiNativeWindow(): screenRect: 720x480
[notice ] ofAppEGLWindow: setupRPiNativeWindow(): windowRect: 320x240
[…]

which results in the content being draw as if it were really on a larger display - in this case both scaled and horizontally squashed since it isn’t the same aspect ratio. I poked through the code a little and came upon ofAppEGLWindow.cpp

ofPoint ofAppEGLWindow::getScreenSize(){
  unsigned int screenWidth = 0;
  unsigned int screenHeight = 0;

  if(isUsingX11) {
    […]      
  } else {
    #ifdef TARGET_RASPBERRY_PI
      int success = graphics_get_display_size(settings.screenNum, &screenWidth, &screenHeight);
      if(success < 0) {
        ofLogError("ofAppEGLWindow") << "getScreenSize(): tried to get display size but failed";
      }

    #else
      ofLogError("ofAppEGLWindow") << "getScreenSize(): no native window type for this system, perhaps try X11?";
    #endif

  }

  return ofPoint(screenWidth, screenHeight,0);
}```

and debugging that (I couldn't get `gdb` to print local variables so I added a log and rebuilt :cry:) I could see the values out of `graphics_get_display_size` were `720` and `480`. This function seems to be declared in [bcm_host.h](https://github.com/raspberrypi/firmware/blob/master/opt/vc/include/bcm_host.h)
```C
int32_t graphics_get_display_size( const uint16_t display_number,
                                                    uint32_t *width,
                                                    uint32_t *height);

which seems like VideoCore stuff, so I’m guessing maybe the GL context has some sort of minimum size it’ll support?

Have others run into this? Could the viewport be used to compensate for the transforms that are being applied?

#2

I have this one on the way that requires a kernel patch - might be related?

#3

Im interested!!!, i was looking to get one of those piTft, but im not sure because of the kernel patch that its need.

I see on rpi forums that there is a patch that duplicate the “framebuffer” of the hdmi to the tft, or something like that and in the adafruit tuto they show how to modify the pygame library to output to the tft buffer… Do you think that it would work on of?

I also see those http://www.chalk-elec.com/?page_id=1283#!/~/product/id=14647624 that seems to work out of the box but are too big

#4

The whole topical space is pretty foreign to me in the little investigation I’ve made, so many grains of salt…

It sounds as though these TFT displays use the linux framebuffer /dev/fb1.The firmware function graphics_get_display_size only accepts a display_number of 0 and even more so, EGL on the Raspberry Pi does not use framebuffers – so this display 0 doesn’t likely refer to the TFT display size.

The PiTFT from Adafruit has a custom kernel that as far as I can tell, copies the framebuffer contents from /dev/fb0 to /dev/fb1 to allow for hardware acceleration, though the synchronization and copy cost then maxes out at 28 FPS. If you watch the video on the product page, you’ll see that they specifically target /dev/fb1 with the image viewer fbi and with mplayer.

So, I don’t understand how the oF-created EGL context is being drawn to my TFT display or what is responsible for the scaling. I’m guessing something is copying the content to /dev/fb1 and maybe the display is actually doing the scaling but I really don’t know. :confused:

I’m going to ask over on the Adafruit forum and see if they might have some idea how one uses these TFT displays should be configured to work with an EGL context without the transforms. And failing that maybe the Raspberry Pi forum, but I think I’m just missing something in how these things work.

1 Like
#5

I posted over on the Adafruit forum in the thread 3.5" TFT and EGL display size. For simple calibration, I’m just drawing a 40x40 px checkerboard.

Expected (running on OS X):

Actual:

#6

have you tried any of the hello_pi apps in /opt/vc/src/hello_pi?

#7

Indeed, those all work without a hitch - each fills the display and doesn’t appear to have any uneven transforms applied.

If I setup my oF app with a 720x480 context then re-scale at draw time (and account for the aspect-ratio change) I get pretty close though the checkerboard pattern is eroded in the first and last columns:

int main() {
    ofSetCurrentRenderer(ofGLProgrammableRenderer::TYPE);
#if defined(TARGET_LINUX)
    ofSetupOpenGL(720, 480, OF_WINDOW);
#elif defined(TARGET_OSX)
    ofSetupOpenGL(640, 480, OF_WINDOW);
#endif
    ofRunApp(new App());
}

and:

void App::draw() {
    ofScale((float)ofGetWindowWidth()/320.0f, (float)ofGetWindowHeight()/240.0f);
    mCheckerboardTexture.draw(0.0f, 0.0f, 320.0f, 240.0f);
    […]
#8

Tweaked checkerboard pattern to better demonstrate the clipping:

#9

@bakercp any clue?

#10

I’ve had analog TFT displays do all sorts of “helpful” (unhelpful) scaling / overscan compensation – when it receives an analog / composite signal. 320x240 doesn’t mean that’s the physical limit, it just means that whatever composite signal you pass in there will be scaled to that. I’d check your overscan settings and make sure the pi is configured in the same way you’d configure it to display on an NTSC / PAL tv.

#11

Hmm, experimentally, I’ve haven’t seen EGL respect the overscan settings and a moderator on the Raspberry Pi forum seems to confirm that in the thread EGL windows not respecting overscan:
The overscan settings from config.txt just apply to the standard framebuffer.
Anything created through dispmanx (e.g. Video and EGL overlays) do not consider the config.txt overscan settings.

You can compensate for overscan yourself, by altering the dispmanx dest_rect.

BUT that thread also mentions a config setting that isn’t in the default config.txt, isn’t listed on http://elinux.org/RPiconfig and I really can’t find much documentation on:
There’s an experimental feature in latest firmware.
overscan_scale=1

And adding that fixes the clipping!

I still don’t know how the EGL content gets to the framebuffer, and why I don’t need to use a framebuffer copying tool like the PiTFT requires, but for my immediate needs, it is working.

Thanks for all the help guys!


So for those following along at home, to get a TFT working when connected via composite (fbcp and what not isn’t required) two settings are needed to get things working:

openFrameworks

The context needs to be created at 720x480 even if the display isn’t, and drawn content should be scaled to accommodate, namely the aspect ratio.

Raspberry Pi

/boot/config.txt needs overscan_scale=1 to prevent clipped content.

2 Likes