summaryrefslogtreecommitdiffstats
path: root/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp')
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp485
1 files changed, 338 insertions, 147 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index 0486e400b4..3e54e7f57d 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -81,10 +81,11 @@ public:
QDirectFBKeyboardHandler *keyboard;
#endif
bool videoonly;
+ QImage::Format alphaPixmapFormat;
};
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
@@ -96,6 +97,7 @@ QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen* screen)
, keyboard(0)
#endif
, videoonly(false)
+ , alphaPixmapFormat(QImage::Format_Invalid)
{
#ifndef QT_NO_QWS_SIGNALHANDLER
QWSSignalHandler::instance()->addObject(this);
@@ -130,7 +132,90 @@ QDirectFBScreenPrivate::~QDirectFBScreenPrivate()
dfb->Release(dfb);
}
-IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription* desc, bool track)
+
+
+// creates a preallocated surface with the same format as the image if
+// possible.
+
+IDirectFBSurface* QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCreationOptions options)
+{
+ if (img.isNull()) // assert?
+ return 0;
+ if (QDirectFBScreen::getSurfacePixelFormat(img.format()) == DSPF_UNKNOWN) {
+ QImage image = img.convertToFormat(img.hasAlphaChannel()
+ ? d_ptr->alphaPixmapFormat
+ : pixelFormat());
+ IDirectFBSurface *tmp = createDFBSurface(image, false);
+ if (!tmp) {
+ qWarning("Couldn't create surface createDFBSurface(QImage, bool)");
+ return 0;
+ }
+ IDirectFBSurface *surface = copyDFBSurface(tmp, image.format(), options);
+ tmp->Release(tmp);
+ return surface;
+ }
+
+ DFBSurfaceDescription desc = QDirectFBScreen::getSurfaceDescription(img);
+ IDirectFBSurface *surface = createDFBSurface(&desc, options);
+#ifdef QT_NO_DIRECTFB_PREALLOCATED
+ if (surface) {
+ int bpl;
+ uchar *mem = QDirectFBScreen::lockSurface(surface, DSLF_WRITE, &bpl);
+ if (mem) {
+ const int h = img.height();
+ const int w = img.width() * img.depth() / 8;
+ for (int i = 0; i < h; ++i) {
+ memcpy(mem, img.scanLine(i), w);
+ mem += bpl;
+ }
+ surface->Unlock(surface);
+ }
+ }
+#endif
+#ifndef QT_NO_DIRECTFB_PALETTE
+ if (img.numColors() != 0 && surface)
+ QDirectFBScreen::setSurfaceColorTable(surface, img);
+#endif
+ return surface;
+}
+
+IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src,
+ QImage::Format format,
+ SurfaceCreationOptions options)
+{
+ Q_ASSERT(src);
+ QSize size;
+ src->GetSize(src, &size.rwidth(), &size.rheight());
+ IDirectFBSurface *surface = createDFBSurface(size, format, options);
+ DFBSurfacePixelFormat dspf;
+ src->GetPixelFormat(src, &dspf);
+ DFBSurfaceBlittingFlags flags = QDirectFBScreen::hasAlpha(dspf)
+ ? DSBLIT_BLEND_ALPHACHANNEL
+ : DSBLIT_NOFX;
+ if (flags & DSBLIT_BLEND_ALPHACHANNEL)
+ surface->Clear(surface, 0, 0, 0, 0);
+
+ surface->SetBlittingFlags(surface, flags);
+ surface->Blit(surface, src, 0, 0, 0);
+ surface->ReleaseSource(surface);
+ return surface;
+}
+
+IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size,
+ QImage::Format format,
+ SurfaceCreationOptions options)
+{
+ DFBSurfaceDescription desc;
+ desc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH|DSDESC_HEIGHT);
+ if (!QDirectFBScreen::initSurfaceDescriptionPixelFormat(&desc, format))
+ return 0;
+ desc.width = size.width();
+ desc.height = size.height();
+ return createDFBSurface(&desc, options);
+}
+
+
+IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription *desc, SurfaceCreationOptions options)
{
DFBResult result;
IDirectFBSurface* newSurface = 0;
@@ -143,22 +228,43 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription*
if (d_ptr->videoonly && !(desc->flags & DSDESC_PREALLOCATED)) {
// Add the video only capability. This means the surface will be created in video ram
DFBSurfaceDescription voDesc = *desc;
- voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY);
- voDesc.flags = DFBSurfaceDescriptionFlags(voDesc.flags | DSDESC_CAPS);
+ if (!(voDesc.flags & DSDESC_CAPS)) {
+ voDesc.caps = DSCAPS_VIDEOONLY;
+ voDesc.flags = DFBSurfaceDescriptionFlags(voDesc.flags | DSDESC_CAPS);
+ } else {
+ 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)
result = d_ptr->dfb->CreateSurface(d_ptr->dfb, desc, &newSurface);
if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::createDFBSurface", result);
+ qWarning("QDirectFBScreen::createDFBSurface() Failed!\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));
return 0;
}
Q_ASSERT(newSurface);
- if (track) {
+ if (options & TrackSurface) {
d_ptr->allocatedSurfaces.insert(newSurface);
//qDebug("Created a new DirectFB surface at %p. New count = %d",
@@ -168,8 +274,69 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription*
return newSurface;
}
-void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface* surface)
+IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img,
+ QImage::Format pixmapFormat,
+ SurfaceCreationOptions options)
+{
+ QImage image = img;
+ if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN
+#ifdef QT_NO_DIRECTFB_PREALLOCATED
+ || image.format() != pixmapFormat
+#endif
+#ifdef QT_NO_DIRECTFB_PALETTE
+ || image.numColors() != 0
+#endif
+ ) {
+ image = image.convertToFormat(pixmapFormat);
+ }
+
+ IDirectFBSurface *dfbSurface = createDFBSurface(image.size(), pixmapFormat, options);
+ if (!dfbSurface) {
+ qWarning("QDirectFBPixmapData::fromImage() Couldn't create surface");
+ return 0;
+ }
+
+#ifndef QT_NO_DIRECTFB_PREALLOCATED
+ IDirectFBSurface *imgSurface = createDFBSurface(image, DontTrackSurface);
+ if (!imgSurface) {
+ qWarning("QDirectFBPixmapData::fromImage()");
+ QDirectFBScreen::releaseDFBSurface(dfbSurface);
+ return 0;
+ }
+
+ Q_ASSERT(imgSurface);
+ DFBSurfaceBlittingFlags flags = img.hasAlphaChannel()
+ ? DSBLIT_BLEND_ALPHACHANNEL
+ : DSBLIT_NOFX;
+ if (flags & DSBLIT_BLEND_ALPHACHANNEL)
+ dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
+
+ dfbSurface->SetBlittingFlags(dfbSurface, flags);
+ DFBResult result = dfbSurface->Blit(dfbSurface, imgSurface, 0, 0, 0);
+ if (result != DFB_OK)
+ DirectFBError("QDirectFBPixmapData::fromImage()", result);
+ dfbSurface->ReleaseSource(dfbSurface);
+ imgSurface->Release(imgSurface);
+#else // QT_NO_DIRECTFB_PREALLOCATED
+ Q_ASSERT(image.format() == pixmapFormat);
+ int bpl;
+ uchar *mem = QDirectFBScreen::lockSurface(dfbSurface, DSLF_WRITE, &bpl);
+ if (mem) {
+ const int h = image.height();
+ const int w = image.width() * image.depth() / 8;
+ for (int i=0; i<h; ++i) {
+ memcpy(mem, image.scanLine(i), w);
+ mem += bpl;
+ }
+ dfbSurface->Unlock(dfbSurface);
+ }
+#endif
+ return dfbSurface;
+}
+
+void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface *surface)
{
+ Q_ASSERT(QDirectFBScreen::instance());
Q_ASSERT(surface);
surface->Release(surface);
if (!d_ptr->allocatedSurfaces.remove(surface))
@@ -200,9 +367,9 @@ IDirectFBDisplayLayer* QDirectFBScreen::dfbDisplayLayer()
}
#endif
-DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(const QImage &image)
+DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(QImage::Format format)
{
- switch (image.format()) {
+ switch (format) {
#ifndef QT_NO_DIRECTFB_PALETTE
case QImage::Format_Indexed8:
return DSPF_LUT8;
@@ -233,8 +400,11 @@ DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(const QImage &image
};
}
-QImage::Format QDirectFBScreen::getImageFormat(DFBSurfacePixelFormat format)
+QImage::Format QDirectFBScreen::getImageFormat(IDirectFBSurface *surface)
{
+ DFBSurfacePixelFormat format;
+ surface->GetPixelFormat(surface, &format);
+
switch (format) {
case DSPF_LUT8:
return QImage::Format_Indexed8;
@@ -257,8 +427,14 @@ QImage::Format QDirectFBScreen::getImageFormat(DFBSurfacePixelFormat format)
return QImage::Format_RGB666;
case DSPF_RGB32:
return QImage::Format_RGB32;
- case DSPF_ARGB:
- return QImage::Format_ARGB32_Premultiplied;
+ case DSPF_ARGB: {
+ DFBSurfaceCapabilities caps;
+ const DFBResult result = surface->GetCapabilities(surface, &caps);
+ Q_ASSERT(result == DFB_OK);
+ Q_UNUSED(result);
+ return (caps & DSCAPS_PREMULTIPLIED
+ ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_ARGB32); }
default:
break;
}
@@ -268,38 +444,32 @@ QImage::Format QDirectFBScreen::getImageFormat(DFBSurfacePixelFormat format)
DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const QImage &image)
{
DFBSurfaceDescription description;
- DFBSurfacePixelFormat format = getSurfacePixelFormat(image);
+
+ const DFBSurfacePixelFormat format = getSurfacePixelFormat(image.format());
if (format == DSPF_UNKNOWN || image.isNull()) {
description.flags = DFBSurfaceDescriptionFlags(0);
return description;
}
- description.flags = DFBSurfaceDescriptionFlags(DSDESC_CAPS
- | DSDESC_WIDTH
+ description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH
| DSDESC_HEIGHT
- | DSDESC_PIXELFORMAT
- | DSDESC_PREALLOCATED);
-
- description.caps = DSCAPS_NONE;
+#ifndef QT_NO_DIRECTFB_PREALLOCATED
+ | DSDESC_PREALLOCATED
+#endif
+ | DSDESC_PIXELFORMAT);
+ QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, image.format());
description.width = image.width();
description.height = image.height();
- description.pixelformat = format;
+#ifndef QT_NO_DIRECTFB_PREALLOCATED
description.preallocated[0].data = (void*)(image.bits());
description.preallocated[0].pitch = image.bytesPerLine();
description.preallocated[1].data = 0;
description.preallocated[1].pitch = 0;
+#endif
- switch (image.format()) {
- case QImage::Format_ARGB32_Premultiplied:
- case QImage::Format_ARGB8565_Premultiplied:
- case QImage::Format_ARGB6666_Premultiplied:
- case QImage::Format_ARGB8555_Premultiplied:
- case QImage::Format_ARGB4444_Premultiplied:
+ if (QDirectFBScreen::isPremultiplied(image.format()))
description.caps = DSCAPS_PREMULTIPLIED;
- default:
- break;
- }
return description;
}
@@ -337,7 +507,7 @@ void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface,
if (numColors == 0)
return;
- QVarLengthArray<DFBColor> colors(numColors);
+ QVarLengthArray<DFBColor, 256> colors(numColors);
for (int i = 0; i < numColors; ++i) {
QRgb c = image.color(i);
colors[i].a = qAlpha(c);
@@ -362,50 +532,6 @@ void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface,
palette->Release(palette);
}
-void QDirectFBScreen::setImageColorTable(QImage *image, IDirectFBSurface *surface)
-{
- if (!image || !surface || image->depth() > 8)
- return;
-
- IDirectFBPalette *palette = 0;
- unsigned int numColors = 0;
- DFBResult result;
- do {
- result = surface->GetPalette(surface, &palette);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setImageColorTable GetPalette", result);
- break;
- }
-
- result = palette->GetSize(palette, &numColors);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setImageColorTable GetPalette", result);
- break;
- }
-
- if (numColors == 0)
- break;
-
- QVarLengthArray<DFBColor> dfbColors(numColors);
- result = palette->GetEntries(palette, dfbColors.data(), numColors, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setImageColorTable GetPalette", result);
- break;
- }
-
- QVector<QRgb> qtColors(numColors);
- for (unsigned int i=0; i<numColors; ++i) {
- const DFBColor &col = dfbColors[i];
- qtColors[i] = qRgba(col.r, col.g, col.b, col.a);
- }
- image->setColorTable(qtColors);
-
- } while (0);
-
- if (palette)
- palette->Release(palette);
-}
-
#endif // QT_NO_DIRECTFB_PALETTE
#if !defined(QT_NO_DIRECTFB_LAYER) && !defined(QT_NO_QWS_CURSOR)
@@ -505,18 +631,10 @@ void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty)
} else if (!image.isNull() && implicitHide) {
show();
}
+ cursor = image.convertToFormat(QDirectFBScreen::instance()->alphaPixmapFormat());
if (!image.isNull()) {
-#ifdef QT_NO_DIRECTFB_PALETTE
- if (image.numColors() > 0)
- cursor = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- else
-#endif
- if (image.format() == QImage::Format_Indexed8) {
- cursor = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- } else {
- cursor = image;
- }
+ Q_ASSERT(cursor.numColors() == 0);
size = cursor.size();
hotspot = QPoint(hotx, hoty);
@@ -524,15 +642,12 @@ void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty)
description = QDirectFBScreen::getSurfaceDescription(cursor);
IDirectFBSurface *surface;
- surface = QDirectFBScreen::instance()->createDFBSurface(&description);
+ surface = QDirectFBScreen::instance()->createDFBSurface(&description,
+ QDirectFBScreen::TrackSurface);
if (!surface) {
qWarning("QDirectFBScreenCursor::set: Unable to create surface");
return;
}
-#ifndef QT_NO_DIRECTFB_PALETTE
- QDirectFBScreen::setSurfaceColorTable(surface, cursor);
-#endif
-
DFBResult result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
if (result != DFB_OK) {
DirectFBError("QDirectFBScreenCursor::set: "
@@ -611,7 +726,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(','),
@@ -630,6 +745,8 @@ void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args)
qWarning("QDirectFBScreen: Unknown flip argument: %s",
qPrintable(flip));
}
+ } else {
+ flipFlags = DFBSurfaceFlipFlags(DSFLIP_BLIT);
}
}
@@ -659,6 +776,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;
@@ -680,7 +809,7 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
}
const QStringList displayArgs = displaySpec.split(QLatin1Char(':'),
- QString::SkipEmptyParts);
+ QString::SkipEmptyParts);
d_ptr->setFlipFlags(displayArgs);
@@ -704,23 +833,57 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
DFBSurfaceDescription description;
description.flags = DFBSurfaceDescriptionFlags(DSDESC_CAPS);
- description.caps = DFBSurfaceCapabilities(DSCAPS_PRIMARY
- | DSCAPS_DOUBLE
- | DSCAPS_STATIC_ALLOC);
- if (!(d_ptr->flipFlags & DSFLIP_BLIT)) {
- description.caps = DFBSurfaceCapabilities(description.caps
- | DSCAPS_DOUBLE
- | DSCAPS_TRIPLE);
+ 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);
+ uint caps = DSCAPS_PRIMARY|DSCAPS_DOUBLE;
+ if (displayArgs.contains(QLatin1String("static_alloc")))
+ caps |= DSCAPS_STATIC_ALLOC;
+
+ if (displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive)) {
+ caps |= DSCAPS_PREMULTIPLIED;
}
-
+ description.caps = DFBSurfaceCapabilities(caps);
// We don't track the primary surface as it's released in disconnect
- d_ptr->dfbSurface = createDFBSurface(&description, false);
+ d_ptr->dfbSurface = createDFBSurface(&description, DontTrackSurface);
if (!d_ptr->dfbSurface) {
DirectFBError("QDirectFBScreen: error creating primary surface",
result);
return false;
}
+
+ // Work out what format we're going to use for surfaces with an alpha channel
+ d_ptr->alphaPixmapFormat = QDirectFBScreen::getImageFormat(d_ptr->dfbSurface);
+ setPixelFormat(d_ptr->alphaPixmapFormat);
+ switch (d_ptr->alphaPixmapFormat) {
+ case QImage::Format_RGB666:
+ d_ptr->alphaPixmapFormat = QImage::Format_ARGB6666_Premultiplied;
+ break;
+ case QImage::Format_RGB444:
+ d_ptr->alphaPixmapFormat = QImage::Format_ARGB4444_Premultiplied;
+ break;
+ case QImage::NImageFormats:
+ case QImage::Format_Invalid:
+ case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
+ case QImage::Format_Indexed8:
+ case QImage::Format_RGB32:
+ case QImage::Format_RGB888:
+ case QImage::Format_RGB16:
+ case QImage::Format_RGB555:
+ d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
+ break;
+ case QImage::Format_ARGB32:
+ case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_ARGB8555_Premultiplied:
+ case QImage::Format_ARGB8565_Premultiplied:
+ case QImage::Format_ARGB6666_Premultiplied:
+ // works already
+ break;
+ }
d_ptr->dfbSurface->GetSize(d_ptr->dfbSurface, &w, &h);
data = 0;
@@ -736,21 +899,11 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
else
DirectFBError("QDirectFBScreen: error getting surface format", result);
- setPixelFormat(getImageFormat(format));
+ 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);
@@ -803,16 +956,15 @@ void QDirectFBScreen::disconnect()
bool QDirectFBScreen::initDevice()
{
- QWSServer *server = QWSServer::instance();
#ifndef QT_NO_DIRECTFB_MOUSE
if (qgetenv("QWS_MOUSE_PROTO").isEmpty()) {
- server->setDefaultMouse("None");
+ QWSServer::instance()->setDefaultMouse("None");
d_ptr->mouse = new QDirectFBMouseHandler;
}
#endif
#ifndef QT_NO_DIRECTFB_KEYBOARD
if (qgetenv("QWS_KEYBOARD").isEmpty()) {
- server->setDefaultKeyboard("None");
+ QWSServer::instance()->setDefaultKeyboard("None");
d_ptr->keyboard = new QDirectFBKeyboardHandler(QString());
}
#endif
@@ -858,19 +1010,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);
}
@@ -903,7 +1057,7 @@ void QDirectFBScreen::compose(const QRegion &region)
if (surface->key() == QLatin1String("directfb")) {
QDirectFBSurface *s = static_cast<QDirectFBSurface*>(surface);
- blit(s->directFbSurface(), offset, r);
+ blit(s->directFBSurface(), offset, r);
} else {
blit(surface->image(), offset, r);
}
@@ -952,11 +1106,12 @@ void QDirectFBScreen::compose(const QRegion &region)
if (surface->key() == QLatin1String("directfb")) {
QDirectFBSurface *s = static_cast<QDirectFBSurface*>(surface);
- blit(s->directFbSurface(), offset, r);
+ blit(s->directFBSurface(), offset, r);
} else {
blit(surface->image(), offset, r);
}
}
+ d_ptr->dfbSurface->ReleaseSource(d_ptr->dfbSurface);
}
// Normally, when using DirectFB to compose the windows (I.e. when
@@ -998,21 +1153,14 @@ void QDirectFBScreen::exposeRegion(QRegion r, int changing)
void QDirectFBScreen::blit(const QImage &img, const QPoint &topLeft,
const QRegion &reg)
{
- IDirectFBSurface *src = 0;
- DFBSurfaceDescription description = getSurfaceDescription(img);
-
- src = createDFBSurface(&description);
+ IDirectFBSurface *src = createDFBSurface(img, QDirectFBScreen::DontTrackSurface);
if (!src) {
qWarning("QDirectFBScreen::blit(): Error creating surface");
return;
}
-#ifndef QT_NO_DIRECTFB_PALETTE
- setSurfaceColorTable(d_ptr->dfbSurface, img);
-#endif
-
blit(src, topLeft, reg);
-
- releaseDFBSurface(src);
+ d_ptr->dfbSurface->ReleaseSource(d_ptr->dfbSurface);
+ src->Release(src);
}
void QDirectFBScreen::blit(IDirectFBSurface *src, const QPoint &topLeft,
@@ -1043,25 +1191,68 @@ void QDirectFBScreen::blit(IDirectFBSurface *src, const QPoint &topLeft,
points.data(), n);
}
+// This function is only ever called by QScreen::drawBackground which
+// is only ever called by QScreen::compose which is never called with
+// DirectFB so it's really a noop.
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) {
+ data = QDirectFBScreen::lockSurface(d_ptr->dfbSurface, DSLF_WRITE, &lstep);
+ if (!data)
+ return;
+
+ QScreen::solidFill(color, region);
+ d_ptr->dfbSurface->Unlock(d_ptr->dfbSurface);
+ data = 0;
+ lstep = 0;
+ } 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());
+ }
+ }
+}
+
+QImage::Format QDirectFBScreen::alphaPixmapFormat() const
+{
+ return d_ptr->alphaPixmapFormat;
+}
+
+bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description,
+ QImage::Format format)
+{
+ const DFBSurfacePixelFormat pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
+ if (pixelformat == DSPF_UNKNOWN)
+ return false;
+ description->flags = DFBSurfaceDescriptionFlags(description->flags | DSDESC_PIXELFORMAT);
+ description->pixelformat = pixelformat;
+ if (QDirectFBScreen::isPremultiplied(format)) {
+ if (!(description->flags & DSDESC_CAPS)) {
+ description->caps = DSCAPS_PREMULTIPLIED;
+ description->flags = DFBSurfaceDescriptionFlags(description->flags | DSDESC_CAPS);
+ } else {
+ description->caps = DFBSurfaceCapabilities(description->caps | DSCAPS_PREMULTIPLIED);
+ }
+ }
+ return true;
+}
+
+uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl)
+{
+ void *mem;
+ const DFBResult result = surface->Lock(surface, flags, static_cast<void**>(&mem), bpl);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBPixmapData::lockSurface()", result);
}
- 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());
+ return reinterpret_cast<uchar*>(mem);
}