eglfs: Allow using a different framebuffer device

Right now /dev/fb0 is hardcoded. This is not ideal. Therefore
QT_QPA_EGLFS_FB is introduced. This environment variable can be set to
a different framebuffer device. Once it is set, eglfs will use the
specific device. This is similar to linuxfb's fb=... plugin parameter.

The actual behavior depends on the board-specific implementations.
For now only iMX6 has real support. It extracts the index from the
device name as bind the EGL display to the corresponding framebuffer
using the vendor-specific fbGetDisplayByIndex(). Other hooks can
follow suit later on.

With this patch eglfs is at least on par with linuxfb, meaning that,
if the board supports it, different apps can run on different screens.

Task-number: QTBUG-36113
Change-Id: Ia3c88bd06e108bc668433e3c5c3fce34a5a0e73d
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
This commit is contained in:
Laszlo Agocs 2014-01-16 14:01:04 +01:00 committed by The Qt Project
parent 894ce8aaab
commit 87d2fa5f84
3 changed files with 25 additions and 6 deletions

View File

@ -72,7 +72,7 @@ QEglFSImx6Hooks::QEglFSImx6Hooks()
qputenv("FB_MULTI_BUFFER", "2");
}
mNativeDisplay = fbGetDisplayByIndex(0);
mNativeDisplay = fbGetDisplayByIndex(framebufferIndex());
fbGetDisplayGeometry(mNativeDisplay, &width, &height);
mScreenSize.setHeight(height);
mScreenSize.setWidth(width);

View File

@ -77,7 +77,8 @@ public:
virtual bool filterConfig(EGLDisplay display, EGLConfig config) const;
virtual void waitForVSync() const;
virtual const char *fbDeviceName() const;
virtual QByteArray fbDeviceName() const;
virtual int framebufferIndex() const;
static QEglFSHooks *hooks()
{

View File

@ -41,6 +41,7 @@
#include "qeglfshooks.h"
#include "qeglfscursor.h"
#include <QtCore/QRegularExpression>
#include <fcntl.h>
#include <unistd.h>
@ -56,17 +57,34 @@ QT_BEGIN_NAMESPACE
// this is a global static to keep the QEglFSHooks interface as clean as possible
static int framebuffer = -1;
const char *QEglFSHooks::fbDeviceName() const
QByteArray QEglFSHooks::fbDeviceName() const
{
return "/dev/fb0";
QByteArray fbDev = qgetenv("QT_QPA_EGLFS_FB");
if (fbDev.isEmpty())
fbDev = QByteArrayLiteral("/dev/fb0");
return fbDev;
}
int QEglFSHooks::framebufferIndex() const
{
int fbIndex = 0;
QRegularExpression fbIndexRx(QLatin1String("fb(\\d+)"));
QRegularExpressionMatch match = fbIndexRx.match(fbDeviceName());
if (match.hasMatch())
fbIndex = match.captured(1).toInt();
return fbIndex;
}
void QEglFSHooks::platformInit()
{
framebuffer = qt_safe_open(fbDeviceName(), O_RDONLY);
QByteArray fbDev = fbDeviceName();
framebuffer = qt_safe_open(fbDev, O_RDONLY);
if (framebuffer == -1)
qWarning("EGLFS: Failed to open %s", fbDeviceName());
qWarning("EGLFS: Failed to open %s", qPrintable(fbDev));
}
void QEglFSHooks::platformDestroy()