diff options
Diffstat (limited to 'src/plugins/gfxdrivers')
5 files changed, 87 insertions, 76 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 70a6e02..146a920 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -209,66 +209,60 @@ bool QDirectFBPixmapData::fromData(const uchar *buffer, uint len, const char *fo return QPixmapData::fromData(buffer, len, format, flags); } -template <typename T> class QDirectFBPointer +template <typename T> struct QDirectFBInterfaceCleanupHandler { -public: - QDirectFBPointer(T *tt = 0) : t(tt) {} - ~QDirectFBPointer() { if (t) t->Release(t); } - - inline T* operator->() { return t; } - inline operator T*() { return t; } - - inline T** operator&() { return &t; } - inline bool operator!() const { return !t; } - inline T *data() { return t; } - inline const T *data() const { return t; } + static void cleanup(T *t) { if (t) t->Release(t); } +}; - T *t; +template <typename T> +class QDirectFBPointer : public QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> > +{ +public: + QDirectFBPointer(T *t = 0) + : QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> >(t) + {} }; bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescription &dataBufferDescription) { IDirectFB *dfb = screen->dfb(); Q_ASSERT(dfb); - QDirectFBPointer<IDirectFBDataBuffer> dataBuffer; DFBResult result = DFB_OK; - if ((result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, &dataBuffer)) != DFB_OK) { + IDirectFBDataBuffer *dataBufferPtr; + if ((result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, &dataBufferPtr)) != DFB_OK) { DirectFBError("QDirectFBPixmapData::fromDataBufferDescription()", result); return false; } + QDirectFBPointer<IDirectFBDataBuffer> dataBuffer(dataBufferPtr); -#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE - IDirectFBImageProvider *provider = 0; -#else - QDirectFBPointer<IDirectFBImageProvider> provider; -#endif - if ((result = dataBuffer->CreateImageProvider(dataBuffer, &provider)) != DFB_OK) { + IDirectFBImageProvider *providerPtr; + if ((result = dataBuffer->CreateImageProvider(dataBuffer.data(), &providerPtr)) != DFB_OK) { DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't create image provider", result); return false; } -#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE - screen->setDirectFBImageProvider(provider); -#endif + QDirectFBPointer<IDirectFBImageProvider> provider(providerPtr); + DFBSurfaceDescription surfaceDescription; - if ((result = provider->GetSurfaceDescription(provider, &surfaceDescription)) != DFB_OK) { + if ((result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription)) != DFB_OK) { DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't get surface description", result); return false; } - QDirectFBPointer<IDirectFBSurface> surfaceFromDescription = screen->createDFBSurface(surfaceDescription, QDirectFBScreen::DontTrackSurface, &result); + QDirectFBPointer<IDirectFBSurface> surfaceFromDescription; + surfaceFromDescription.reset(screen->createDFBSurface(surfaceDescription, QDirectFBScreen::DontTrackSurface, &result)); if (!surfaceFromDescription) { DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't create surface", result); return false; } - result = provider->RenderTo(provider, surfaceFromDescription, 0); + result = provider->RenderTo(provider.data(), surfaceFromDescription.data(), 0); if (result != DFB_OK) { DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't render to surface", result); return false; } DFBImageDescription imageDescription; - result = provider->GetImageDescription(provider, &imageDescription); + result = provider->GetImageDescription(provider.data(), &imageDescription); if (result != DFB_OK) { DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't get image description", result); return false; @@ -285,7 +279,7 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX; if (imageDescription.caps & DICAPS_COLORKEY) { blittingFlags |= DSBLIT_SRC_COLORKEY; - result = surfaceFromDescription->SetSrcColorKey(surfaceFromDescription, + result = surfaceFromDescription->SetSrcColorKey(surfaceFromDescription.data(), imageDescription.colorkey_r, imageDescription.colorkey_g, imageDescription.colorkey_b); @@ -305,7 +299,7 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti return false; } - result = dfbSurface->Blit(dfbSurface, surfaceFromDescription, 0, 0, 0); + result = dfbSurface->Blit(dfbSurface, surfaceFromDescription.data(), 0, 0, 0); if (result != DFB_OK) { DirectFBError("QDirectFBPixmapData::fromSurfaceDescription: Can't blit to surface", result); invalidate(); // release dfbSurface @@ -324,6 +318,11 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti #if (Q_DIRECTFB_VERSION >= 0x010000) dfbSurface->ReleaseSource(dfbSurface); #endif +#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE + screen->setDirectFBImageProvider(providerPtr); + provider.take(); +#endif + return true; } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index dbe8926..1bf74d4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1557,5 +1557,36 @@ void QDirectFBScreen::setDirectFBImageProvider(IDirectFBImageProvider *provider) } #endif +IDirectFBSurface * QDirectFBScreen::surfaceForWidget(const QWidget *widget, QRect *rect) const +{ + Q_ASSERT(widget); + if (!widget->isVisible() || widget->size().isNull()) + return 0; + + const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface()); + if (surface && surface->key() == QLatin1String("directfb")) { + return static_cast<const QDirectFBWindowSurface*>(surface)->surfaceForWidget(widget, rect); + } + return 0; +} +IDirectFBSurface *QDirectFBScreen::subSurfaceForWidget(const QWidget *widget, const QRect &area) const +{ + Q_ASSERT(widget); + QRect rect; + IDirectFBSurface *surface = surfaceForWidget(widget, &rect); + IDirectFBSurface *subSurface = 0; + if (surface) { + if (!area.isNull()) + rect &= area.translated(widget->mapTo(widget->window(), QPoint(0, 0))); + if (!rect.isNull()) { + const DFBRectangle subRect = {rect.x(), rect.y(), rect.width(), rect.height() }; + const DFBResult result = surface->GetSubSurface(surface, &subRect, &subSurface); + if (result != DFB_OK) { + DirectFBError("QDirectFBScreen::subSurface(): Can't get sub surface", result); + } + } + } + return subSurface; +} diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 8ec91c7..8af4e0f 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -152,6 +152,9 @@ public: return static_cast<QDirectFBScreen*>(inst); } + IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const; + IDirectFBSurface *subSurfaceForWidget(const QWidget *widget, const QRect &area = QRect()) const; + IDirectFB *dfb(); #ifdef QT_NO_DIRECTFB_WM IDirectFBSurface *primarySurface(); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index 2f240fb..9de1ca5 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -48,8 +48,6 @@ #include <qpaintdevice.h> #include <qvarlengtharray.h> -//#define QT_DIRECTFB_DEBUG_SURFACES 1 - QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr) : QDirectFBPaintDevice(scr) #ifndef QT_NO_DIRECTFB_WM @@ -245,22 +243,19 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect) QByteArray QDirectFBWindowSurface::permanentState() const { - QByteArray state; #ifdef QT_DIRECTFB_WM - QDataStream ds(&state, QIODevice::WriteOnly); - ds << reinterpret_cast<quintptr>(this); -#endif + QByteArray state(sizeof(this), 0); + *reinterpret_cast<const QDirectFBWindowSurface**>(state.data()) = this; return state; +#endif + return QByteArray(); } void QDirectFBWindowSurface::setPermanentState(const QByteArray &state) { #ifdef QT_DIRECTFB_WM - if (state.size() == sizeof(quintptr)) { - QDataStream ds(state); - quintptr ptr; - ds >> ptr; - sibling = reinterpret_cast<QDirectFBWindowSurface*>(ptr); + if (state.size() == sizeof(this)) { + sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData()); } #else Q_UNUSED(state); @@ -418,7 +413,6 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion ®ion, #endif } - void QDirectFBWindowSurface::beginPaint(const QRegion &) { if (!engine) @@ -427,43 +421,28 @@ void QDirectFBWindowSurface::beginPaint(const QRegion &) void QDirectFBWindowSurface::endPaint(const QRegion &) { -#ifdef QT_DIRECTFB_DEBUG_SURFACES - if (bufferImages.count()) { - qDebug("QDirectFBWindowSurface::endPaint() this=%p", this); - - foreach(QImage* bufferImg, bufferImages) - qDebug(" Deleting buffer image %p", bufferImg); - } -#endif - - qDeleteAll(bufferImages); - bufferImages.clear(); unlockDirectFB(); } - -QImage *QDirectFBWindowSurface::buffer(const QWidget *widget) +IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget, QRect *rect) const { - if (!lockedImage) + Q_ASSERT(widget); + if (!dfbSurface) { + if (sibling && (!sibling->sibling || sibling->dfbSurface)) + return sibling->surfaceForWidget(widget, rect); return 0; - - const QRect rect = QRect(offset(widget), widget->size()) - & lockedImage->rect(); - if (rect.isEmpty()) - return 0; - - QImage *img = new QImage(lockedImage->scanLine(rect.y()) - + rect.x() * (lockedImage->depth() / 8), - rect.width(), rect.height(), - lockedImage->bytesPerLine(), - lockedImage->format()); - bufferImages.append(img); - -#ifdef QT_DIRECTFB_DEBUG_SURFACES - qDebug("QDirectFBWindowSurface::buffer() Created & returned %p", img); -#endif - - return img; + } + QWidget *win = window(); + Q_ASSERT(win); + if (rect) { + if (win == widget) { + *rect = widget->rect(); + } else { + *rect = QRect(widget->mapTo(win, QPoint(0, 0)), widget->size()); + } + } + Q_ASSERT(win == widget || widget->isAncestorOf(win)); + return dfbSurface; } void QDirectFBWindowSurface::updateFormat() diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h index 0da3a98..dafc478 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -88,7 +88,7 @@ public: void beginPaint(const QRegion &); void endPaint(const QRegion &); - QImage *buffer(const QWidget *widget); + IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const; private: void updateFormat(); #ifdef QT_DIRECTFB_WM @@ -104,7 +104,6 @@ private: } mode; #endif - QList<QImage*> bufferImages; DFBSurfaceFlipFlags flipFlags; bool boundingRectFlip; #ifdef QT_DIRECTFB_TIMING |