diff options
Diffstat (limited to 'src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp')
-rw-r--r-- | src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 180 |
1 files changed, 144 insertions, 36 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index a53b1c0..c1b75c5 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -84,7 +84,7 @@ public: QImage::Format alphaPixmapFormat; }; -QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen* screen) +QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *screen) : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_NONE) #ifndef QT_NO_DIRECTFB_LAYER , dfbLayer(0) @@ -113,7 +113,7 @@ QDirectFBScreenPrivate::~QDirectFBScreenPrivate() delete keyboard; #endif - foreach (IDirectFBSurface* surf, allocatedSurfaces) + foreach (IDirectFBSurface *surf, allocatedSurfaces) surf->Release(surf); allocatedSurfaces.clear(); @@ -137,7 +137,7 @@ QDirectFBScreenPrivate::~QDirectFBScreenPrivate() // creates a preallocated surface with the same format as the image if // possible. -IDirectFBSurface* QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCreationOptions options) +IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCreationOptions options) { if (img.isNull()) // assert? return 0; @@ -155,8 +155,7 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCr return surface; } - DFBSurfaceDescription desc = QDirectFBScreen::getSurfaceDescription(img); - IDirectFBSurface *surface = createDFBSurface(&desc, options); + IDirectFBSurface *surface = createDFBSurface(QDirectFBScreen::getSurfaceDescription(img), options); #ifdef QT_NO_DIRECTFB_PREALLOCATED if (surface) { int bpl; @@ -211,53 +210,55 @@ IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size, return 0; desc.width = size.width(); desc.height = size.height(); - return createDFBSurface(&desc, options); + return createDFBSurface(desc, options); } -IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription *desc, SurfaceCreationOptions options) +IDirectFBSurface *QDirectFBScreen::createDFBSurface(DFBSurfaceDescription desc, SurfaceCreationOptions options) { - DFBResult result; - IDirectFBSurface* newSurface = 0; + DFBResult result = DFB_OK; + IDirectFBSurface *newSurface = 0; if (!d_ptr->dfb) { qWarning("QDirectFBScreen::createDFBSurface() - not connected"); return 0; } - if (d_ptr->directFBFlags & VideoOnly && !(desc->flags & DSDESC_PREALLOCATED)) { + if (d_ptr->directFBFlags & VideoOnly && !(desc.flags & DSDESC_PREALLOCATED)) { // Add the video only capability. This means the surface will be created in video ram - DFBSurfaceDescription voDesc = *desc; - if (!(voDesc.flags & DSDESC_CAPS)) { - voDesc.caps = DSCAPS_VIDEOONLY; - voDesc.flags = DFBSurfaceDescriptionFlags(voDesc.flags | DSDESC_CAPS); + if (!(desc.flags & DSDESC_CAPS)) { + desc.caps = DSCAPS_VIDEOONLY; + desc.flags = DFBSurfaceDescriptionFlags(desc.flags | DSDESC_CAPS); } else { - voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY); + desc.caps = DFBSurfaceCapabilities(desc.caps | DSCAPS_VIDEOONLY); } - result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &voDesc, &newSurface); + result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &newSurface); if (result != DFB_OK #ifdef QT_NO_DEBUG - && (desc->flags & DSDESC_CAPS) && (desc->caps & DSCAPS_PRIMARY) + && (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, + 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)); } + desc.caps = DFBSurfaceCapabilities(desc.caps & ~DSCAPS_VIDEOONLY); } + if (d_ptr->directFBFlags & SystemOnly) + desc.caps = DFBSurfaceCapabilities(desc.caps | DSCAPS_SYSTEMONLY); if (!newSurface) - result = d_ptr->dfb->CreateSurface(d_ptr->dfb, desc, &newSurface); + result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &newSurface); if (result != DFB_OK) { 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, + 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; } @@ -349,18 +350,18 @@ QDirectFBScreen::DirectFBFlags QDirectFBScreen::directFBFlags() const { return d_ptr->directFBFlags; } -IDirectFB* QDirectFBScreen::dfb() +IDirectFB *QDirectFBScreen::dfb() { return d_ptr->dfb; } -IDirectFBSurface* QDirectFBScreen::dfbSurface() +IDirectFBSurface *QDirectFBScreen::dfbSurface() { return d_ptr->dfbSurface; } #ifndef QT_NO_DIRECTFB_LAYER -IDirectFBDisplayLayer* QDirectFBScreen::dfbDisplayLayer() +IDirectFBDisplayLayer *QDirectFBScreen::dfbDisplayLayer() { return d_ptr->dfbLayer; } @@ -730,7 +731,7 @@ void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args) } } -QPixmapData* QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType type) const +QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType type) const { if (type == QPixmapData::BitmapType) return QWSGraphicsSystem::createPixmapData(type); @@ -738,6 +739,84 @@ QPixmapData* QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType typ return new QDirectFBPixmapData(type); } +#ifdef QT_NO_DEBUG +struct FlagDescription; +static const FlagDescription *accelerationDescriptions = 0; +static const FlagDescription *blitDescriptions = 0; +static const FlagDescription *drawDescriptions = 0; +#else +struct FlagDescription { + const char *name; + uint flag; +}; + +static const FlagDescription accelerationDescriptions[] = { + { "DFXL_NONE ", DFXL_NONE }, + { "DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE }, + { "DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE }, + { "DFXL_DRAWLINE", DFXL_DRAWLINE }, + { "DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE }, + { "DFXL_BLIT", DFXL_BLIT }, + { "DFXL_STRETCHBLIT", DFXL_STRETCHBLIT }, + { "DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES }, + { "DFXL_DRAWSTRING", DFXL_DRAWSTRING }, + { 0, 0 } +}; + +static const FlagDescription blitDescriptions[] = { + { "DSBLIT_NOFX", DSBLIT_NOFX }, + { "DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL }, + { "DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA }, + { "DSBLIT_COLORIZE", DSBLIT_COLORIZE }, + { "DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY }, + { "DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY }, + { "DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY }, + { "DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY }, + { "DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY }, + { "DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE }, + { "DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR }, + { "DSBLIT_XOR", DSBLIT_XOR }, + { "DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION }, + { 0, 0 } +}; + +static const FlagDescription drawDescriptions[] = { + { "DSDRAW_NOFX", DSDRAW_NOFX }, + { "DSDRAW_BLEND", DSDRAW_BLEND }, + { "DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY }, + { "DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY }, + { "DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY }, + { "DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY }, + { "DSDRAW_XOR", DSDRAW_XOR }, + { 0, 0 } +}; +#endif + + + +static const QByteArray flagDescriptions(uint mask, const FlagDescription *flags) +{ +#ifdef QT_NO_DEBUG + Q_UNUSED(mask); + Q_UNUSED(flags); + return QByteArray(""); +#else + if (!mask) + return flags[0].name; + + QStringList list; + for (int i=1; flags[i].name; ++i) { + if (mask & flags[i].flag) { + list.append(QString::fromLatin1(flags[i].name)); + } + } + Q_ASSERT(!list.isEmpty()); + return (QLatin1Char(' ') + list.join(QLatin1String("|"))).toLatin1(); +#endif +} + + + static void printDirectFBInfo(IDirectFB *fb) { DFBResult result; @@ -750,10 +829,13 @@ static void printDirectFBInfo(IDirectFB *fb) } qDebug("Device: %s (%s), Driver: %s v%i.%i (%s)\n" - " acceleration: 0x%x, blit: 0x%x, draw: 0x%0x video: %i\n", + " acceleration: 0x%x%s,\nblit: 0x%x%s,\ndraw: 0x%0x%s\nvideo: %iKB\n", dev.name, dev.vendor, dev.driver.name, dev.driver.major, dev.driver.minor, dev.driver.vendor, dev.acceleration_mask, - dev.blitting_flags, dev.drawing_flags, dev.video_memory); + ::flagDescriptions(dev.acceleration_mask, accelerationDescriptions).constData(), + dev.blitting_flags, ::flagDescriptions(dev.blitting_flags, blitDescriptions).constData(), + dev.drawing_flags, ::flagDescriptions(dev.drawing_flags, drawDescriptions).constData(), + (dev.video_memory >> 10)); } static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value) @@ -806,6 +888,18 @@ bool QDirectFBScreen::connect(const QString &displaySpec) if (displayArgs.contains(QLatin1String("videoonly"), Qt::CaseInsensitive)) d_ptr->directFBFlags |= VideoOnly; + if (displayArgs.contains(QLatin1String("systemonly"), Qt::CaseInsensitive)) { + if (d_ptr->directFBFlags & VideoOnly) { + qWarning("QDirectFBScreen: error. videoonly and systemonly are mutually exclusive"); + } else { + d_ptr->directFBFlags |= SystemOnly; + } + } + + if (displayArgs.contains(QLatin1String("boundingrectflip"), Qt::CaseInsensitive)) { + d_ptr->directFBFlags |= BoundingRectFlip; + } + if (displayArgs.contains(QLatin1String("ignoresystemclip"), Qt::CaseInsensitive)) d_ptr->directFBFlags |= IgnoreSystemClip; @@ -820,9 +914,23 @@ bool QDirectFBScreen::connect(const QString &displaySpec) 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; + struct { + const char *name; + const DFBSurfaceCapabilities cap; + } const capabilities[] = { + { "static_alloc", DSCAPS_STATIC_ALLOC }, + { "triplebuffer", DSCAPS_TRIPLE }, + { "interlaced", DSCAPS_INTERLACED }, + { "separated", DSCAPS_SEPARATED }, +// { "depthbuffer", DSCAPS_DEPTH }, // only makes sense with TextureTriangles which are not supported + { 0, DSCAPS_NONE } + }; + for (int i=0; capabilities[i].name; ++i) { + if (displayArgs.contains(QString::fromLatin1(capabilities[i].name), Qt::CaseInsensitive)) + caps |= capabilities[i].cap; + } if (displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive)) { caps |= DSCAPS_PREMULTIPLIED; @@ -830,7 +938,7 @@ bool QDirectFBScreen::connect(const QString &displaySpec) description.caps = DFBSurfaceCapabilities(caps); // We don't track the primary surface as it's released in disconnect - d_ptr->dfbSurface = createDFBSurface(&description, DontTrackSurface); + d_ptr->dfbSurface = createDFBSurface(description, DontTrackSurface); if (!d_ptr->dfbSurface) { DirectFBError("QDirectFBScreen: error creating primary surface", result); @@ -921,7 +1029,7 @@ void QDirectFBScreen::disconnect() d_ptr->dfbSurface->Release(d_ptr->dfbSurface); d_ptr->dfbSurface = 0; - foreach (IDirectFBSurface* surf, d_ptr->allocatedSurfaces) + foreach (IDirectFBSurface *surf, d_ptr->allocatedSurfaces) surf->Release(surf); d_ptr->allocatedSurfaces.clear(); @@ -990,7 +1098,7 @@ void QDirectFBScreen::blank(bool on) (on ? DSPM_ON : DSPM_SUSPEND)); } -QWSWindowSurface* QDirectFBScreen::createSurface(QWidget *widget) const +QWSWindowSurface *QDirectFBScreen::createSurface(QWidget *widget) const { #ifdef QT_NO_DIRECTFB_WM if (QApplication::type() == QApplication::GuiServer) { @@ -1003,7 +1111,7 @@ QWSWindowSurface* QDirectFBScreen::createSurface(QWidget *widget) const #endif } -QWSWindowSurface* QDirectFBScreen::createSurface(const QString &key) const +QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const { if (key == QLatin1String("directfb")) { return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this)); |