summaryrefslogtreecommitdiffstats
path: root/src/plugins/gfxdrivers/hybrid
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gfxdrivers/hybrid')
-rw-r--r--src/plugins/gfxdrivers/hybrid/hybrid.pro16
-rw-r--r--src/plugins/gfxdrivers/hybrid/hybridplugin.cpp75
-rw-r--r--src/plugins/gfxdrivers/hybrid/hybridscreen.cpp382
-rw-r--r--src/plugins/gfxdrivers/hybrid/hybridscreen.h97
-rw-r--r--src/plugins/gfxdrivers/hybrid/hybridsurface.cpp300
-rw-r--r--src/plugins/gfxdrivers/hybrid/hybridsurface.h90
6 files changed, 960 insertions, 0 deletions
diff --git a/src/plugins/gfxdrivers/hybrid/hybrid.pro b/src/plugins/gfxdrivers/hybrid/hybrid.pro
new file mode 100644
index 0000000..8b8e9ef
--- /dev/null
+++ b/src/plugins/gfxdrivers/hybrid/hybrid.pro
@@ -0,0 +1,16 @@
+TEMPLATE = lib
+CONFIG += plugin
+QT += opengl
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/gfxdrivers
+
+TARGET = hybridscreen
+target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
+INSTALLS += target
+
+HEADERS = hybridscreen.h \
+ hybridsurface.h
+SOURCES = hybridscreen.cpp \
+ hybridsurface.cpp \
+ hybridplugin.cpp
+
diff --git a/src/plugins/gfxdrivers/hybrid/hybridplugin.cpp b/src/plugins/gfxdrivers/hybrid/hybridplugin.cpp
new file mode 100644
index 0000000..803c4fc
--- /dev/null
+++ b/src/plugins/gfxdrivers/hybrid/hybridplugin.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "hybridscreen.h"
+
+#include <QScreenDriverPlugin>
+#include <QStringList>
+
+class HybridPlugin : public QScreenDriverPlugin
+{
+public:
+ HybridPlugin();
+
+ QStringList keys() const;
+ QScreen *create(const QString&, int displayId);
+};
+
+HybridPlugin::HybridPlugin()
+ : QScreenDriverPlugin()
+{
+}
+
+QStringList HybridPlugin::keys() const
+{
+ return (QStringList() << "hybrid");
+}
+
+QScreen* HybridPlugin::create(const QString &driver, int displayId)
+{
+ if (driver.toLower() != "hybrid")
+ return 0;
+
+ return new HybridScreen(displayId);
+}
+
+Q_EXPORT_STATIC_PLUGIN(Hybrid)
+Q_EXPORT_PLUGIN2(hybridscreendriver, HybridPlugin)
diff --git a/src/plugins/gfxdrivers/hybrid/hybridscreen.cpp b/src/plugins/gfxdrivers/hybrid/hybridscreen.cpp
new file mode 100644
index 0000000..3a40b4c
--- /dev/null
+++ b/src/plugins/gfxdrivers/hybrid/hybridscreen.cpp
@@ -0,0 +1,382 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "hybridscreen.h"
+#include "hybridsurface.h"
+
+#include <QVector>
+#include <QVarLengthArray>
+#include <QApplication>
+#include <QColor>
+#include <QWidget>
+
+#include <GLES/egl.h>
+
+class HybridScreenPrivate
+{
+public:
+ HybridScreenPrivate(HybridScreen *owner);
+
+ bool verbose;
+ EGLDisplay display;
+ EGLint majorEGLVersion;
+ EGLint minorEGLVersion;
+
+ QScreen *screen;
+
+private:
+ HybridScreen *q_ptr;
+};
+
+HybridScreenPrivate::HybridScreenPrivate(HybridScreen *owner)
+ : display(EGL_NO_DISPLAY), majorEGLVersion(0), minorEGLVersion(0),
+ screen(0), q_ptr(owner)
+{
+}
+
+HybridScreen::HybridScreen(int displayId)
+ : QGLScreen(displayId)
+{
+ d_ptr = new HybridScreenPrivate(this);
+}
+
+HybridScreen::~HybridScreen()
+{
+ delete d_ptr;
+}
+
+static void error(const char *message)
+{
+ const EGLint error = eglGetError();
+ qWarning("HybridScreen error: %s: 0x%x", message, error);
+}
+
+static int getDisplayId(const QString &spec)
+{
+ QRegExp regexp(QLatin1String(":(\\d+)\\b"));
+ if (regexp.lastIndexIn(spec) != -1) {
+ const QString capture = regexp.cap(1);
+ return capture.toInt();
+ }
+ return 0;
+}
+
+bool HybridScreen::connect(const QString &displaySpec)
+{
+ QString dspec = displaySpec;
+ if (dspec.startsWith(QLatin1String("hybrid:"), Qt::CaseInsensitive))
+ dspec = dspec.mid(QString(QLatin1String("hybrid:")).size());
+ else if (dspec.compare(QLatin1String("hybrid"), Qt::CaseInsensitive) == 0)
+ dspec = QString();
+
+ const QString displayIdSpec = QString(QLatin1String(" :%1")).arg(displayId);
+ if (dspec.endsWith(displayIdSpec))
+ dspec = dspec.left(dspec.size() - displayIdSpec.size());
+
+ const QStringList args = dspec.split(QLatin1Char(':'),
+ QString::SkipEmptyParts);
+ const int id = getDisplayId(dspec);
+ d_ptr->screen = qt_get_screen(id, dspec.toLatin1().constData());
+
+ const QScreen *screen = d_ptr->screen;
+ d = screen->depth();
+ w = screen->width();
+ h = screen->height();
+ dw = screen->deviceWidth();
+ dh = screen->deviceHeight();
+ lstep = screen->linestep();
+ data = screen->base();
+ physWidth = screen->physicalWidth();
+ physHeight = screen->physicalHeight();
+ setPixelFormat(screen->pixelFormat());
+ setOffset(screen->offset());
+
+ d_ptr->verbose = args.contains(QLatin1String("verbose"));
+
+ d_ptr->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (d_ptr->display == EGL_NO_DISPLAY) {
+ error("getting display");
+ return false;
+ }
+
+ EGLBoolean status;
+ status = eglInitialize(d_ptr->display,
+ &d_ptr->majorEGLVersion, &d_ptr->minorEGLVersion);
+ if (!status) {
+ error("eglInitialize");
+ return false;
+ }
+ if (d_ptr->verbose) {
+ qDebug("Detected EGL version %d.%d",
+ d_ptr->majorEGLVersion, d_ptr->minorEGLVersion);
+
+ EGLint numConfigs = 0;
+ eglGetConfigs(d_ptr->display, 0, 0, &numConfigs);
+ qDebug("%d available configurations", numConfigs);
+ }
+
+ // XXX: hw: use eglQueryString to find supported APIs
+
+ qt_screen = this; // XXX
+
+ return true;
+}
+
+bool HybridScreen::initDevice()
+{
+ if (d_ptr->screen)
+ return d_ptr->screen->initDevice();
+ return false;
+}
+
+void HybridScreen::shutdownDevice()
+{
+ if (d_ptr->screen)
+ d_ptr->screen->shutdownDevice();
+}
+
+void HybridScreen::disconnect()
+{
+ if (!eglTerminate(d_ptr->display))
+ error("disconnecting");
+ if (d_ptr->screen) {
+ d_ptr->screen->disconnect();
+ delete d_ptr->screen;
+ d_ptr->screen = 0;
+ }
+
+}
+
+bool HybridScreen::hasOpenGLOverlays() const
+{
+ return true;
+}
+
+bool HybridScreen::chooseContext(QGLContext *context,
+ const QGLContext *shareContext)
+{
+#if 0
+ // hw: update the glFormat variable. Probably needs a setter in the
+ // QGLWindowSurface class which can be a friend of whatever it wants.
+
+ GLint res;
+ eglGetConfigAttrib(d_ptr->display, d_ptr->config, EGL_LEVEL, &res);
+ d_ptr->glFormat.setPlane(res);
+ QT_EGL_ERR("eglGetConfigAttrib");
+
+ /*
+ if(deviceIsPixmap())
+ res = 0;
+ else
+ eglDescribePixelFormat(fmt, EGL_DOUBLEBUFFER, &res);
+ d_ptr->glFormat.setDoubleBuffer(res);
+ */
+
+ eglGetConfigAttrib(d_ptr->display, d_ptr->config, EGL_DEPTH_SIZE, &res);
+ d_ptr->glFormat.setDepth(res);
+ if (d_ptr->glFormat.depth())
+ d_ptr->glFormat.setDepthBufferSize(res);
+
+ //eglGetConfigAttrib(d_ptr->display,d_ptr->config, EGL_RGBA, &res);
+ //d_ptr->glFormat.setRgba(res);
+
+ eglGetConfigAttrib(d_ptr->display, d_ptr->config, EGL_ALPHA_SIZE, &res);
+ d_ptr->glFormat.setAlpha(res);
+ if (d_ptr->glFormat.alpha())
+ d_ptr->glFormat.setAlphaBufferSize(res);
+
+ //eglGetConfigAttrib(d_ptr->display,d_ptr->config, EGL_ACCUM_RED_SIZE, &res);
+ //d_ptr->glFormat.setAccum(res);
+ //if (d_ptr->glFormat.accum())
+ // d_ptr->glFormat.setAccumBufferSize(res);
+
+ eglGetConfigAttrib(d_ptr->display, d_ptr->config, EGL_STENCIL_SIZE, &res);
+ d_ptr->glFormat.setStencil(res);
+ if (d_ptr->glFormat.stencil())
+ d_ptr->glFormat.setStencilBufferSize(res);
+
+ //eglGetConfigAttrib(d_ptr->display, d_ptr->config, EGL_STEREO, &res);
+ //d_ptr->glFormat.setStereo(res);
+
+ eglGetConfigAttrib(d_ptr->display, d_ptr->config, EGL_SAMPLE_BUFFERS, &res);
+ d_ptr->glFormat.setSampleBuffers(res);
+
+ if (d_ptr->glFormat.sampleBuffers()) {
+ eglGetConfigAttrib(d_ptr->display, d_ptr->config, EGL_SAMPLES, &res);
+ d_ptr->glFormat.setSamples(res);
+ }
+#endif
+
+ // hw: TODO: implement sharing of contexts
+
+#if 0
+ if(shareContext &&
+ (!shareContext->isValid() || !shareContext->d_func()->cx)) {
+ qWarning("QGLContext::chooseContext(): Cannot share with invalid context");
+ shareContext = 0;
+ }
+#endif
+
+#if 0
+ d_ptr->cx = ctx;
+ if (shareContext && shareContext->d_func()->cx) {
+ QGLContext *share = const_cast<QGLContext *>(shareContext);
+ d_ptr->sharing = true;
+ share->d_func()->sharing = true;
+ }
+#endif
+
+#if 0
+ // vblank syncing
+ GLint interval = d_ptr->reqFormat.swapInterval();
+ if (interval != -1) {
+ if (interval != 0)
+ eglSwapInterval(d_ptr->display, interval);
+ }
+#endif
+
+ return QGLScreen::chooseContext(context, shareContext);
+}
+
+void HybridScreen::setDirty(const QRect& rect)
+{
+ d_ptr->screen->setDirty(rect);
+}
+
+void HybridScreen::setMode(int w, int h, int d)
+{
+ d_ptr->screen->setMode(w, h, d);
+ setDirty(region().boundingRect());
+}
+
+bool HybridScreen::supportsDepth(int depth) const
+{
+ return d_ptr->screen->supportsDepth(depth);
+}
+
+void HybridScreen::save()
+{
+ d_ptr->screen->save();
+}
+
+void HybridScreen::restore()
+{
+ d_ptr->screen->restore();
+}
+
+void HybridScreen::blank(bool on)
+{
+ d_ptr->screen->blank(on);
+}
+
+bool HybridScreen::onCard(const unsigned char *ptr) const
+{
+ return d_ptr->screen->onCard(ptr);
+}
+
+bool HybridScreen::onCard(const unsigned char *ptr, ulong &offset) const
+{
+ return d_ptr->screen->onCard(ptr, offset);
+}
+
+bool HybridScreen::isInterlaced() const
+{
+ return d_ptr->screen->isInterlaced();
+}
+
+int HybridScreen::memoryNeeded(const QString &str)
+{
+ return d_ptr->screen->memoryNeeded(str);
+}
+
+int HybridScreen::sharedRamSize(void *ptr)
+{
+ return d_ptr->screen->sharedRamSize(ptr);
+}
+
+void HybridScreen::haltUpdates()
+{
+ d_ptr->screen->haltUpdates();
+}
+
+void HybridScreen::resumeUpdates()
+{
+ d_ptr->screen->resumeUpdates();
+}
+
+void HybridScreen::exposeRegion(QRegion r, int changing)
+{
+ d_ptr->screen->exposeRegion(r, changing);
+}
+
+void HybridScreen::blit(const QImage &img, const QPoint &topLeft, const QRegion &region)
+{
+ d_ptr->screen->blit(img, topLeft, region);
+}
+
+void HybridScreen::solidFill(const QColor &color, const QRegion &region)
+{
+ d_ptr->screen->solidFill(color, region);
+}
+
+QWSWindowSurface* HybridScreen::createSurface(QWidget *widget) const
+{
+ if (qobject_cast<QGLWidget*>(widget))
+ return new HybridSurface(widget, d_ptr->display);
+ return d_ptr->screen->createSurface(widget);
+}
+
+QWSWindowSurface* HybridScreen::createSurface(const QString &key) const
+{
+ if (key == QLatin1String("hybrid"))
+ return new HybridSurface;
+ return d_ptr->screen->createSurface(key);
+}
+
+QList<QScreen*> HybridScreen::subScreens() const
+{
+ return d_ptr->screen->subScreens();
+}
+
+QRegion HybridScreen::region() const
+{
+ return d_ptr->screen->region();
+}
diff --git a/src/plugins/gfxdrivers/hybrid/hybridscreen.h b/src/plugins/gfxdrivers/hybrid/hybridscreen.h
new file mode 100644
index 0000000..d463e12
--- /dev/null
+++ b/src/plugins/gfxdrivers/hybrid/hybridscreen.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HYBRIDSCREEN_H
+#define HYBRIDSCREEN_H
+
+#include <QtOpenGL/QGLScreen>
+
+class HybridScreenPrivate;
+
+class HybridScreen : public QGLScreen
+{
+public:
+ HybridScreen(int displayId);
+ ~HybridScreen();
+
+ bool hasOpenGLOverlays() const;
+
+ bool chooseContext(QGLContext *context, const QGLContext *shareContext);
+ bool hasOpenGL() { return true; }
+
+ bool initDevice();
+ bool connect(const QString &displaySpec);
+ void disconnect();
+ void shutdownDevice();
+ void setMode(int,int,int);
+ bool supportsDepth(int) const;
+
+ void save();
+ void restore();
+ void blank(bool on);
+
+ bool onCard(const unsigned char *) const;
+ bool onCard(const unsigned char *, ulong& out_offset) const;
+
+ bool isInterlaced() const;
+
+ int memoryNeeded(const QString&);
+ int sharedRamSize(void *);
+
+ void haltUpdates();
+ void resumeUpdates();
+
+ void exposeRegion(QRegion r, int changing);
+
+ void blit(const QImage &img, const QPoint &topLeft, const QRegion &region);
+ void solidFill(const QColor &color, const QRegion &region);
+ void setDirty(const QRect&);
+
+ QWSWindowSurface* createSurface(QWidget *widget) const;
+ QWSWindowSurface* createSurface(const QString &key) const;
+
+ QList<QScreen*> subScreens() const;
+ QRegion region() const;
+private:
+ HybridScreenPrivate *d_ptr;
+};
+
+#endif // HYBRIDSCREEN_H
diff --git a/src/plugins/gfxdrivers/hybrid/hybridsurface.cpp b/src/plugins/gfxdrivers/hybrid/hybridsurface.cpp
new file mode 100644
index 0000000..7281328
--- /dev/null
+++ b/src/plugins/gfxdrivers/hybrid/hybridsurface.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "hybridsurface.h"
+
+#include <private/qwindowsurface_qws_p.h>
+#include <private/qwslock_p.h>
+#include <qscreen_qws.h>
+#include <qvarlengtharray.h>
+
+static void error(const char *message)
+{
+ const EGLint error = eglGetError();
+ qWarning("HybridSurface error: %s: 0x%x", message, error);
+}
+
+static void imgToVanilla(const QImage *img, VanillaPixmap *pix)
+{
+ pix->width = img->width();
+ pix->height = img->height();
+ pix->stride = img->bytesPerLine();
+
+ if (img->depth() == 32) {
+ pix->rSize = pix->gSize = pix->bSize = pix->aSize = 8;
+ pix->lSize = 0;
+ pix->rOffset = 16;
+ pix->gOffset = 8;
+ pix->bOffset = 0;
+ pix->aOffset = 24;
+ } else if (img->format() == QImage::Format_RGB16) {
+ pix->rSize = 5;
+ pix->gSize = 6;
+ pix->bSize = 5;
+ pix->aSize = 0;
+ pix->lSize = 0;
+ pix->rOffset = 11;
+ pix->gOffset = 5;
+ pix->bOffset = 0;
+ pix->aOffset = 0;
+ }
+
+ pix->padding = pix->padding2 = 0;
+ pix->pixels = const_cast<uchar*>(img->bits());
+}
+
+HybridSurface::HybridSurface()
+ : QWSGLWindowSurface(), memlock(0)
+{
+ setSurfaceFlags(Buffered | Opaque);
+}
+
+HybridSurface::HybridSurface(QWidget *w, EGLDisplay disp)
+ : QWSGLWindowSurface(w), memlock(0), display(disp), config(0),
+ surface(EGL_NO_SURFACE), context(EGL_NO_CONTEXT),
+ pdevice(new QWSGLPaintDevice(w))
+{
+ setSurfaceFlags(Buffered | Opaque);
+
+ EGLint configAttribs[] = {
+ EGL_RED_SIZE, 0,
+ EGL_GREEN_SIZE, 0,
+ EGL_BLUE_SIZE, 0,
+ EGL_ALPHA_SIZE, 0,
+ EGL_DEPTH_SIZE, 0,
+ EGL_STENCIL_SIZE, EGL_DONT_CARE,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_NONE, EGL_NONE
+ };
+
+
+ EGLBoolean status;
+ EGLint numConfigs;
+ status = eglChooseConfig(display, configAttribs, 0, 0, &numConfigs);
+ if (!status) {
+ error("chooseConfig");
+ return;
+ }
+
+ //If there isn't any configuration good enough
+ if (numConfigs < 1) {
+ error("chooseConfig, no matching configurations found");
+ return;
+ }
+
+ QVarLengthArray<EGLConfig> configs(numConfigs);
+
+ status = eglChooseConfig(display, configAttribs, configs.data(),
+ numConfigs, &numConfigs);
+ if (!status) {
+ error("chooseConfig");
+ return;
+ }
+
+ // hw: if used on an image buffer we need to check whether the resulting
+ // configuration matches our requirements exactly!
+ config = configs[0];
+
+ context = eglCreateContext(display, config, 0, 0);
+ //(shareContext ? shareContext->d_func()->cx : 0),
+ //configAttribs);
+ if (context == EGL_NO_CONTEXT)
+ error("eglCreateContext");
+
+}
+
+HybridSurface::~HybridSurface()
+{
+}
+
+bool HybridSurface::isValid() const
+{
+ return true;
+}
+
+void HybridSurface::setGeometry(const QRect &rect, const QRegion &mask)
+{
+ const QSize size = rect.size();
+ if (img.size() != size) {
+// QWidget *win = window();
+ QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied;
+ const int bytesPerPixel = 4;
+
+ const int bpl = (size.width() * bytesPerPixel + 3) & ~3;
+ const int imagesize = bpl * size.height();
+
+ if (imagesize == 0) {
+ eglDestroySurface(display, surface);
+ mem.detach();
+ img = QImage();
+ } else {
+ mem.detach();
+ if (!mem.create(imagesize)) {
+ perror("HybridSurface::setGeometry allocating shared memory");
+ qFatal("Error creating shared memory of size %d", imagesize);
+ }
+ uchar *base = static_cast<uchar*>(mem.address());
+ img = QImage(base, size.width(), size.height(), imageFormat);
+// setImageMetrics(img, win);
+
+ imgToVanilla(&img, &vanillaPix);
+ surface = eglCreatePixmapSurface(display, config, &vanillaPix, 0);
+ if (surface == EGL_NO_SURFACE)
+ error("setGeometry:eglCreatePixmapSurface");
+
+ }
+ }
+ QWSWindowSurface::setGeometry(rect, mask);
+}
+
+QByteArray HybridSurface::permanentState() const
+{
+ QByteArray array;
+ array.resize(4 * sizeof(int) + sizeof(QImage::Format) +
+ sizeof(SurfaceFlags));
+
+ char *ptr = array.data();
+
+ reinterpret_cast<int*>(ptr)[0] = mem.id();
+ reinterpret_cast<int*>(ptr)[1] = img.width();
+ reinterpret_cast<int*>(ptr)[2] = img.height();
+ reinterpret_cast<int*>(ptr)[3] = (memlock ? memlock->id() : -1);
+ ptr += 4 * sizeof(int);
+
+ *reinterpret_cast<QImage::Format*>(ptr) = img.format();
+ ptr += sizeof(QImage::Format);
+
+ *reinterpret_cast<SurfaceFlags*>(ptr) = surfaceFlags();
+
+ return array;
+}
+
+void HybridSurface::setPermanentState(const QByteArray &data)
+{
+ int memId;
+ int width;
+ int height;
+ int lockId;
+ QImage::Format format;
+ SurfaceFlags flags;
+
+ const char *ptr = data.constData();
+
+ memId = reinterpret_cast<const int*>(ptr)[0];
+ width = reinterpret_cast<const int*>(ptr)[1];
+ height = reinterpret_cast<const int*>(ptr)[2];
+ lockId = reinterpret_cast<const int*>(ptr)[3];
+ ptr += 4 * sizeof(int);
+
+ format = *reinterpret_cast<const QImage::Format*>(ptr);
+ ptr += sizeof(QImage::Format);
+ flags = *reinterpret_cast<const SurfaceFlags*>(ptr);
+
+ setSurfaceFlags(flags);
+
+// setMemory(memId);
+ if (mem.id() != memId) {
+ mem.detach();
+ if (!mem.attach(memId)) {
+ perror("QWSSharedMemSurface: attaching to shared memory");
+ qCritical("QWSSharedMemSurface: Error attaching to"
+ " shared memory 0x%x", memId);
+ }
+ }
+
+// setLock(lockId);
+ if (!memlock || memlock->id() == lockId) {
+ delete memlock;
+ memlock = (lockId == -1 ? 0 : new QWSLock(lockId));
+ }
+
+ uchar *base = static_cast<uchar*>(mem.address());
+ img = QImage(base, width, height, format);
+}
+
+QImage HybridSurface::image() const
+{
+ return img;
+}
+
+QPaintDevice* HybridSurface::paintDevice()
+{
+ return pdevice;
+}
+
+void HybridSurface::beginPaint(const QRegion &region)
+{
+ QWSGLWindowSurface::beginPaint(region);
+ eglBindAPI(EGL_OPENGL_ES_API);
+
+ EGLBoolean ok = eglMakeCurrent(display, surface, surface, context);
+ if (!ok)
+ error("qglMakeCurrent");
+}
+
+bool HybridSurface::lock(int timeout)
+{
+ Q_UNUSED(timeout);
+ if (!memlock)
+ return true;
+ return memlock->lock(QWSLock::BackingStore);
+}
+
+void HybridSurface::unlock()
+{
+ if (memlock)
+ memlock->unlock(QWSLock::BackingStore);
+}
+
+QPoint HybridSurface::painterOffset() const
+{
+ const QWidget *w = window();
+ if (!w)
+ return QPoint();
+
+ if (w->mask().isEmpty())
+ return QWSWindowSurface::painterOffset();
+
+ const QRegion region = w->mask()
+ & w->frameGeometry().translated(-w->geometry().topLeft());
+ return -region.boundingRect().topLeft();
+}
+
diff --git a/src/plugins/gfxdrivers/hybrid/hybridsurface.h b/src/plugins/gfxdrivers/hybrid/hybridsurface.h
new file mode 100644
index 0000000..d9be3b6
--- /dev/null
+++ b/src/plugins/gfxdrivers/hybrid/hybridsurface.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HYBRIDSURFACE_H
+#define HYBRIDSURFACE_H
+
+#include <private/qglwindowsurface_qws_p.h>
+#include <private/qglpaintdevice_qws_p.h>
+#include <GLES/egl.h>
+#include <vanilla/eglVanilla.h>
+#include <private/qwssharedmemory_p.h>
+
+class HybridPaintDevice;
+class HybridSurfacePrivate;
+class QWSLock;
+
+class HybridSurface : public QWSGLWindowSurface
+{
+public:
+ HybridSurface();
+ HybridSurface(QWidget *w, EGLDisplay display);
+ ~HybridSurface();
+
+ void beginPaint(const QRegion &region);
+ bool lock(int timeout);
+ void unlock();
+
+ bool isValid() const;
+ void setGeometry(const QRect &rect, const QRegion &mask);
+ QString key() const { return QLatin1String("hybrid"); }
+
+ QByteArray permanentState() const;
+ void setPermanentState(const QByteArray &state);
+
+ QImage image() const;
+ QPaintDevice *paintDevice();
+ QPoint painterOffset() const;
+
+private:
+ QWSSharedMemory mem;
+ QImage img;
+ QWSLock *memlock;
+ EGLDisplay display;
+ EGLConfig config;
+ EGLSurface surface;
+ EGLContext context;
+ QWSGLPaintDevice *pdevice;
+
+ VanillaPixmap vanillaPix;
+};
+
+#endif // HYBRIDSURFACE_H