summaryrefslogtreecommitdiffstats
path: root/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp')
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp529
1 files changed, 210 insertions, 319 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index 4fc4035..d9346fd 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -61,17 +61,6 @@ static inline uint ALPHA_MUL(uint x, uint a)
return t;
}
-static inline QRect mapRect(const QTransform &transform, const QRect &rect)
-{
- return (transform.isIdentity() ? rect : transform.mapRect(rect));
-}
-
-static inline QRect mapRect(const QTransform &transform, const QRectF &rect)
-{
- return (transform.isIdentity() ? rect : transform.mapRect(rect)).
- toRect();
-}
-
class SurfaceCache
{
public:
@@ -112,7 +101,7 @@ CachedImage::CachedImage(const QImage &image)
description = QDirectFBScreen::getSurfaceDescription(image);
QDirectFBScreen* screen = QDirectFBScreen::instance();
- tmpSurface = screen->createDFBSurface(&description);
+ tmpSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface);
if (!tmpSurface) {
qWarning("CachedImage CreateSurface failed!");
return;
@@ -124,7 +113,7 @@ CachedImage::CachedImage(const QImage &image)
description.flags = DFBSurfaceDescriptionFlags(description.flags & ~DSDESC_PREALLOCATED);
- s = screen->createDFBSurface(&description);
+ s = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface);
if (!s)
qWarning("QDirectFBPaintEngine failed caching image");
@@ -159,7 +148,7 @@ IDirectFBSurface* SurfaceCache::getSurface(const uint *buf, int size)
DFBSurfaceDescription description;
description = QDirectFBScreen::getSurfaceDescription(buf, size);
- surface = QDirectFBScreen::instance()->createDFBSurface(&description);
+ surface = QDirectFBScreen::instance()->createDFBSurface(&description, QDirectFBScreen::TrackSurface);
if (!surface)
qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface");
@@ -195,6 +184,7 @@ public:
QBrush brush;
bool antialiased;
+ bool forceRasterPrimitives;
bool simplePen;
bool simpleBrush;
@@ -206,12 +196,12 @@ 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 bool lock();
+ inline void lock();
inline void unlock();
inline bool dfbCanHandleClip(const QRect &rect) const;
@@ -232,43 +222,41 @@ 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;
int fbHeight;
quint8 opacity;
- QTransform transform;
- quint32 drawFlags;
- quint32 blitFlags;
- quint32 duffFlags;
- bool dirtyFlags;
+ quint32 drawFlagsFromCompositionMode, blitFlagsFromCompositionMode;
+ DFBSurfacePorterDuffRule porterDuffRule;
+
bool dirtyClip;
bool dfbHandledClip;
+ QDirectFBPaintDevice *dfbDevice;
QDirectFBPaintEngine *q;
};
QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p)
- : surface(0), antialiased(false), simplePen(false),
- simpleBrush(false), matrixRotShear(false), matrixScale(false), fbWidth(-1), fbHeight(-1),
- opacity(255), drawFlags(0), blitFlags(0), duffFlags(0), dirtyFlags(false), dirtyClip(true),
- dfbHandledClip(false), q(p)
+ : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false),
+ simpleBrush(false), matrixRotShear(false), matrixScale(false), lastLockedHeight(-1),
+ 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;
@@ -279,7 +267,6 @@ QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p
QDirectFBPaintEnginePrivate::~QDirectFBPaintEnginePrivate()
{
- unlock();
delete surfaceCache;
}
@@ -305,27 +292,20 @@ void QDirectFBPaintEnginePrivate::setClipDirty()
dirtyClip = true;
}
-
-bool QDirectFBPaintEnginePrivate::lock()
+void QDirectFBPaintEnginePrivate::lock()
{
// We will potentially get a new pointer to the buffer after a
// lock so we need to call the base implementation of prepare so
// it updates its rasterBuffer to point to the new buffer address.
- if (device->devType() == QInternal::CustomRaster) {
- prepare(static_cast<QCustomRasterPaintDevice*>(device));
- return true;
- }
- return false;
+ lastLockedHeight = dfbDevice->height();
+
+ Q_ASSERT(dfbDevice);
+ prepare(dfbDevice);
}
void QDirectFBPaintEnginePrivate::unlock()
{
- QPaintDevice *device = q->paintDevice();
- if (!device) //XXX This should probably be an assert
- return;
-
- Q_ASSERT(device->devType() == QInternal::CustomRaster);
- QDirectFBPaintDevice* dfbDevice = static_cast<QDirectFBPaintDevice*>(device);
+ Q_ASSERT(dfbDevice);
dfbDevice->unlockDirectFB();
}
@@ -338,35 +318,31 @@ void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m)
void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device)
{
- QDirectFBPaintDevice* dfbDevice = 0;
-
+ lastLockedHeight = -1;
if (device->devType() == QInternal::CustomRaster)
dfbDevice = static_cast<QDirectFBPaintDevice*>(device);
else if (device->devType() == QInternal::Pixmap) {
QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData();
- if (data->classId() == QPixmapData::DirectFBClass) {
- QDirectFBPixmapData* dfbPixmapData = static_cast<QDirectFBPixmapData*>(data);
- dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData);
- }
+ Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
+ QDirectFBPixmapData* dfbPixmapData = static_cast<QDirectFBPixmapData*>(data);
+ dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData);
}
if (dfbDevice)
- surface = dfbDevice->directFbSurface();
+ surface = dfbDevice->directFBSurface();
if (!surface) {
qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x",
device->devType());
}
+ forceRasterPrimitives = dfbDevice->forceRasterPrimitives();
surface->GetSize(surface, &fbWidth, &fbHeight);
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());
@@ -374,6 +350,7 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device)
void QDirectFBPaintEnginePrivate::end()
{
+ dfbDevice = 0;
surface->ReleaseSource(surface);
surface->SetClip(surface, NULL);
surface = 0;
@@ -383,13 +360,14 @@ void QDirectFBPaintEnginePrivate::setPen(const QPen &p)
{
pen = p;
simplePen = (pen.style() == Qt::NoPen) ||
- (pen.style() == Qt::SolidLine && !antialiased
+ (pen.style() == Qt::SolidLine
+ && !antialiased
+ && (pen.brush().style() == Qt::SolidPattern)
&& (pen.widthF() <= 1 && !matrixScale));
}
void QDirectFBPaintEnginePrivate::setBrush(const QBrush &b)
{
- // TODO: accelerate texture pattern
brush = b;
simpleBrush = (brush.style() == Qt::NoBrush) ||
(brush.style() == Qt::SolidPattern && !antialiased);
@@ -397,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)
@@ -493,133 +452,83 @@ 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]);
-
- // TODO: clip!
-
- 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();
-
- // TODO: clip!
-
- 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 = ::mapRect(transform, 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 = ::mapRect(transform, rects[i]);
- region += clip & r;
+ surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2());
}
-
- return region;
}
-*/
void QDirectFBPaintEnginePrivate::fillRegion(const QRegion &region) const
{
const QVector<QRect> rects = region.rects();
const int n = rects.size();
- QVarLengthArray<DFBRectangle> dfbRects(n);
-
- for (int i = 0; i < n; ++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();
-
- }
- surface->FillRectangles(surface, dfbRects.data(), n);
+ fillRects(rects.constData(), n);
}
void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) const
{
- QVarLengthArray<DFBRectangle> dfbRects(n);
for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
- dfbRects[i].x = r.x();
- dfbRects[i].y = r.y();
- dfbRects[i].w = r.width();
- dfbRects[i].h = r.height();
+ const QRect r = transform.mapRect(rects[i]);
+ surface->FillRectangle(surface, r.x(), r.y(),
+ r.width(), r.height());
}
- surface->FillRectangles(surface, dfbRects.data(), n);
}
void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) const
{
- QVarLengthArray<DFBRectangle> dfbRects(n);
for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
- dfbRects[i].x = r.x();
- dfbRects[i].y = r.y();
- dfbRects[i].w = r.width();
- dfbRects[i].h = r.height();
+ const QRect r = transform.mapRect(rects[i]).toRect();
+ surface->FillRectangle(surface, r.x(), r.y(),
+ r.width(), r.height());
}
- surface->FillRectangles(surface, dfbRects.data(), n);
}
void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const
{
for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
+ const QRect r = transform.mapRect(rects[i]);
surface->DrawRectangle(surface, r.x(), r.y(),
r.width() + 1, r.height() + 1);
}
@@ -628,7 +537,7 @@ void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const
void QDirectFBPaintEnginePrivate::drawRects(const QRectF *rects, int n) const
{
for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
+ const QRect r = transform.mapRect(rects[i]).toRect();
surface->DrawRectangle(surface, r.x(), r.y(),
r.width() + 1, r.height() + 1);
}
@@ -638,21 +547,13 @@ 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);
- IDirectFBSurface *s = dfbData->directFbSurface();
+ IDirectFBSurface *s = dfbData->directFBSurface();
const QRect sr = src.toRect();
- const QRect dr = ::mapRect(transform, dest);
+ const QRect dr = transform.mapRect(dest).toRect();
const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() };
DFBResult result;
@@ -664,27 +565,17 @@ 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);
- IDirectFBSurface *s = dfbData->directFbSurface();
- const QRect dr = ::mapRect(transform, dest);
+ IDirectFBSurface *s = dfbData->directFBSurface();
+ const QRect dr = transform.mapRect(dest).toRect();
DFBResult result = DFB_OK;
if (!matrixScale && dr == QRect(0, 0, fbWidth, fbHeight)) {
@@ -706,7 +597,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest,
result = surface->BatchBlit(surface, s, rects.constData(),
points.constData(), points.size());
} else {
- const QRect sr = ::mapRect(transform, QRect(0, 0, pixmap.width(), pixmap.height()));
+ const QRect sr = transform.mapRect(QRect(0, 0, pixmap.width(), pixmap.height()));
const int dx = sr.width();
const int dy = sr.height();
const DFBRectangle sRect = { 0, 0, dx, dy };
@@ -725,25 +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) == DSPF_UNKNOWN) {
- QImage::Format format;
- if (image.hasAlphaChannel())
- format = QImage::Format_ARGB32_Premultiplied;
- else
- format = QImage::Format_RGB32;
- image = image.convertToFormat(format);
- }
-
+ Q_ASSERT(QDirectFBScreen::getSurfacePixelFormat(image.format()) != DSPF_UNKNOWN);
CachedImage *img = imageCache[image.cacheKey()];
IDirectFBSurface *imgSurface = 0;
bool doRelease = false;
@@ -767,7 +646,8 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest,
DFBSurfaceDescription description;
description = QDirectFBScreen::getSurfaceDescription(image);
- imgSurface = QDirectFBScreen::instance()->createDFBSurface(&description);
+ imgSurface = QDirectFBScreen::instance()->createDFBSurface(&description,
+ QDirectFBScreen::DontTrackSurface);
if (!imgSurface) {
qWarning("QDirectFBPaintEnginePrivate::drawImage");
return;
@@ -781,17 +661,10 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest,
}
const QRect sr = src.toRect();
- const QRect dr = ::mapRect(transform, 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 {
@@ -799,10 +672,10 @@ 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)
- QDirectFBScreen::instance()->releaseDFBSurface(imgSurface);
+ if (doRelease) {
+ surface->ReleaseSource(surface);
+ imgSurface->Release(imgSurface);
+ }
}
void QDirectFBPaintEnginePrivate::updateClip()
@@ -893,8 +766,7 @@ void QDirectFBPaintEngine::brushChanged()
void QDirectFBPaintEngine::opacityChanged()
{
Q_D(QDirectFBPaintEngine);
- d->setOpacity(state()->opacity);
-
+ d->setOpacity(quint8(state()->opacity * 255));
QRasterPaintEngine::opacityChanged();
}
@@ -902,7 +774,6 @@ void QDirectFBPaintEngine::compositionModeChanged()
{
Q_D(QDirectFBPaintEngine);
d->setCompositionMode(state()->compositionMode());
-
QRasterPaintEngine::compositionModeChanged();
}
@@ -928,11 +799,10 @@ void QDirectFBPaintEngine::setState(QPainterState *s)
{
Q_D(QDirectFBPaintEngine);
QRasterPaintEngine::setState(s);
- if (d->surface)
- d->updateClip();
+ 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());
}
@@ -941,6 +811,9 @@ void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
{
Q_D(QDirectFBPaintEngine);
d->setClipDirty();
+ const QPoint bottom = d->transform.map(QPoint(0, path.controlPointRect().y2));
+ if (bottom.y() >= d->lastLockedHeight)
+ d->lock();
QRasterPaintEngine::clip(path, op);
}
@@ -948,15 +821,21 @@ void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
{
Q_D(QDirectFBPaintEngine);
d->setClipDirty();
+ if (!d->clip()->hasRectClip && d->clip()->enabled) {
+ const QPoint bottom = d->transform.map(QPoint(0, rect.bottom()));
+ if (bottom.y() >= d->lastLockedHeight)
+ d->lock();
+ }
+
QRasterPaintEngine::clip(rect, op);
}
-
void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush || !d->simplePen) {
+ if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush
+ || !d->simplePen || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::drawRects(rects, rectCount);
return;
@@ -965,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);
}
@@ -980,7 +857,8 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush || !d->simplePen) {
+ if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush
+ || !d->simplePen || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::drawRects(rects, rectCount);
return;
@@ -989,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);
}
@@ -1004,7 +880,7 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->simplePen || !d->dfbCanHandleClip()) {
+ if (!d->simplePen || !d->dfbCanHandleClip() || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::drawLines(lines, lineCount);
return;
@@ -1012,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);
}
@@ -1022,7 +897,7 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->simplePen || !d->dfbCanHandleClip()) {
+ if (!d->simplePen || !d->dfbCanHandleClip() || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::drawLines(lines, lineCount);
return;
@@ -1030,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);
}
@@ -1045,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();
@@ -1055,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
}
@@ -1074,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);
}
}
@@ -1101,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()) {
- QImage* img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer();
+ } 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);
- d->lock();
QRasterPaintEngine::drawTiledPixmap(r, pix, sp);
- }
- else {
+ } else {
d->unlock();
- d->updateFlags();
d->drawTiledPixmap(r, pixmap);
}
}
@@ -1184,67 +1052,89 @@ void QDirectFBPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
QRasterPaintEngine::fill(path, brush);
}
-void QDirectFBPaintEngine::fillRect(const QRectF &r, const QBrush &brush)
+
+void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
{
Q_D(QDirectFBPaintEngine);
- if (brush.style() != Qt::SolidPattern) {
- d->lock();
- QRasterPaintEngine::fillRect(r, brush);
+ d->updateClip();
+ if (d->dfbCanHandleClip(rect) && !d->matrixRotShear) {
+ switch (brush.style()) {
+ case Qt::SolidPattern: {
+ if (d->forceRasterPrimitives)
+ break;
+ d->unlock();
+ d->setDFBColor(brush.color());
+ const QRect r = d->transform.mapRect(rect).toRect();
+ d->surface->FillRectangle(d->surface, r.x(), r.y(),
+ r.width(), r.height());
+ return; }
+ case Qt::TexturePattern:
+ if (state()->brushOrigin == QPointF() && brush.transform().isIdentity()) {
+ //could handle certain types of brush.transform() E.g. scale
+ d->unlock();
+ d->drawTiledPixmap(rect, brush.texture());
+ return;
+ }
+ break;
+ default:
+ break;
+ }
}
- else
- fillRect(r, brush.color());
+ d->lock();
+ QRasterPaintEngine::fillRect(rect, brush);
}
void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->dfbCanHandleClip() || d->matrixRotShear) {
+ if (!d->dfbCanHandleClip() || d->matrixRotShear || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::fillRect(rect, color);
} else {
d->unlock();
- d->updateFlags();
d->setDFBColor(color);
- d->fillRects(&rect, 1);
+ const QRect r = d->transform.mapRect(rect).toRect();
+ d->surface->FillRectangle(d->surface, r.x(), r.y(),
+ r.width(), r.height());
}
}
-
-
-
-
-
-
void QDirectFBPaintEngine::drawColorSpans(const QSpan *spans, int count,
uint color)
{
Q_D(QDirectFBPaintEngine);
- color = INV_PREMUL(color);
-
- QVarLengthArray<DFBRegion> lines(count);
- int j = 0;
- for (int i = 0; i < count; ++i) {
- if (spans[i].coverage == 255) {
- lines[j].x1 = spans[i].x;
- lines[j].y1 = spans[i].y;
- lines[j].x2 = spans[i].x + spans[i].len - 1;
- lines[j].y2 = spans[i].y;
- ++j;
- } else {
- DFBSpan span = { spans[i].x, spans[i].len };
- uint c = BYTE_MUL(color, spans[i].coverage);
+ if (d->forceRasterPrimitives) {
+ d->lock();
+ QRasterPaintEngine::drawColorSpans(spans, count, color);
+ } else {
+ color = INV_PREMUL(color);
+
+ QVarLengthArray<DFBRegion> lines(count);
+ int j = 0;
+ for (int i = 0; i < count; ++i) {
+ if (spans[i].coverage == 255) {
+ lines[j].x1 = spans[i].x;
+ lines[j].y1 = spans[i].y;
+ lines[j].x2 = spans[i].x + spans[i].len - 1;
+ lines[j].y2 = spans[i].y;
+ ++j;
+ } 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);
+ }
+ }
+ if (j > 0) {
d->surface->SetColor(d->surface,
- qRed(c), qGreen(c), qBlue(c), qAlpha(c));
- d->surface->FillSpans(d->surface, spans[i].y, &span, 1);
+ qRed(color), qGreen(color), qBlue(color),
+ qAlpha(color));
+ d->surface->DrawLines(d->surface, lines.data(), j);
}
}
- if (j > 0) {
- d->surface->SetColor(d->surface,
- qRed(color), qGreen(color), qBlue(color),
- qAlpha(color));
- d->surface->DrawLines(d->surface, lines.data(), j);
- }
}
void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
@@ -1253,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);