diff options
author | Anders Bakken <anders.bakken@nokia.com> | 2009-08-28 03:37:40 (GMT) |
---|---|---|
committer | Anders Bakken <anders.bakken@nokia.com> | 2009-09-01 22:25:51 (GMT) |
commit | add57539ec7cd24346e26b22a5298da50d81e91b (patch) | |
tree | fda78f056d25bd876b7348bf732463939b9fe648 /src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | |
parent | 913a21aae513714217be233c6cecfb39212a4be8 (diff) | |
download | Qt-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.cpp | 68 |
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()) { |