summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason McDonald <jason.mcdonald@nokia.com>2009-11-02 03:04:22 (GMT)
committerJason McDonald <jason.mcdonald@nokia.com>2009-11-02 03:04:22 (GMT)
commitd8251a83c274dfafc14227cfed52a1afc32a0f1a (patch)
treef07e5b62329383609a24cd07bc79ce1a05a7fd8d
parent8d1a520f2683289647f95d5661a31324f87f0b55 (diff)
parent0dc3e7f6b482d359b10bfe4e0a3032644b77c94b (diff)
downloadQt-d8251a83c274dfafc14227cfed52a1afc32a0f1a.zip
Qt-d8251a83c274dfafc14227cfed52a1afc32a0f1a.tar.gz
Qt-d8251a83c274dfafc14227cfed52a1afc32a0f1a.tar.bz2
Merge branch '4.5' of git@scm.dev.nokia.troll.no:qt/qt into 4.5
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c72
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h18
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h1
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c14
-rw-r--r--src/plugins/gfxdrivers/powervr/README12
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp67
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h9
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp54
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h8
9 files changed, 167 insertions, 88 deletions
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c
index ac9dc8d..a9c22ef 100644
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c
+++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c
@@ -617,6 +617,16 @@ void pvrQwsGetGeometry(PvrQwsDrawable *drawable, PvrQwsRect *rect)
*rect = drawable->rect;
}
+void pvrQwsSetRotation(PvrQwsDrawable *drawable, int angle)
+{
+ if (drawable->rotationAngle != angle) {
+ drawable->rotationAngle = angle;
+
+ /* Force the buffers to be recreated if the rotation angle changes */
+ pvrQwsInvalidateBuffers(drawable);
+ }
+}
+
int pvrQwsGetStride(PvrQwsDrawable *drawable)
{
if (drawable->backBuffersValid)
@@ -652,7 +662,7 @@ int pvrQwsAllocBuffers(PvrQwsDrawable *drawable)
PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
}
}
- drawable->stridePixels = (drawable->rect.width + 7) & ~7;
+ drawable->stridePixels = (drawable->rect.width + 31) & ~31;
drawable->strideBytes =
drawable->stridePixels *
pvrQwsDisplay.screens[drawable->screen].bytesPerPixel;
@@ -818,63 +828,3 @@ void pvrQwsSetSwapFunction
drawable->swapFunction = func;
drawable->userData = userData;
}
-
-unsigned long pvrQwsGetMemoryId(PvrQwsDrawable *drawable)
-{
- unsigned long addr;
- unsigned long start;
- unsigned long end;
- unsigned long off;
- unsigned long offset;
- FILE *file;
- char buffer[BUFSIZ];
- char flags[16];
-
- if (!drawable->backBuffersValid)
- return 0;
- addr = (unsigned long)
- (drawable->backBuffers[drawable->currentBackBuffer]->pBase);
-
- /* Search /proc/self/maps for the memory region that contains "addr".
- The file offset for that memory region is the identifier we need */
- file = fopen("/proc/self/maps", "r");
- if (!file) {
- perror("/proc/self/maps");
- return 0;
- }
- offset = 0;
- while (fgets(buffer, sizeof(buffer), file)) {
- if (sscanf(buffer, "%lx-%lx %s %lx",
- &start, &end, flags, &off) < 4)
- continue;
- if (start <= addr && addr < end) {
- offset = off;
- break;
- }
- }
- fclose(file);
- return offset;
-}
-
-void *pvrQwsMapMemory(unsigned long id, int size)
-{
- void *addr;
- int fd = open("/dev/pvrsrv", O_RDWR, 0);
- if (fd < 0) {
- perror("/dev/pvrsrv");
- return 0;
- }
- addr = mmap(0, (size_t)size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, (off_t)id);
- if (addr == (void *)(-1)) {
- perror("mmap pvr memory region");
- addr = 0;
- }
- close(fd);
- return addr;
-}
-
-void pvrQwsUnmapMemory(void *addr, int size)
-{
- munmap(addr, size);
-}
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h
index 952ff6f..55e0310 100644
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h
+++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h
@@ -126,6 +126,9 @@ void pvrQwsSetGeometry(PvrQwsDrawable *drawable, const PvrQwsRect *rect);
/* Get the current geometry for a drawable */
void pvrQwsGetGeometry(PvrQwsDrawable *drawable, PvrQwsRect *rect);
+/* Set the rotation angle in degrees */
+void pvrQwsSetRotation(PvrQwsDrawable *drawable, int angle);
+
/* Get the line stride for a drawable. Returns zero if the buffers
are not allocated or have been invalidated */
int pvrQwsGetStride(PvrQwsDrawable *drawable);
@@ -159,21 +162,6 @@ int pvrQwsSwapBuffers(PvrQwsDrawable *drawable, int repaintOnly);
void pvrQwsSetSwapFunction
(PvrQwsDrawable *drawable, PvrQwsSwapFunction func, void *userData);
-/* Get a memory identifier for the indicated drawable's buffer.
- The identifier can be passed to another process and then
- passed to pvrQwsMapMemory() to map the drawable's buffer into
- the other process's address space. Returns zero if the
- memory identifier could not be determined. This should only
- be used for pixmap drawables */
-unsigned long pvrQwsGetMemoryId(PvrQwsDrawable *drawable);
-
-/* Map the memory buffer of a foreign application's drawable, as
- indicated by "id" and "size". Returns null if the map failed */
-void *pvrQwsMapMemory(unsigned long id, int size);
-
-/* Unmap the memory obtained from pvrQwsMapMemory() */
-void pvrQwsUnmapMemory(void *addr, int size);
-
#ifdef __cplusplus
};
#endif
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h
index cf80a90..dcd4e4f 100644
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h
+++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h
@@ -114,6 +114,7 @@ struct _PvrQwsDrawable
int isFullScreen;
int strideBytes;
int stridePixels;
+ int rotationAngle;
PvrQwsSwapFunction swapFunction;
void *userData;
PvrQwsDrawable *nextWinId;
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c
index 253f39f..28b2251 100644
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c
+++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c
@@ -132,6 +132,16 @@ static WSEGLError wseglCloseDisplay(WSEGLDisplayHandle display)
return WSEGL_SUCCESS;
}
+static WSEGLRotationAngle wseglRotationValue(int degrees)
+{
+ switch (degrees) {
+ case 90: return WSEGL_ROTATE_90;
+ case 180: return WSEGL_ROTATE_180;
+ case 270: return WSEGL_ROTATE_270;
+ default: return WSEGL_ROTATE_0;
+ }
+}
+
/* Create the WSEGL drawable version of a native window */
static WSEGLError wseglCreateWindowDrawable
(WSEGLDisplayHandle display, WSEGLConfig *config,
@@ -152,7 +162,7 @@ static WSEGLError wseglCreateWindowDrawable
*drawable = (WSEGLDrawableHandle)screen;
if (!pvrQwsAllocBuffers(screen))
return WSEGL_OUT_OF_MEMORY;
- *rotationAngle = WSEGL_ROTATE_0;
+ *rotationAngle = wseglRotationValue(screen->rotationAngle);
return WSEGL_SUCCESS;
}
@@ -163,7 +173,7 @@ static WSEGLError wseglCreateWindowDrawable
/* The drawable is ready to go */
*drawable = (WSEGLDrawableHandle)draw;
- *rotationAngle = WSEGL_ROTATE_0;
+ *rotationAngle = wseglRotationValue(draw->rotationAngle);
if (!pvrQwsAllocBuffers(draw))
return WSEGL_OUT_OF_MEMORY;
return WSEGL_SUCCESS;
diff --git a/src/plugins/gfxdrivers/powervr/README b/src/plugins/gfxdrivers/powervr/README
index 4dce87f..513e7f5 100644
--- a/src/plugins/gfxdrivers/powervr/README
+++ b/src/plugins/gfxdrivers/powervr/README
@@ -31,9 +31,10 @@ strictly Unix-style markers.
* IMPORTANT: To build the QScreen plugin and the WSEGL library it depends *
* on, the pvr2d.h, wsegl.h headers for your platform are required. You *
* can find a copy of these headers in src/3rdparty/powervr for SGX based *
-* platforms like the TI OMAP3xxx. They may also work on MBX platforms too *
-* depending on how old your libEGL is. You can tell Qt where to find *
-* these headers by setting QMAKE_INCDIR_POWERVR in the mkspec. *
+* platforms like the TI OMAP3xxx. They probably will not work on MBX *
+* because of differences in the layout of certain PVR2D structures. *
+* You can tell Qt where to find the actual headers for your system by *
+* setting QMAKE_INCDIR_POWERVR in the mkspec. *
***************************************************************************
When you start a Qt/Embedded application, you should modify the QWS_DISPLAY
@@ -51,6 +52,11 @@ on the device with:
hellogl_es -qws
+The driver also supports screen rotation if Qt is configured with the
+-qt-gfx-transformed option and the QWS_DISPLAY variable is wrapped in a
+"Transformed" declaration:
+
+ Transformed:powervr:mmWidth40:mmHeight54:Rot90:0
Know Issues:
* A QGLWidget may not have window decorations if it is a top-level window.
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
index 6696672..2e4c6d1 100644
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
+++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
@@ -44,6 +44,9 @@
#include "pvrqwsdrawable_p.h"
#include <QRegExp>
#include <qwindowsystem_qws.h>
+#ifndef QT_NO_QWS_TRANSFORMED
+#include <qscreentransformed_qws.h>
+#endif
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/kd.h>
@@ -60,6 +63,7 @@ PvrEglScreen::PvrEglScreen(int displayId)
ttyfd = -1;
doGraphicsMode = true;
oldKdMode = KD_TEXT;
+ parent = 0;
// Make sure that the EGL layer is initialized and the drivers loaded.
EGLDisplay dpy = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
@@ -189,7 +193,7 @@ bool PvrEglScreen::hasOpenGL()
QWSWindowSurface* PvrEglScreen::createSurface(QWidget *widget) const
{
if (qobject_cast<QGLWidget*>(widget))
- return new PvrEglWindowSurface(widget, (QScreen *)this, displayId);
+ return new PvrEglWindowSurface(widget, (PvrEglScreen *)this, displayId);
return QScreen::createSurface(widget);
}
@@ -202,6 +206,67 @@ QWSWindowSurface* PvrEglScreen::createSurface(const QString &key) const
return QScreen::createSurface(key);
}
+#ifndef QT_NO_QWS_TRANSFORMED
+
+static const QScreen *parentScreen
+ (const QScreen *current, const QScreen *lookingFor)
+{
+ if (!current)
+ return 0;
+ switch (current->classId()) {
+ case QScreen::ProxyClass:
+ case QScreen::TransformedClass: {
+ const QScreen *child =
+ static_cast<const QProxyScreen *>(current)->screen();
+ if (child == lookingFor)
+ return current;
+ else
+ return parentScreen(child, lookingFor);
+ }
+ // Not reached.
+
+ case QScreen::MultiClass: {
+ QList<QScreen *> screens = current->subScreens();
+ foreach (QScreen *screen, screens) {
+ if (screen == lookingFor)
+ return current;
+ const QScreen *parent = parentScreen(screen, lookingFor);
+ if (parent)
+ return parent;
+ }
+ }
+ break;
+
+ default: break;
+ }
+ return 0;
+}
+
+int PvrEglScreen::transformation() const
+{
+ // We need to search for our parent screen, which is assumed to be
+ // "Transformed". If it isn't, then there is no transformation.
+ // There is no direct method to get the parent screen so we need
+ // to search every screen until we find ourselves.
+ if (!parent && qt_screen != this)
+ parent = parentScreen(qt_screen, this);
+ if (!parent)
+ return 0;
+ if (parent->classId() != QScreen::TransformedClass)
+ return 0;
+ return 90 * static_cast<const QTransformedScreen *>(parent)
+ ->transformation();
+}
+
+#else
+
+int PvrEglScreen::transformation() const
+{
+ return 0;
+}
+
+#endif
+
void PvrEglScreen::sync()
{
// Put code here to synchronize 2D and 3D operations if necessary.
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h
index 8bf42c7..5769e70 100644
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h
+++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h
@@ -46,16 +46,18 @@
#include <QGLScreen>
#include "pvrqwsdrawable.h"
+class PvrEglScreen;
+
class PvrEglScreenSurfaceFunctions : public QGLScreenSurfaceFunctions
{
public:
- PvrEglScreenSurfaceFunctions(QScreen *s, int screenNum)
+ PvrEglScreenSurfaceFunctions(PvrEglScreen *s, int screenNum)
: screen(s), displayId(screenNum) {}
bool createNativeWindow(QWidget *widget, EGLNativeWindowType *native);
private:
- QScreen *screen;
+ PvrEglScreen *screen;
int displayId;
};
@@ -80,6 +82,8 @@ public:
QWSWindowSurface* createSurface(QWidget *widget) const;
QWSWindowSurface* createSurface(const QString &key) const;
+ int transformation() const;
+
private:
void sync();
void openTty();
@@ -89,6 +93,7 @@ private:
int ttyfd, oldKdMode;
QString ttyDevice;
bool doGraphicsMode;
+ mutable const QScreen *parent;
};
#endif
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp
index 2c5ac21..4a3787f 100644
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp
+++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp
@@ -46,7 +46,7 @@
#include <QWSDisplay>
PvrEglWindowSurface::PvrEglWindowSurface
- (QWidget *widget, QScreen *screen, int screenNum)
+ (QWidget *widget, PvrEglScreen *screen, int screenNum)
: QWSGLWindowSurface(widget)
{
setSurfaceFlags(QWSWindowSurface::Opaque);
@@ -63,6 +63,7 @@ PvrEglWindowSurface::PvrEglWindowSurface
pvrRect.y = pos.y();
pvrRect.width = size.width();
pvrRect.height = size.height();
+ transformRects(&pvrRect, 1);
// Try to recover a previous PvrQwsDrawable object for the widget
// if there is one. This can happen when a PvrEglWindowSurface
@@ -75,6 +76,7 @@ PvrEglWindowSurface::PvrEglWindowSurface
pvrQwsSetGeometry(drawable, &pvrRect);
else
drawable = pvrQwsCreateWindow(screenNum, (long)widget, &pvrRect);
+ pvrQwsSetRotation(drawable, screen->transformation());
}
PvrEglWindowSurface::PvrEglWindowSurface()
@@ -113,7 +115,9 @@ void PvrEglWindowSurface::setGeometry(const QRect &rect)
pvrRect.y = rect.y();
pvrRect.width = rect.width();
pvrRect.height = rect.height();
+ transformRects(&pvrRect, 1);
pvrQwsSetGeometry(drawable, &pvrRect);
+ pvrQwsSetRotation(drawable, screen->transformation());
}
QWSGLWindowSurface::setGeometry(rect);
}
@@ -127,7 +131,9 @@ bool PvrEglWindowSurface::move(const QPoint &offset)
pvrRect.y = rect.y();
pvrRect.width = rect.width();
pvrRect.height = rect.height();
+ transformRects(&pvrRect, 1);
pvrQwsSetGeometry(drawable, &pvrRect);
+ pvrQwsSetRotation(drawable, screen->transformation());
}
return QWSGLWindowSurface::move(offset);
}
@@ -200,7 +206,9 @@ void PvrEglWindowSurface::setDirectRegion(const QRegion &r, int id)
pvrRect.y = rect.y();
pvrRect.width = rect.width();
pvrRect.height = rect.height();
+ transformRects(&pvrRect, 1);
pvrQwsSetVisibleRegion(drawable, &pvrRect, 1);
+ pvrQwsSetRotation(drawable, screen->transformation());
if (!pvrQwsSwapBuffers(drawable, 1))
screen->solidFill(QColor(0, 0, 0), region);
} else {
@@ -213,9 +221,53 @@ void PvrEglWindowSurface::setDirectRegion(const QRegion &r, int id)
pvrRects[index].width = rect.width();
pvrRects[index].height = rect.height();
}
+ transformRects(pvrRects, rects.size());
pvrQwsSetVisibleRegion(drawable, pvrRects, rects.size());
+ pvrQwsSetRotation(drawable, screen->transformation());
if (!pvrQwsSwapBuffers(drawable, 1))
screen->solidFill(QColor(0, 0, 0), region);
delete [] pvrRects;
}
}
+
+void PvrEglWindowSurface::transformRects(PvrQwsRect *rects, int count) const
+{
+ switch (screen->transformation()) {
+ case 0: break;
+
+ case 90:
+ {
+ for (int index = 0; index < count; ++index) {
+ int x = rects[index].y;
+ int y = screen->height() - (rects[index].x + rects[index].width);
+ rects[index].x = x;
+ rects[index].y = y;
+ qSwap(rects[index].width, rects[index].height);
+ }
+ }
+ break;
+
+ case 180:
+ {
+ for (int index = 0; index < count; ++index) {
+ int x = screen->width() - (rects[index].x + rects[index].width);
+ int y = screen->height() - (rects[index].y + rects[index].height);
+ rects[index].x = x;
+ rects[index].y = y;
+ }
+ }
+ break;
+
+ case 270:
+ {
+ for (int index = 0; index < count; ++index) {
+ int x = screen->width() - (rects[index].y + rects[index].height);
+ int y = rects[index].x;
+ rects[index].x = x;
+ rects[index].y = y;
+ qSwap(rects[index].width, rects[index].height);
+ }
+ }
+ break;
+ }
+}
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h
index 58a5fb2..b0a161c 100644
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h
+++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h
@@ -45,12 +45,12 @@
#include <private/qglwindowsurface_qws_p.h>
#include "pvrqwsdrawable.h"
-class QScreen;
+class PvrEglScreen;
class PvrEglWindowSurface : public QWSGLWindowSurface
{
public:
- PvrEglWindowSurface(QWidget *widget, QScreen *screen, int screenNum);
+ PvrEglWindowSurface(QWidget *widget, PvrEglScreen *screen, int screenNum);
PvrEglWindowSurface();
~PvrEglWindowSurface();
@@ -76,8 +76,10 @@ public:
private:
QWidget *widget;
PvrQwsDrawable *drawable;
- QScreen *screen;
+ PvrEglScreen *screen;
QPaintDevice *pdevice;
+
+ void transformRects(PvrQwsRect *rects, int count) const;
};
#endif