summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Bakken <anders.bakken@nokia.com>2009-03-27 17:58:37 (GMT)
committerTom Cooksey <thomas.cooksey@nokia.com>2009-03-30 14:49:35 (GMT)
commit34059fba55816496d2570b3306ac2b631b12a5c6 (patch)
treef66e2313829c50eaf9d85423b3fea3d7d5c3f24e
parent637b8aa2361fea8c0ea6579a6308ae594e6d8633 (diff)
downloadQt-34059fba55816496d2570b3306ac2b631b12a5c6.zip
Qt-34059fba55816496d2570b3306ac2b631b12a5c6.tar.gz
Qt-34059fba55816496d2570b3306ac2b631b12a5c6.tar.bz2
Work around raster engine not ignoring the pad byte in RGB32
DirectFB sets the alpha byte to 0 in RGB32 for all drawing operations. The raster paint engine needs this padding byte to be 0xFF as it shares some code paths with RGBA8888_Premultiplied. So, always fall back to raster engine for draw operations. This is really due to a bug in the raster paint engine (Tracked by task 184073), which should ignore the extra byte. Once this task is fixed, this patch can probably be reverted. Reviewed-by: Tom Cooksey
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h7
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp67
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp59
3 files changed, 78 insertions, 55 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
index 23fa5d6..7096124 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
@@ -61,25 +61,28 @@ public:
void lockDirectFB();
void unlockDirectFB();
+ inline bool forceRasterPrimitives() const { return forceRaster; }
+
// Reimplemented from QCustomRasterPaintDevice:
void* memory() const;
QImage::Format format() const;
int bytesPerLine() const;
QSize size() const;
int metric(QPaintDevice::PaintDeviceMetric metric) const;
-
protected:
// Shouldn't create QDirectFBPaintDevice by itself but only sub-class it:
QDirectFBPaintDevice(QDirectFBScreen *scr = QDirectFBScreen::instance())
: QCustomRasterPaintDevice(0),
dfbSurface(0),
lockedImage(0),
- screen(scr) {}
+ screen(scr),
+ forceRaster(false) {}
IDirectFBSurface *dfbSurface;
QImage *lockedImage;
QDirectFBScreen *screen;
int bpl;
+ bool forceRaster;
private:
Q_DISABLE_COPY(QDirectFBPaintDevice)
};
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index 84a92d8..28386e5 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -195,6 +195,7 @@ public:
QBrush brush;
bool antialiased;
+ bool forceRasterPrimitives;
bool simplePen;
bool simpleBrush;
@@ -265,7 +266,7 @@ private:
};
QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p)
- : surface(0), antialiased(false), simplePen(false),
+ : surface(0), antialiased(false), forceRasterPrimitives(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), dfbDevice(0), q(p)
@@ -345,6 +346,7 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device)
qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x",
device->devType());
}
+ forceRasterPrimitives = dfbDevice->forceRasterPrimitives();
surface->GetSize(surface, &fbWidth, &fbHeight);
@@ -945,7 +947,8 @@ 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;
@@ -969,7 +972,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;
@@ -993,7 +997,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;
@@ -1011,7 +1015,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;
@@ -1181,6 +1185,8 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
if (d->dfbCanHandleClip(rect) && !d->matrixRotShear) {
switch (brush.style()) {
case Qt::SolidPattern: {
+ if (d->forceRasterPrimitives)
+ break;
d->unlock();
d->updateFlags();
d->setDFBColor(brush.color());
@@ -1209,7 +1215,7 @@ 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 {
@@ -1226,31 +1232,36 @@ 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);
+ 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,
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index 6d942a4..3099205 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -71,15 +71,10 @@ void QDirectFBPixmapData::resize(int width, int height)
return;
}
- DFBSurfaceDescription description;
- description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH
- | DSDESC_HEIGHT
- | DSDESC_PIXELFORMAT);
- QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, screen->pixelFormat());
- description.width = width;
- description.height = height;
-
- dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface);
+ dfbSurface = QDirectFBScreen::instance()->createDFBSurface(QSize(width, height),
+ screen->pixelFormat(),
+ QDirectFBScreen::TrackSurface);
+ forceRaster = (screen->pixelFormat() == QImage::Format_RGB32);
if (!dfbSurface) {
setSerialNumber(0);
qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface");
@@ -92,10 +87,12 @@ void QDirectFBPixmapData::resize(int width, int height)
void QDirectFBPixmapData::fromImage(const QImage &img,
Qt::ImageConversionFlags)
{
- dfbSurface = screen->copyToDFBSurface(img,
- img.hasAlphaChannel() ? screen->alphaPixmapFormat()
- : screen->pixelFormat(),
- QDirectFBScreen::TrackSurface);
+ const QImage::Format format = img.hasAlphaChannel() ?
+ screen->alphaPixmapFormat()
+ : screen->pixelFormat();
+ dfbSurface = screen->copyToDFBSurface(img, format,
+ QDirectFBScreen::TrackSurface);
+ forceRaster = (format == QImage::Format_RGB32);
if (!dfbSurface) {
qWarning("QDirectFBPixmapData::fromImage()");
setSerialNumber(0);
@@ -112,22 +109,18 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
}
IDirectFBSurface *src = static_cast<const QDirectFBPixmapData*>(data)->directFbSurface();
+ const QImage::Format format = (data->hasAlphaChannel()
+ ? QDirectFBScreen::instance()->alphaPixmapFormat()
+ : QDirectFBScreen::instance()->pixelFormat());
- DFBSurfaceDescription description;
- description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH |
- DSDESC_HEIGHT |
- DSDESC_PIXELFORMAT);
- description.width = rect.width();
- description.height = rect.height();
- src->GetPixelFormat(src, &description.pixelformat);
- src->GetCapabilities(src, &description.caps);
-
- dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface);
+ dfbSurface = screen->createDFBSurface(rect.size(), format,
+ QDirectFBScreen::TrackSurface);
if (!dfbSurface) {
qWarning("QDirectFBPixmapData::copy()");
setSerialNumber(0);
return;
}
+ forceRaster = (format == QImage::Format_RGB32);
dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
const DFBRectangle blitRect = { rect.x(), rect.y(),
@@ -160,6 +153,7 @@ void QDirectFBPixmapData::fill(const QColor &color)
screen->releaseDFBSurface(dfbSurface); // release old surface
dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface);
+ forceRaster = false;
setSerialNumber(++global_ser_no);
if (!dfbSurface) {
qWarning("QDirectFBPixmapData::fill()");
@@ -168,8 +162,23 @@ void QDirectFBPixmapData::fill(const QColor &color)
}
}
- dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(),
- color.alpha());
+ if (forceRaster) {
+ // in DSPF_RGB32 all dfb drawing causes the Alpha byte to be
+ // set to 0. This causes issues for the raster engine.
+ char *mem;
+ int bpl;
+ const int h = QPixmapData::height();
+ dfbSurface->Lock(dfbSurface, DSLF_WRITE, (void**)&mem, &bpl);
+ const int c = color.rgba();
+ for (int i = 0; i < h; ++i) {
+ memset(mem, c, bpl);
+ mem += bpl;
+ }
+ dfbSurface->Unlock(dfbSurface);
+ } else {
+ dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(),
+ color.alpha());
+ }
}
bool QDirectFBPixmapData::hasAlphaChannel() const