summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@trolltech.com>2009-04-15 09:19:56 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2009-04-15 09:19:56 (GMT)
commit21099dac569348a15df2d6a5a61015b5afa17097 (patch)
treeb4ae338f206666b7f07e1f78278ad6d38609880b /src/plugins
parentf169ca1020886707b04101300e365d79f38a6332 (diff)
parent4e78de5a4281bd1c27a984b13887975798573aae (diff)
downloadQt-21099dac569348a15df2d6a5a61015b5afa17097.zip
Qt-21099dac569348a15df2d6a5a61015b5afa17097.tar.gz
Qt-21099dac569348a15df2d6a5a61015b5afa17097.tar.bz2
Merge commit 'origin/4.5'
Conflicts: src/gui/graphicsview/qgraphicsitem.cpp
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/gfxdrivers/directfb/directfb.pro1
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp279
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp171
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h7
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp106
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp64
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbsurface.h5
7 files changed, 333 insertions, 300 deletions
diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro
index 399044e..89a289c 100644
--- a/src/plugins/gfxdrivers/directfb/directfb.pro
+++ b/src/plugins/gfxdrivers/directfb/directfb.pro
@@ -13,6 +13,7 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/gfxdrivers
#DEFINES += QT_NO_DIRECTFB_MOUSE
#DEFINES += QT_NO_DIRECTFB_KEYBOARD
#DEFINES += QT_DIRECTFB_TIMING
+#DEFINES += QT_NO_DIRECTFB_OPAQUE_DETECTION
target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
INSTALLS += target
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index a93bbf7..d9346fd 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -196,10 +196,10 @@ public:
void setPen(const QPen &pen);
void setBrush(const QBrush &brush);
void setCompositionMode(QPainter::CompositionMode mode);
- void setOpacity(const qreal value);
+ void setOpacity(quint8 value);
void setRenderHints(QPainter::RenderHints hints);
- inline void setDFBColor(const QColor &color) const;
+ inline void setDFBColor(const QColor &color);
inline void lock();
inline void unlock();
@@ -222,21 +222,18 @@ public:
void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap);
void drawImage(const QRectF &dest, const QImage &image, const QRectF &src);
- void updateClip();
- void updateFlags();
+ inline void updateClip();
inline void setClipDirty();
- void systemStateChanged(); //Needed to be notified when system clip changes
+ void systemStateChanged();
void begin(QPaintDevice *device);
void end();
+ void prepareForBlit(bool alpha);
SurfaceCache *surfaceCache;
QTransform transform;
int lastLockedHeight;
private:
-// QRegion rectsToClippedRegion(const QRect *rects, int n) const;
-// QRegion rectsToClippedRegion(const QRectF *rects, int n) const;
-
IDirectFB *fb;
DFBSurfaceDescription fbDescription;
int fbWidth;
@@ -244,10 +241,9 @@ private:
quint8 opacity;
- quint32 drawFlags;
- quint32 blitFlags;
- quint32 duffFlags;
- bool dirtyFlags;
+ quint32 drawFlagsFromCompositionMode, blitFlagsFromCompositionMode;
+ DFBSurfacePorterDuffRule porterDuffRule;
+
bool dirtyClip;
bool dfbHandledClip;
QDirectFBPaintDevice *dfbDevice;
@@ -258,8 +254,9 @@ private:
QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p)
: surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false),
simpleBrush(false), matrixRotShear(false), matrixScale(false), lastLockedHeight(-1),
- fbWidth(-1), fbHeight(-1), opacity(255), drawFlags(0), blitFlags(0), duffFlags(0),
- dirtyFlags(false), dirtyClip(true), dfbHandledClip(false), dfbDevice(0), q(p)
+ fbWidth(-1), fbHeight(-1), opacity(255), drawFlagsFromCompositionMode(0),
+ blitFlagsFromCompositionMode(0), porterDuffRule(DSPD_SRC_OVER), dirtyClip(true),
+ dfbHandledClip(false), dfbDevice(0), q(p)
{
fb = QDirectFBScreen::instance()->dfb();
surfaceCache = new SurfaceCache;
@@ -295,7 +292,6 @@ void QDirectFBPaintEnginePrivate::setClipDirty()
dirtyClip = true;
}
-
void QDirectFBPaintEnginePrivate::lock()
{
// We will potentially get a new pointer to the buffer after a
@@ -345,11 +341,8 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device)
setTransform(QTransform());
antialiased = false;
- drawFlags = DSDRAW_BLEND;
- blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
- duffFlags = DSPD_SRC_OVER;
opacity = 255;
- dirtyFlags = true;
+ setCompositionMode(q->state()->compositionMode());
dirtyClip = true;
setPen(q->state()->pen);
setDFBColor(pen.color());
@@ -382,91 +375,72 @@ void QDirectFBPaintEnginePrivate::setBrush(const QBrush &b)
void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode)
{
- drawFlags &= ~(DSDRAW_XOR);
- blitFlags &= ~(DSBLIT_XOR);
-
- // TODO: check these mappings!!!!
- quint32 duff = DSPD_NONE;
- quint32 blit = blitFlags;
+ blitFlagsFromCompositionMode = DSBLIT_NOFX;
+ drawFlagsFromCompositionMode = DSDRAW_NOFX;
+ bool blend = true;
switch (mode) {
case QPainter::CompositionMode_SourceOver:
- duff = DSPD_SRC_OVER;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_SRC_OVER;
break;
case QPainter::CompositionMode_DestinationOver:
- duff = DSPD_DST_OVER;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_DST_OVER;
break;
case QPainter::CompositionMode_Clear:
- duff = DSPD_CLEAR;
- blit &= ~DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_CLEAR;
+ blend = false;
break;
case QPainter::CompositionMode_Source:
- duff = DSPD_SRC;
- blit &= ~DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_SRC;
+ blend = false;
break;
case QPainter::CompositionMode_Destination:
- blit &= ~DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_NONE; // ### need to double check this
+ blend = false;
return;
case QPainter::CompositionMode_SourceIn:
- duff = DSPD_SRC_IN;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_SRC_IN;
break;
case QPainter::CompositionMode_DestinationIn:
- duff = DSPD_DST_IN;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_DST_IN;
break;
case QPainter::CompositionMode_SourceOut:
- duff = DSPD_SRC_OUT;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_SRC_OUT;
break;
case QPainter::CompositionMode_DestinationOut:
- duff = DSPD_DST_OUT;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
- break;
- case QPainter::CompositionMode_SourceAtop:
- duff = DSPD_SRC_OVER;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
- break;
- case QPainter::CompositionMode_DestinationAtop:
- duff = DSPD_DST_OVER;
+ porterDuffRule = DSPD_DST_OUT;
break;
case QPainter::CompositionMode_Xor:
- duff = DSPD_NONE;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
- drawFlags |= DSDRAW_XOR;
- blit |= DSBLIT_XOR;
- dirtyFlags = true;
+ porterDuffRule = DSPD_XOR;
+ blitFlagsFromCompositionMode |= DSBLIT_XOR;
+ drawFlagsFromCompositionMode |= DSDRAW_XOR;
break;
+// case QPainter::CompositionMode_Plus: // ???
+// porterDuffRule = DSPD_ADD;
+// break;
default:
qWarning("QDirectFBPaintEnginePrivate::setCompositionMode(): "
"mode %d not implemented", mode);
- break;
+ return;
}
-
- if (duff != duffFlags || blit != blitFlags) {
- duffFlags = duff;
- blitFlags = blit;
- dirtyFlags = true;
+ // intentially not comparing with current porterDuffRule. surface might have changed.
+ if (blend) {
+ blitFlagsFromCompositionMode |= DSBLIT_BLEND_ALPHACHANNEL;
+ drawFlagsFromCompositionMode |= DSDRAW_BLEND;
+ }
+ if (opacity != 255) {
+ setOpacity(opacity);
}
}
-void QDirectFBPaintEnginePrivate::setOpacity(const qreal value)
+void QDirectFBPaintEnginePrivate::setOpacity(quint8 op)
{
- const bool wasOpaque = (opacity == 255);
- opacity = quint8(value * 255);
- const bool opaque = (opacity == 255);
-
- if (opaque == wasOpaque)
- return;
-
- if (opaque)
- blitFlags &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR);
- else
- blitFlags |= (DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR);
-
- dirtyFlags = true;
+ opacity = op;
+ if (opacity == 255) {
+ blitFlagsFromCompositionMode &= ~DSBLIT_BLEND_COLORALPHA;
+ } else {
+ blitFlagsFromCompositionMode |= DSBLIT_BLEND_COLORALPHA;
+ }
}
void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints)
@@ -478,81 +452,53 @@ void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints)
}
}
-void QDirectFBPaintEnginePrivate::updateFlags()
+void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha)
{
- if (!dirtyFlags)
- return;
- surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawFlags));
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags));
- surface->SetPorterDuff(surface, DFBSurfacePorterDuffRule(duffFlags));
- dirtyFlags = false;
+ quint32 blittingFlags = blitFlagsFromCompositionMode;
+ if (alpha) {
+ surface->SetPorterDuff(surface,
+ (blittingFlags & DSBLIT_BLEND_COLORALPHA)
+ ? DSPD_NONE
+ : porterDuffRule);
+ } else {
+ blittingFlags &= ~DSBLIT_BLEND_ALPHACHANNEL;
+ surface->SetPorterDuff(surface, DSPD_NONE);
+ }
+ surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
+ surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags));
}
-void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) const
+void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color)
{
+ Q_ASSERT(surface);
const quint8 alpha = (opacity == 255 ?
color.alpha() : ALPHA_MUL(color.alpha(), opacity));
surface->SetColor(surface,
color.red(), color.green(), color.blue(), alpha);
+ quint32 drawingFlags = drawFlagsFromCompositionMode;
+ if (alpha == 255) {
+ drawingFlags &= ~DSDRAW_BLEND;
+ }
+ surface->SetPorterDuff(surface, DSPD_NONE);
+ // PorterDuff messes up alpha values for primitives
+ surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawingFlags));
}
void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) const
{
- QVarLengthArray<DFBRegion> regions(n);
-
for (int i = 0; i < n; ++i) {
const QLine l = transform.map(lines[i]);
-
- regions[i].x1 = l.x1();
- regions[i].y1 = l.y1();
- regions[i].x2 = l.x2();
- regions[i].y2 = l.y2();
+ surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2());
}
- surface->DrawLines(surface, regions.data(), n);
}
void QDirectFBPaintEnginePrivate::drawLines(const QLineF *lines, int n) const
{
- QVarLengthArray<DFBRegion> regions(n);
-
for (int i = 0; i < n; ++i) {
const QLine l = transform.map(lines[i]).toLine();
-
- regions[i].x1 = l.x1();
- regions[i].y1 = l.y1();
- regions[i].x2 = l.x2();
- regions[i].y2 = l.y2();
- }
- surface->DrawLines(surface, regions.data(), n);
-}
-
-/* ### Commented out until it can be implemented properly using raster's QClipData
-QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRect *rects,
- int n) const
-{
- QRegion region;
-
- for (int i = 0; i < n; ++i) {
- const QRect r = transform.mapRect(rects[i]);
- region += clip & r;
- }
-
- return region;
-}
-
-QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRectF *rects,
- int n) const
-{
- QRegion region;
-
- for (int i = 0; i < n; ++i) {
- const QRect r = transform.mapRect(rects[i]).toRect();
- region += clip & r;
+ surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2());
}
-
- return region;
}
-*/
void QDirectFBPaintEnginePrivate::fillRegion(const QRegion &region) const
{
@@ -601,15 +547,7 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest,
const QPixmap &pixmap,
const QRectF &src)
{
- surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
-
- const bool changeFlags = !pixmap.hasAlphaChannel()
- && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL);
- if (changeFlags) {
- quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL;
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags));
- }
-
+ prepareForBlit(pixmap.hasAlphaChannel());
QPixmapData *data = pixmap.pixmapData();
Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
@@ -627,22 +565,12 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest,
}
if (result != DFB_OK)
DirectFBError("QDirectFBPaintEngine::drawPixmap()", result);
- if (changeFlags)
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags));
}
void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest,
const QPixmap &pixmap)
{
- surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
-
- const bool changeFlags = !pixmap.hasAlphaChannel()
- && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL);
- if (changeFlags) {
- quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL;
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags));
- }
-
+ prepareForBlit(pixmap.hasAlphaChannel());
QPixmapData *data = pixmap.pixmapData();
Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
@@ -688,22 +616,13 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest,
if (result != DFB_OK)
DirectFBError("QDirectFBPaintEngine::drawTiledPixmap()", result);
-
- if (changeFlags)
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags));
}
void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest,
- const QImage &srcImage,
+ const QImage &image,
const QRectF &src)
{
- QImage image = srcImage;
- if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) {
- image = image.convertToFormat(image.hasAlphaChannel()
- ? QDirectFBScreen::instance()->alphaPixmapFormat()
- : QDirectFBScreen::instance()->pixelFormat());
- }
-
+ Q_ASSERT(QDirectFBScreen::getSurfacePixelFormat(image.format()) != DSPF_UNKNOWN);
CachedImage *img = imageCache[image.cacheKey()];
IDirectFBSurface *imgSurface = 0;
bool doRelease = false;
@@ -745,14 +664,7 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest,
const QRect dr = transform.mapRect(dest).toRect();
const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() };
- surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
-
- const bool changeFlags = !image.hasAlphaChannel()
- && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL);
- if (changeFlags) {
- quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL;
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags));
- }
+ prepareForBlit(image.hasAlphaChannel());
if (dr.size() == sr.size()) {
surface->Blit(surface, imgSurface, &sRect, dr.x(), dr.y());
} else {
@@ -760,8 +672,6 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest,
dr.width(), dr.height() };
surface->StretchBlit(surface, imgSurface, &sRect, &dRect);
}
- if (changeFlags)
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags));
if (doRelease) {
surface->ReleaseSource(surface);
imgSurface->Release(imgSurface);
@@ -856,8 +766,7 @@ void QDirectFBPaintEngine::brushChanged()
void QDirectFBPaintEngine::opacityChanged()
{
Q_D(QDirectFBPaintEngine);
- d->setOpacity(state()->opacity);
-
+ d->setOpacity(quint8(state()->opacity * 255));
QRasterPaintEngine::opacityChanged();
}
@@ -865,7 +774,6 @@ void QDirectFBPaintEngine::compositionModeChanged()
{
Q_D(QDirectFBPaintEngine);
d->setCompositionMode(state()->compositionMode());
-
QRasterPaintEngine::compositionModeChanged();
}
@@ -894,7 +802,7 @@ void QDirectFBPaintEngine::setState(QPainterState *s)
d->setClipDirty();
d->setPen(state()->pen);
d->setBrush(state()->brush);
- d->setOpacity(state()->opacity);
+ d->setOpacity(quint8(state()->opacity * 255));
d->setCompositionMode(state()->compositionMode());
d->setTransform(state()->transform());
}
@@ -936,12 +844,10 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
d->unlock();
if (d->brush != Qt::NoBrush) {
- d->updateFlags();
d->setDFBColor(d->brush.color());
d->fillRects(rects, rectCount);
}
if (d->pen != Qt::NoPen) {
- d->updateFlags();
d->setDFBColor(d->pen.color());
d->drawRects(rects, rectCount);
}
@@ -961,12 +867,10 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
d->unlock();
if (d->brush != Qt::NoBrush) {
- d->updateFlags();
d->setDFBColor(d->brush.color());
d->fillRects(rects, rectCount);
}
if (d->pen != Qt::NoPen) {
- d->updateFlags();
d->setDFBColor(d->pen.color());
d->drawRects(rects, rectCount);
}
@@ -984,7 +888,6 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
if (d->pen != Qt::NoPen) {
d->unlock();
- d->updateFlags();
d->setDFBColor(d->pen.color());
d->drawLines(lines, lineCount);
}
@@ -1002,7 +905,6 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
if (d->pen != Qt::NoPen) {
d->unlock();
- d->updateFlags();
d->setDFBColor(d->pen.color());
d->drawLines(lines, lineCount);
}
@@ -1017,7 +919,8 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
#ifndef QT_NO_DIRECTFB_PREALLOCATED
d->updateClip();
- if (!d->dfbCanHandleClip(r) || d->matrixRotShear)
+ if (!d->dfbCanHandleClip(r) || d->matrixRotShear
+ || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN)
#endif
{
d->lock();
@@ -1027,7 +930,6 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
#ifndef QT_NO_DIRECTFB_PREALLOCATED
d->unlock();
- d->updateFlags();
d->drawImage(r, image, sr);
#endif
}
@@ -1046,15 +948,12 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap,
if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
d->lock();
QRasterPaintEngine::drawPixmap(r, pixmap, sr);
- }
- else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) {
+ } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) {
const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer();
d->lock();
QRasterPaintEngine::drawImage(r, *img, sr);
- }
- else {
+ } else {
d->unlock();
- d->updateFlags();
d->drawPixmap(r, pixmap, sr);
}
}
@@ -1073,18 +972,15 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r,
if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
d->lock();
QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp);
- }
- else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) {
+ } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) {
const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer();
d->lock();
QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType);
data->fromImage(*img, Qt::AutoColor);
const QPixmap pix(data);
QRasterPaintEngine::drawTiledPixmap(r, pix, sp);
- }
- else {
+ } else {
d->unlock();
- d->updateFlags();
d->drawTiledPixmap(r, pixmap);
}
}
@@ -1167,7 +1063,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
if (d->forceRasterPrimitives)
break;
d->unlock();
- d->updateFlags();
d->setDFBColor(brush.color());
const QRect r = d->transform.mapRect(rect).toRect();
d->surface->FillRectangle(d->surface, r.x(), r.y(),
@@ -1177,7 +1072,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
if (state()->brushOrigin == QPointF() && brush.transform().isIdentity()) {
//could handle certain types of brush.transform() E.g. scale
d->unlock();
- d->updateFlags();
d->drawTiledPixmap(rect, brush.texture());
return;
}
@@ -1199,7 +1093,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
QRasterPaintEngine::fillRect(rect, color);
} else {
d->unlock();
- d->updateFlags();
d->setDFBColor(color);
const QRect r = d->transform.mapRect(rect).toRect();
d->surface->FillRectangle(d->surface, r.x(), r.y(),
@@ -1229,6 +1122,7 @@ void QDirectFBPaintEngine::drawColorSpans(const QSpan *spans, int count,
} else {
DFBSpan span = { spans[i].x, spans[i].len };
uint c = BYTE_MUL(color, spans[i].coverage);
+ // ### how does this play with setDFBColor
d->surface->SetColor(d->surface,
qRed(c), qGreen(c), qBlue(c), qAlpha(c));
d->surface->FillSpans(d->surface, spans[i].y, &span, 1);
@@ -1249,6 +1143,7 @@ void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
{
Q_D(QDirectFBPaintEngine);
IDirectFBSurface *src = d->surfaceCache->getSurface(buffer, bufsize);
+ // ### how does this play with setDFBColor
src->SetColor(src, 0, 0, 0, const_alpha);
const DFBRectangle rect = { 0, 0, length, 1 };
d->surface->Blit(d->surface, src, &rect, x, y);
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index 35ab859..0a1696a 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -51,7 +51,7 @@ static int global_ser_no = 0;
QDirectFBPixmapData::QDirectFBPixmapData(PixelType pixelType)
: QPixmapData(pixelType, DirectFBClass),
- engine(0)
+ engine(0), format(QImage::Format_Invalid), alpha(false)
{
setSerialNumber(0);
}
@@ -67,16 +67,18 @@ QDirectFBPixmapData::~QDirectFBPixmapData()
void QDirectFBPixmapData::resize(int width, int height)
{
if (width <= 0 || height <= 0) {
- setSerialNumber(0);
+ invalidate();
return;
}
- dfbSurface = screen->createDFBSurface(QSize(width, height),
- screen->pixelFormat(),
- QDirectFBScreen::TrackSurface);
- forceRaster = (screen->pixelFormat() == QImage::Format_RGB32);
+ format = screen->pixelFormat();
+ dfbSurface = QDirectFBScreen::instance()->createDFBSurface(QSize(width, height),
+ format,
+ QDirectFBScreen::TrackSurface);
+ alpha = false;
+ forceRaster = (format == QImage::Format_RGB32);
if (!dfbSurface) {
- setSerialNumber(0);
+ invalidate();
qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface");
return;
}
@@ -84,18 +86,98 @@ void QDirectFBPixmapData::resize(int width, int height)
setSerialNumber(++global_ser_no);
}
+
+// mostly duplicated from qimage.cpp (QImageData::checkForAlphaPixels)
+static bool checkForAlphaPixels(const QImage &img)
+{
+ const uchar *bits = img.bits();
+ const int bytes_per_line = img.bytesPerLine();
+ const uchar *end_bits = bits + bytes_per_line;
+ const int width = img.width();
+ const int height = img.height();
+ switch (img.format()) {
+ case QImage::Format_Indexed8:
+ return img.hasAlphaChannel();
+ case QImage::Format_ARGB32:
+ case QImage::Format_ARGB32_Premultiplied:
+ for (int y=0; y<height; ++y) {
+ for (int x=0; x<width; ++x) {
+ if ((((uint *)bits)[x] & 0xff000000) != 0xff000000) {
+ return true;
+ }
+ }
+ bits += bytes_per_line;
+ }
+ break;
+
+ case QImage::Format_ARGB8555_Premultiplied:
+ case QImage::Format_ARGB8565_Premultiplied:
+ for (int y=0; y<height; ++y) {
+ while (bits < end_bits) {
+ if (bits[0] != 0) {
+ return true;
+ }
+ bits += 3;
+ }
+ bits = end_bits;
+ end_bits += bytes_per_line;
+ }
+ break;
+
+ case QImage::Format_ARGB6666_Premultiplied:
+ for (int y=0; y<height; ++y) {
+ while (bits < end_bits) {
+ if ((bits[0] & 0xfc) != 0) {
+ return true;
+ }
+ bits += 3;
+ }
+ bits = end_bits;
+ end_bits += bytes_per_line;
+ }
+ break;
+
+ case QImage::Format_ARGB4444_Premultiplied:
+ for (int y=0; y<height; ++y) {
+ while (bits < end_bits) {
+ if ((bits[0] & 0xf0) != 0) {
+ return true;
+ }
+ bits += 2;
+ }
+ bits = end_bits;
+ end_bits += bytes_per_line;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
void QDirectFBPixmapData::fromImage(const QImage &img,
- Qt::ImageConversionFlags)
+ Qt::ImageConversionFlags flags)
{
- const QImage::Format format = img.hasAlphaChannel() ?
- screen->alphaPixmapFormat()
- : screen->pixelFormat();
+ Q_ASSERT(img.depth() != 1); // these should be handled by QRasterPixmapData
+ if (img.hasAlphaChannel()
+#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION
+ && (flags & Qt::NoOpaqueDetection || ::checkForAlphaPixels(img))
+#endif
+ ) {
+ alpha = true;
+ format = screen->alphaPixmapFormat();
+ } else {
+ alpha = false;
+ format = screen->pixelFormat();
+ }
dfbSurface = screen->copyToDFBSurface(img, format,
QDirectFBScreen::TrackSurface);
forceRaster = (format == QImage::Format_RGB32);
if (!dfbSurface) {
qWarning("QDirectFBPixmapData::fromImage()");
- setSerialNumber(0);
+ invalidate();
return;
}
setSerialNumber(++global_ser_no);
@@ -110,15 +192,15 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
IDirectFBSurface *src = static_cast<const QDirectFBPixmapData*>(data)->directFBSurface();
const bool hasAlpha = data->hasAlphaChannel();
- const QImage::Format format = (hasAlpha
- ? screen->alphaPixmapFormat()
- : screen->pixelFormat());
+ format = (hasAlpha
+ ? QDirectFBScreen::instance()->alphaPixmapFormat()
+ : QDirectFBScreen::instance()->pixelFormat());
dfbSurface = screen->createDFBSurface(rect.size(), format,
QDirectFBScreen::TrackSurface);
if (!dfbSurface) {
qWarning("QDirectFBPixmapData::copy()");
- setSerialNumber(0);
+ invalidate();
return;
}
forceRaster = (format == QImage::Format_RGB32);
@@ -135,13 +217,28 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
dfbSurface->ReleaseSource(dfbSurface);
if (result != DFB_OK) {
DirectFBError("QDirectFBPixmapData::copy()", result);
- setSerialNumber(0);
+ invalidate();
return;
}
setSerialNumber(++global_ser_no);
}
+static inline bool isOpaqueFormat(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_RGB32:
+ case QImage::Format_RGB16:
+ case QImage::Format_RGB666:
+ case QImage::Format_RGB555:
+ case QImage::Format_RGB888:
+ case QImage::Format_RGB444:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
void QDirectFBPixmapData::fill(const QColor &color)
{
@@ -150,17 +247,19 @@ void QDirectFBPixmapData::fill(const QColor &color)
Q_ASSERT(dfbSurface);
- if (color.alpha() < 255 && !hasAlphaChannel()) {
+ alpha = (color.alpha() < 255);
+ if (alpha && ::isOpaqueFormat(format)) {
QSize size;
dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight());
screen->releaseDFBSurface(dfbSurface);
+ format = screen->alphaPixmapFormat();
dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface);
forceRaster = false;
setSerialNumber(++global_ser_no);
if (!dfbSurface) {
- qWarning("QDirectFBPixmapData::fill()");
- setSerialNumber(0);
+ qWarning("QDirecttFBPixmapData::fill()");
+ invalidate();
return;
}
}
@@ -184,19 +283,6 @@ void QDirectFBPixmapData::fill(const QColor &color)
}
}
-bool QDirectFBPixmapData::hasAlphaChannel() const
-{
- if (!serialNumber())
- return false;
- DFBSurfacePixelFormat format;
- dfbSurface->GetPixelFormat(dfbSurface, &format);
- return QDirectFBScreen::hasAlpha(format);
-
- // We don't need to ask DFB for this really. Can just keep track
- // of what image format this has. It should always have either
- // QDirectFBScreen::alphaPixmapFormat() or QScreen::pixelFormat()
-}
-
QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
Qt::TransformationMode mode) const
{
@@ -221,11 +307,10 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
return QPixmap();
QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType);
- QImage::Format format = screen->pixelFormat();
DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
- if (hasAlphaChannel()) {
+ data->alpha = alpha;
+ if (alpha) {
flags = DSBLIT_BLEND_ALPHACHANNEL;
- format = screen->alphaPixmapFormat();
}
data->dfbSurface = screen->createDFBSurface(size,
format,
@@ -250,7 +335,12 @@ QImage QDirectFBPixmapData::toImage() const
#ifndef QT_NO_DIRECTFB_PREALLOCATED
QImage ret(size(), QDirectFBScreen::getImageFormat(dfbSurface));
if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) {
- imgSurface->SetBlittingFlags(imgSurface, hasAlphaChannel() ? DSBLIT_BLEND_ALPHACHANNEL : DSBLIT_NOFX);
+ if (hasAlphaChannel()) {
+ imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL);
+ imgSurface->Clear(imgSurface, 0, 0, 0, 0);
+ } else {
+ imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX);
+ }
imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0);
imgSurface->ReleaseSource(imgSurface);
imgSurface->Release(imgSurface);
@@ -280,3 +370,10 @@ QImage* QDirectFBPixmapData::buffer()
lockDirectFB();
return lockedImage;
}
+
+void QDirectFBPixmapData::invalidate()
+{
+ setSerialNumber(0);
+ alpha = false;
+ format = QImage::Format_Invalid;
+}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
index 32676f8..6cfafcd 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
@@ -64,7 +64,7 @@ public:
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
void copy(const QPixmapData *data, const QRect &rect);
void fill(const QColor &color);
- bool hasAlphaChannel() const;
+ inline bool hasAlphaChannel() const { return alpha; }
QPixmap transformed(const QTransform &matrix,
Qt::TransformationMode mode) const;
QImage toImage() const;
@@ -73,9 +73,12 @@ public:
// Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice
int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);}
-
+ inline QImage::Format pixelFormat() const { return format; }
private:
+ void invalidate();
QDirectFBPaintEngine *engine;
+ QImage::Format format;
+ bool alpha;
};
QT_END_HEADER
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index 4ae64f7..041d522 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -85,7 +85,7 @@ public:
};
QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen* screen)
- : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_BLIT)
+ : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_NONE)
#ifndef QT_NO_DIRECTFB_LAYER
, dfbLayer(0)
#endif
@@ -233,6 +233,18 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription
voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY);
}
result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &voDesc, &newSurface);
+ if (result != DFB_OK
+#ifdef QT_NO_DEBUG
+ && (desc->flags & DSDESC_CAPS) && (desc->caps & DSCAPS_PRIMARY)
+#endif
+ ) {
+ qWarning("QDirectFBScreen::createDFBSurface() Failed to create surface in video memory!\n"
+ " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s",
+ desc->flags, desc->caps, desc->width, desc->height,
+ desc->pixelformat, DFB_PIXELFORMAT_INDEX(desc->pixelformat),
+ desc->preallocated[0].data, desc->preallocated[0].pitch,
+ DirectFBErrorString(result));
+ }
}
if (!newSurface)
@@ -710,7 +722,7 @@ int QDirectFBScreen::depth(DFBSurfacePixelFormat format)
void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args)
{
- QRegExp flipRegexp(QLatin1String("^flip=([\\w,]+)$"));
+ QRegExp flipRegexp(QLatin1String("^flip=([\\w,]*)$"));
int index = args.indexOf(flipRegexp);
if (index >= 0) {
const QStringList flips = flipRegexp.cap(1).split(QLatin1Char(','),
@@ -729,6 +741,8 @@ void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args)
qWarning("QDirectFBScreen: Unknown flip argument: %s",
qPrintable(flip));
}
+ } else {
+ flipFlags = DFBSurfaceFlipFlags(DSFLIP_BLIT);
}
}
@@ -758,6 +772,18 @@ static void printDirectFBInfo(IDirectFB *fb)
dev.blitting_flags, dev.drawing_flags, dev.video_memory);
}
+static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value)
+{
+ Q_ASSERT(value);
+ QRegExp rx(QString("%1=?(\\d+)").arg(variable));
+ rx.setCaseSensitivity(Qt::CaseInsensitive);
+ if (arguments.indexOf(rx) != -1) {
+ *value = rx.cap(1).toInt();
+ return true;
+ }
+ return false;
+}
+
bool QDirectFBScreen::connect(const QString &displaySpec)
{
DFBResult result = DFB_OK;
@@ -803,6 +829,10 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
DFBSurfaceDescription description;
description.flags = DFBSurfaceDescriptionFlags(DSDESC_CAPS);
+ if (::setIntOption(displayArgs, QLatin1String("width"), &description.width))
+ description.flags = DFBSurfaceDescriptionFlags(description.flags | DSDESC_WIDTH);
+ if (::setIntOption(displayArgs, QLatin1String("height"), &description.height))
+ description.flags = DFBSurfaceDescriptionFlags(description.flags | DSDESC_HEIGHT);
description.caps = DFBSurfaceCapabilities(DSCAPS_PRIMARY
| DSCAPS_DOUBLE
| DSCAPS_STATIC_ALLOC);
@@ -812,13 +842,6 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
| DSCAPS_PREMULTIPLIED);
}
- if (!(d_ptr->flipFlags & DSFLIP_BLIT)) {
- description.caps = DFBSurfaceCapabilities(description.caps
- | DSCAPS_DOUBLE
- | DSCAPS_TRIPLE);
- }
-
-
// We don't track the primary surface as it's released in disconnect
d_ptr->dfbSurface = createDFBSurface(&description, DontTrackSurface);
if (!d_ptr->dfbSurface) {
@@ -875,18 +898,8 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
setPixelFormat(getImageFormat(d_ptr->dfbSurface));
physWidth = physHeight = -1;
- QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)"));
- int dimIdxW = displayArgs.indexOf(mmWidthRx);
- if (dimIdxW >= 0) {
- mmWidthRx.exactMatch(displayArgs.at(dimIdxW));
- physWidth = mmWidthRx.cap(1).toInt();
- }
- QRegExp mmHeightRx(QLatin1String("mmHeight=?(\\d+)"));
- int dimIdxH = displayArgs.indexOf(mmHeightRx);
- if (dimIdxH >= 0) {
- mmHeightRx.exactMatch(displayArgs.at(dimIdxH));
- physHeight = mmHeightRx.cap(1).toInt();
- }
+ ::setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth);
+ ::setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight);
const int dpi = 72;
if (physWidth < 0)
physWidth = qRound(dw * 25.4 / dpi);
@@ -994,19 +1007,21 @@ void QDirectFBScreen::blank(bool on)
QWSWindowSurface* QDirectFBScreen::createSurface(QWidget *widget) const
{
#ifdef QT_NO_DIRECTFB_WM
- if (QApplication::type() == QApplication::GuiServer)
- return new QDirectFBSurface(const_cast<QDirectFBScreen*>(this), widget);
- else
+ if (QApplication::type() == QApplication::GuiServer) {
+ return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
+ } else {
return QScreen::createSurface(widget);
+ }
#else
- return new QDirectFBSurface(const_cast<QDirectFBScreen*>(this), widget);
+ return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
#endif
}
QWSWindowSurface* QDirectFBScreen::createSurface(const QString &key) const
{
- if (key == QLatin1String("directfb"))
- return new QDirectFBSurface(const_cast<QDirectFBScreen*>(this));
+ if (key == QLatin1String("directfb")) {
+ return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this));
+ }
return QScreen::createSurface(key);
}
@@ -1178,21 +1193,29 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion &region)
if (region.isEmpty())
return;
- const QVector<QRect> rects = region.rects();
- QVarLengthArray<DFBRectangle> dfbRects(rects.size());
- for (int i = 0; i < rects.size(); ++i) {
- const QRect r = rects.at(i);
- dfbRects[i].x = r.x();
- dfbRects[i].y = r.y();
- dfbRects[i].w = r.width();
- dfbRects[i].h = r.height();
+ if (QDirectFBScreen::getImageFormat(d_ptr->dfbSurface) == QImage::Format_RGB32) {
+ uchar *mem;
+ int bpl;
+ d_ptr->dfbSurface->Lock(d_ptr->dfbSurface, DSLF_WRITE, (void**)&mem, &bpl);
+ QImage img(mem, w, h, bpl, QImage::Format_RGB32);
+ QPainter p(&img);
+ p.setBrush(color);
+ p.setPen(Qt::NoPen);
+ const QVector<QRect> rects = region.rects();
+ p.drawRects(rects.constData(), rects.size());
+ p.end();
+ d_ptr->dfbSurface->Unlock(d_ptr->dfbSurface);
+ } else {
+ d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface,
+ color.red(), color.green(), color.blue(),
+ color.alpha());
+ const QVector<QRect> rects = region.rects();
+ for (int i=0; i<rects.size(); ++i) {
+ const QRect &r = rects.at(i);
+ d_ptr->dfbSurface->FillRectangle(d_ptr->dfbSurface,
+ r.x(), r.y(), r.width(), r.height());
+ }
}
-
- d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface,
- color.red(), color.green(), color.blue(),
- color.alpha());
- d_ptr->dfbSurface->FillRectangles(d_ptr->dfbSurface, dfbRects.data(),
- dfbRects.size());
}
QImage::Format QDirectFBScreen::alphaPixmapFormat() const
@@ -1200,7 +1223,6 @@ QImage::Format QDirectFBScreen::alphaPixmapFormat() const
return d_ptr->alphaPixmapFormat;
}
-
bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description,
QImage::Format format)
{
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp
index 4b8fe0a..8ed308c 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp
@@ -50,12 +50,13 @@
//#define QT_DIRECTFB_DEBUG_SURFACES 1
-QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr)
+QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen* scr)
: QDirectFBPaintDevice(scr)
#ifndef QT_NO_DIRECTFB_WM
, dfbWindow(0)
#endif
, engine(0)
+ , flipFlags(flip)
{
setSurfaceFlags(Opaque | Buffered);
#ifdef QT_DIRECTFB_TIMING
@@ -64,12 +65,13 @@ QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr)
#endif
}
-QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr, QWidget *widget)
+QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget)
: QWSWindowSurface(widget), QDirectFBPaintDevice(scr)
#ifndef QT_NO_DIRECTFB_WM
, dfbWindow(0)
#endif
, engine(0)
+ , flipFlags(flip)
{
onscreen = widget->testAttribute(Qt::WA_PaintOnScreen);
if (onscreen)
@@ -137,28 +139,32 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask)
dfbWindow = 0;
}
#endif
- if (dfbSurface) {
+ if (dfbSurface && dfbSurface != screen->dfbSurface()) {
dfbSurface->Release(dfbSurface);
dfbSurface = 0;
}
} else if (rect != geometry()) {
- const bool isResize = rect.size() != geometry().size();
DFBResult result = DFB_OK;
// If we're in a resize, the surface shouldn't be locked
- Q_ASSERT( (lockedImage == 0) || (isResize == false));
+ Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size()));
if (onscreen) {
- if (dfbSurface)
- dfbSurface->Release(dfbSurface);
-
- DFBRectangle r = { rect.x(), rect.y(),
- rect.width(), rect.height() };
IDirectFBSurface *primarySurface = screen->dfbSurface();
Q_ASSERT(primarySurface);
- result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface);
+ if (dfbSurface && dfbSurface != primarySurface)
+ dfbSurface->Release(dfbSurface);
+
+ if (rect == screen->region().boundingRect()) {
+ dfbSurface = primarySurface;
+ } else {
+ const DFBRectangle r = { rect.x(), rect.y(),
+ rect.width(), rect.height() };
+ result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface);
+ }
forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32);
} else {
+ const bool isResize = rect.size() != geometry().size();
#ifdef QT_NO_DIRECTFB_WM
if (isResize) {
if (dfbSurface)
@@ -244,7 +250,7 @@ void QDirectFBSurface::setPermanentState(const QByteArray &state)
bool QDirectFBSurface::scroll(const QRegion &region, int dx, int dy)
{
- if (!dfbSurface)
+ if (!dfbSurface || !(flipFlags & DSFLIP_BLIT))
return false;
const QVector<QRect> rects = region.rects();
@@ -360,23 +366,31 @@ void QDirectFBSurface::flush(QWidget *widget, const QRegion &region,
if (winOpacity != opacity)
dfbWindow->SetOpacity(dfbWindow, winOpacity);
}
-#endif
-#ifndef QT_NO_DIRECTFB_WM
- if (region.numRects() > 1) {
- const QVector<QRect> rects = region.rects();
- for (int i=0; i<rects.size(); ++i) {
- const QRect &r = rects.at(i);
+ if (!(flipFlags & DSFLIP_BLIT)) {
+ dfbSurface->Flip(dfbSurface, 0, flipFlags);
+ } else {
+ if (region.numRects() > 1) {
+ const QVector<QRect> rects = region.rects();
+ DFBSurfaceFlipFlags tmpFlags = flipFlags;
+ if (flipFlags & DSFLIP_WAIT)
+ tmpFlags = DFBSurfaceFlipFlags(flipFlags & ~DSFLIP_WAIT);
+ for (int i=0; i<rects.size(); ++i) {
+ const QRect &r = rects.at(i);
+ const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
+ r.x() + r.width() + offset.x(),
+ r.y() + r.height() + offset.y() };
+ dfbSurface->Flip(dfbSurface, &dfbReg,
+ i + 1 < rects.size()
+ ? tmpFlags
+ : flipFlags);
+ }
+ } else {
+ const QRect r = region.boundingRect();
const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
r.x() + r.width() + offset.x(),
r.y() + r.height() + offset.y() };
- dfbSurface->Flip(dfbSurface, &dfbReg, DSFLIP_ONSYNC);
+ dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags);
}
- } else {
- const QRect r = region.boundingRect();
- const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
- r.x() + r.width() + offset.x(),
- r.y() + r.height() + offset.y() };
- dfbSurface->Flip(dfbSurface, &dfbReg, DSFLIP_ONSYNC);
}
#endif
#ifdef QT_DIRECTFB_TIMING
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h
index 9e2791c..ab4145d 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h
@@ -61,8 +61,8 @@ QT_MODULE(Gui)
class QDirectFBSurface: public QWSWindowSurface, public QDirectFBPaintDevice
{
public:
- QDirectFBSurface(QDirectFBScreen* scr);
- QDirectFBSurface(QDirectFBScreen* scr, QWidget *widget);
+ QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr);
+ QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget);
~QDirectFBSurface();
bool isValid() const;
@@ -99,6 +99,7 @@ private:
bool onscreen;
QList<QImage*> bufferImages;
+ DFBSurfaceFlipFlags flipFlags;
#ifdef QT_DIRECTFB_TIMING
int frames;
QTime timer;