summaryrefslogtreecommitdiffstats
path: root/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
diff options
context:
space:
mode:
authorAnders Bakken <anders.bakken@nokia.com>2009-08-28 03:37:40 (GMT)
committerAnders Bakken <anders.bakken@nokia.com>2009-09-01 22:25:51 (GMT)
commitadd57539ec7cd24346e26b22a5298da50d81e91b (patch)
treefda78f056d25bd876b7348bf732463939b9fe648 /src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
parent913a21aae513714217be233c6cecfb39212a4be8 (diff)
downloadQt-add57539ec7cd24346e26b22a5298da50d81e91b.zip
Qt-add57539ec7cd24346e26b22a5298da50d81e91b.tar.gz
Qt-add57539ec7cd24346e26b22a5298da50d81e91b.tar.bz2
Rewrite of DirectFB locking mechanism
DirectFB allows you to have a locked subSurface that remains valid while you paint on the unlocked "parent" surface. The only limitation is that when accessing the locked memory you might have to call DirectFB->WaitIdle() in case pending GPU operations aren't finished. After this we keep the locked surface around at all times (from the first time it's requested) until the surface dies. Previous calls to lock() will just call WaitIdle if necessary and previous calls to unlock now just mark the surface as dirty and in need of a WaitIdle if someone needs to access its pixel data. Reviewed-by: Donald Carr <donald.carr@nokia.com>
Diffstat (limited to 'src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp')
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp68
1 files changed, 39 insertions, 29 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index 984b5c6..5bad4de 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -93,6 +93,7 @@ public:
inline void lock();
inline void unlock();
+ static inline void unlock(QDirectFBPaintDevice *device);
inline bool isSimpleBrush(const QBrush &brush) const;
@@ -221,6 +222,7 @@ template <class T>
static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface);
#define CLIPPED_PAINT(operation) { \
+ d->unlock(); \
DFBRegion clipRegion; \
switch (d->clipType) { \
case QDirectFBPaintEnginePrivate::NoClip: \
@@ -268,6 +270,7 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device)
QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData();
Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
QDirectFBPixmapData *dfbPixmapData = static_cast<QDirectFBPixmapData*>(data);
+ QDirectFBPaintEnginePrivate::unlock(dfbPixmapData);
d->dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData);
}
@@ -408,7 +411,6 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
QRasterPaintEngine::drawRects(rects, rectCount);
return;
}
- d->unlock();
if (brush != Qt::NoBrush) {
d->setDFBColor(brush.color());
CLIPPED_PAINT(QT_PREPEND_NAMESPACE(fillRects<QRect>)(rects, rectCount, state()->matrix, d->surface));
@@ -437,7 +439,6 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
QRasterPaintEngine::drawRects(rects, rectCount);
return;
}
- d->unlock();
if (brush != Qt::NoBrush) {
d->setDFBColor(brush.color());
CLIPPED_PAINT(fillRects<QRectF>(rects, rectCount, state()->matrix, d->surface));
@@ -463,7 +464,6 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
const QPen &pen = state()->pen;
if (pen != Qt::NoPen) {
- d->unlock();
d->setDFBColor(pen.color());
CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface));
}
@@ -484,7 +484,6 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
const QPen &pen = state()->pen;
if (pen != Qt::NoPen) {
- d->unlock();
d->setDFBColor(pen.color());
CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface));
}
@@ -532,7 +531,6 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
return;
}
#if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
- d->unlock();
bool release;
IDirectFBSurface *imgSurface = d->getSurface(image, &release);
d->prepareForBlit(QDirectFBScreen::hasAlphaChannel(imgSurface));
@@ -560,25 +558,25 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap,
RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr);
d->lock();
QRasterPaintEngine::drawPixmap(r, pixmap, sr);
- } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || (state()->renderHints & QPainter::SmoothPixmapTransform
- && state()->matrix.mapRect(r).size() != sr.size())) {
- RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr);
- const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(DSLF_READ);
- d->lock();
- QRasterPaintEngine::drawImage(r, *img, sr);
} else {
- d->unlock();
- d->prepareForBlit(pixmap.hasAlphaChannel());
QPixmapData *data = pixmap.pixmapData();
Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- dfbData->unlockDirectFB();
- IDirectFBSurface *s = dfbData->directFBSurface();
-
- CLIPPED_PAINT(d->blit(r, s, sr));
+ if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
+ || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
+ || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
+ || (state()->renderHints & QPainter::SmoothPixmapTransform
+ && state()->matrix.mapRect(r).size() != sr.size())) {
+ RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr);
+ const QImage *img = dfbData->buffer();
+ d->lock();
+ QRasterPaintEngine::drawImage(r, *img, sr);
+ } else {
+ QDirectFBPaintEnginePrivate::unlock(dfbData);
+ d->prepareForBlit(pixmap.hasAlphaChannel());
+ IDirectFBSurface *s = dfbData->directFBSurface();
+ CLIPPED_PAINT(d->blit(r, s, sr));
+ }
}
}
@@ -601,14 +599,16 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r,
|| d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
|| (state()->renderHints & QPainter::SmoothPixmapTransform && state()->matrix.isScaling())) {
RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset);
- const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(DSLF_READ);
+ QPixmapData *pixmapData = pixmap.pixmapData();
+ Q_ASSERT(pixmapData->classId() == QPixmapData::DirectFBClass);
+ QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(pixmapData);
+ const QImage *img = dfbData->buffer();
d->lock();
QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType);
data->fromImage(*img, Qt::AutoColor);
const QPixmap pix(data);
QRasterPaintEngine::drawTiledPixmap(r, pix, offset);
} else {
- d->unlock();
CLIPPED_PAINT(d->drawTiledPixmap(r, pixmap, offset));
}
}
@@ -707,7 +707,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
const QColor color = brush.color();
if (!color.isValid())
return;
- d->unlock();
d->setDFBColor(color);
const QRect r = state()->matrix.mapRect(rect).toRect();
CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()));
@@ -724,7 +723,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
if (texture.pixmapData()->classId() != QPixmapData::DirectFBClass)
break;
- d->unlock();
CLIPPED_PAINT(d->drawTiledPixmap(rect, texture, rect.topLeft() - state()->brushOrigin));
return; }
default:
@@ -748,7 +746,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
d->lock();
QRasterPaintEngine::fillRect(rect, color);
} else {
- d->unlock();
d->setDFBColor(color);
const QRect r = state()->matrix.mapRect(rect).toRect();
CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()));
@@ -810,8 +807,7 @@ void QDirectFBPaintEnginePrivate::lock()
// lock so we need to call the base implementation of prepare so
// it updates its rasterBuffer to point to the new buffer address.
Q_ASSERT(dfbDevice);
- if (dfbDevice->lockFlags() != (DSLF_WRITE|DSLF_READ)) {
- dfbDevice->lockDirectFB(DSLF_READ|DSLF_WRITE);
+ if (dfbDevice->lockSurface(DSLF_READ|DSLF_WRITE)) {
prepare(dfbDevice);
}
}
@@ -819,7 +815,21 @@ void QDirectFBPaintEnginePrivate::lock()
void QDirectFBPaintEnginePrivate::unlock()
{
Q_ASSERT(dfbDevice);
- dfbDevice->unlockDirectFB();
+#ifdef QT_DIRECTFB_SUBSURFACE
+ dfbDevice->syncPending = true;
+#else
+ QDirectFBPaintEnginePrivate::unlock(dfbDevice);
+#endif
+}
+
+void QDirectFBPaintEnginePrivate::unlock(QDirectFBPaintDevice *device)
+{
+#ifdef QT_NO_DIRECTFB_SUBSURFACE
+ Q_ASSERT(device);
+ device->unlockSurface();
+#else
+ Q_UNUSED(device);
+#endif
}
void QDirectFBPaintEnginePrivate::setTransform(const QTransform &transform)
@@ -1030,7 +1040,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPix
QPixmapData *data = pixmap.pixmapData();
Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- dfbData->unlockDirectFB();
+ QDirectFBPaintEnginePrivate::unlock(dfbData);
const QSize pixmapSize = dfbData->size();
IDirectFBSurface *sourceSurface = dfbData->directFBSurface();
if (transform.isScaling()) {