summaryrefslogtreecommitdiffstats
path: root/src/plugins/gfxdrivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gfxdrivers')
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp44
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp18
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp36
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.h1
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp9
5 files changed, 75 insertions, 33 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index 4869eba..c16a242 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -55,6 +55,7 @@
#include <private/qpixmap_raster_p.h>
#include <private/qimagepixmapcleanuphooks_p.h>
+
QT_BEGIN_NAMESPACE
class SurfaceCache;
@@ -112,7 +113,11 @@ public:
static inline int cacheCost(const QImage &img) { return img.width() * img.height() * img.depth() / 8; }
#endif
- void prepareForBlit(bool alpha);
+ enum BlitFlag {
+ HasAlpha = 0x1,
+ Premultiplied = 0x2
+ };
+ void prepareForBlit(uint blitFlags);
IDirectFBSurface *surface;
@@ -616,7 +621,12 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
#if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
bool release;
IDirectFBSurface *imgSurface = d->getSurface(image, &release);
- d->prepareForBlit(QDirectFBScreen::hasAlphaChannel(imgSurface));
+ uint blitFlags = 0;
+ if (image.hasAlphaChannel())
+ blitFlags |= QDirectFBPaintEnginePrivate::HasAlpha;
+ if (QDirectFBScreen::isPremultiplied(image.format()))
+ blitFlags |= QDirectFBPaintEnginePrivate::Premultiplied;
+ d->prepareForBlit(blitFlags);
CLIPPED_PAINT(d->blit(r, imgSurface, sr));
if (release) {
#if (Q_DIRECTFB_VERSION >= 0x010000)
@@ -655,8 +665,14 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap,
QRasterPaintEngine::drawImage(r, *img, sr);
} else {
QDirectFBPaintEnginePrivate::unlock(dfbData);
- d->prepareForBlit(pixmap.hasAlphaChannel());
IDirectFBSurface *s = dfbData->directFBSurface();
+ uint blitFlags = 0;
+ if (pixmap.hasAlphaChannel())
+ blitFlags |= QDirectFBPaintEnginePrivate::HasAlpha;
+ if (QDirectFBScreen::isPremultiplied(dfbData->pixelFormat()))
+ blitFlags |= QDirectFBPaintEnginePrivate::Premultiplied;
+
+ d->prepareForBlit(blitFlags);
CLIPPED_PAINT(d->blit(r, s, sr));
}
}
@@ -978,7 +994,7 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m
break;
case QPainter::CompositionMode_SourceOver:
compositionModeStatus &= ~PorterDuff_AlwaysBlend;
- surface->SetPorterDuff(surface, DSPD_NONE);
+ surface->SetPorterDuff(surface, DSPD_SRC_OVER);
break;
case QPainter::CompositionMode_DestinationOver:
surface->SetPorterDuff(surface, DSPD_DST_OVER);
@@ -1031,13 +1047,18 @@ void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints)
}
}
-void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha)
+void QDirectFBPaintEnginePrivate::prepareForBlit(uint flags)
{
- DFBSurfaceBlittingFlags blittingFlags = alpha ? DSBLIT_BLEND_ALPHACHANNEL : DSBLIT_NOFX;
+ DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX;
+ if (flags & Premultiplied)
+ blittingFlags |= DSBLIT_SRC_PREMULTIPLY;
+ if (flags & HasAlpha)
+ blittingFlags |= DSBLIT_BLEND_ALPHACHANNEL;
if (opacity != 255) {
blittingFlags |= DSBLIT_BLEND_COLORALPHA;
+ surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
}
- surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
+
surface->SetBlittingFlags(surface, blittingFlags);
}
@@ -1154,13 +1175,18 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPix
QPointF offset = off;
Q_ASSERT(transform.type() <= QTransform::TxScale);
- prepareForBlit(pixmap.hasAlphaChannel());
QPixmapData *data = pixmap.pixmapData();
Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
+ IDirectFBSurface *sourceSurface = dfbData->directFBSurface();
+ uint blitFlags = 0;
+ if (dfbData->hasAlphaChannel())
+ blitFlags |= HasAlpha;
+ if (QDirectFBScreen::isPremultiplied(dfbData->pixelFormat()))
+ blitFlags |= Premultiplied;
+ prepareForBlit(blitFlags);
QDirectFBPaintEnginePrivate::unlock(dfbData);
const QSize pixmapSize = dfbData->size();
- IDirectFBSurface *sourceSurface = dfbData->directFBSurface();
if (transform.isScaling()) {
Q_ASSERT(supportsStretchBlit());
Q_ASSERT(qMin(transform.m11(), transform.m22()) >= 0);
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index c0d96d7..ce3a05a 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -251,12 +251,6 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti
}
QDirectFBPointer<IDirectFBImageProvider> provider(providerPtr);
- DFBSurfaceDescription surfaceDescription;
- if ((result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription)) != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't get surface description", result);
- return false;
- }
-
DFBImageDescription imageDescription;
result = provider->GetImageDescription(provider.data(), &imageDescription);
if (result != DFB_OK) {
@@ -264,7 +258,17 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti
return false;
}
- alpha = imageDescription.caps & (DICAPS_ALPHACHANNEL|DICAPS_COLORKEY);
+ if (imageDescription.caps & DICAPS_COLORKEY) {
+ return false;
+ }
+
+ DFBSurfaceDescription surfaceDescription;
+ if ((result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription)) != DFB_OK) {
+ DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't get surface description", result);
+ return false;
+ }
+
+ alpha = imageDescription.caps & DICAPS_ALPHACHANNEL;
imageFormat = alpha ? screen->alphaPixmapFormat() : screen->pixelFormat();
dfbSurface = screen->createDFBSurface(QSize(surfaceDescription.width, surfaceDescription.height),
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index bf6164d..f2ee6ae 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -1554,9 +1554,8 @@ void QDirectFBScreen::exposeRegion(QRegion r, int)
: (DSBLIT_BLEND_ALPHACHANNEL|DSBLIT_BLEND_COLORALPHA);
}
}
- if (!region.isEmpty()) {
- solidFill(d_ptr->backgroundColor, region);
- }
+
+ solidFill(d_ptr->backgroundColor, region);
while (idx > 0) {
const PaintCommand &cmd = commands[--idx];
@@ -1629,29 +1628,34 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion &region)
Q_UNUSED(color);
Q_UNUSED(region);
#else
+ QDirectFBScreen::solidFill(d_ptr->primarySurface, color, region);
+#endif
+}
+
+static inline void clearRect(IDirectFBSurface *surface, const QColor &color, const QRect &rect)
+{
+ Q_ASSERT(surface);
+ const DFBRegion region = { rect.left(), rect.top(), rect.right(), rect.bottom() };
+ // could just reinterpret_cast this to a DFBRegion
+ surface->SetClip(surface, &region);
+ surface->Clear(surface, color.red(), color.green(), color.blue(), color.alpha());
+}
+
+void QDirectFBScreen::solidFill(IDirectFBSurface *surface, const QColor &color, const QRegion &region)
+{
if (region.isEmpty())
return;
- d_ptr->primarySurface->SetColor(d_ptr->primarySurface,
- color.red(), color.green(), color.blue(),
- color.alpha());
const int n = region.rectCount();
if (n == 1) {
- const QRect r = region.boundingRect();
- d_ptr->primarySurface->FillRectangle(d_ptr->primarySurface, r.x(), r.y(), r.width(), r.height());
+ clearRect(surface, color, region.boundingRect());
} else {
const QVector<QRect> rects = region.rects();
- QVarLengthArray<DFBRectangle, 32> rectArray(n);
for (int i=0; i<n; ++i) {
- const QRect &r = rects.at(i);
- rectArray[i].x = r.x();
- rectArray[i].y = r.y();
- rectArray[i].w = r.width();
- rectArray[i].h = r.height();
+ clearRect(surface, color, rects.at(i));
}
- d_ptr->primarySurface->FillRectangles(d_ptr->primarySurface, rectArray.constData(), n);
}
-#endif
+ surface->SetClip(surface, 0);
}
QImage::Format QDirectFBScreen::alphaPixmapFormat() const
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
index c483020..1085423 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
@@ -159,6 +159,7 @@ public:
void exposeRegion(QRegion r, int changing);
void solidFill(const QColor &color, const QRegion &region);
+ static void solidFill(IDirectFBSurface *surface, const QColor &color, const QRegion &region);
void setMode(int width, int height, int depth);
void blank(bool on);
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
index 51969fc..2eeee24 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
@@ -380,11 +380,18 @@ void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion &region,
flushPending = false;
}
-void QDirectFBWindowSurface::beginPaint(const QRegion &)
+void QDirectFBWindowSurface::beginPaint(const QRegion &region)
{
if (!engine) {
engine = new QDirectFBPaintEngine(this);
}
+
+ if (dfbSurface) {
+ const QWidget *win = window();
+ if (win && win->testAttribute(Qt::WA_NoSystemBackground)) {
+ QDirectFBScreen::solidFill(dfbSurface, Qt::transparent, region);
+ }
+ }
flushPending = true;
}