From 5bc4ed0c33bad23ce2988e74ae8e7f9a4e5a3250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 27 Jan 2010 15:02:54 +0100 Subject: Fix QPixmap::fill autotest and cachekey autotest Also make sure it didn't failed with a QFATAL when drawing bitmaps and tried to make sure all surfaces er unlocked when opperations are being performed on them from the windowsurface. There are still test failuers :( --- src/gui/image/qpixmap_blitter.cpp | 35 ++++++++++++++++++++-- src/gui/painting/qpaintengine_blitter.cpp | 2 ++ .../minimaldfb/qblitter_directfb.cpp | 2 ++ .../minimaldfb/qdirectfbconvenience.cpp | 12 ++++---- .../minimaldfb/qgraphicssystem_minimaldfb.cpp | 2 ++ .../minimaldfb/qwindowsurface_minimaldfb.cpp | 7 +++-- .../minimaldfb/qwindowsurface_minimaldfb.h | 2 ++ 7 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index 175c234..6e34fbd 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -5,9 +5,14 @@ #include #include +#include + +static int global_ser_no = 0; + QBlittablePixmapData::QBlittablePixmapData(QPixmapData::PixelType type) : QPixmapData(type,BlitterClass), m_engine(0), m_blittable(0) { + setSerialNumber(++global_ser_no); } QBlittablePixmapData::~QBlittablePixmapData() @@ -21,7 +26,6 @@ QBlittable *QBlittablePixmapData::blittable() const if (!m_blittable) { QBlittablePixmapData *that = const_cast(this); that->m_blittable = QApplicationPrivate::graphicsSystem()->createBlittable(QRect(0,0,w,h)); - that->setSerialNumber(m_blittable->lock()->serialNumber()); } return m_blittable; @@ -77,11 +81,36 @@ int QBlittablePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const void QBlittablePixmapData::fill(const QColor &color) { + //jlind: todo: change when blittables can support non opaque fillRects if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) { blittable()->unlock(); blittable()->fillRect(QRectF(0,0,w,h),color); - }else - blittable()->lock()->fill(color.rgba()); + }else { + uint pixel; + switch (blittable()->lock()->format()) { + case QImage::Format_ARGB32_Premultiplied: + pixel = PREMUL(color.rgba()); + break; + case QImage::Format_ARGB8565_Premultiplied: + pixel = qargb8565(color.rgba()).rawValue(); + break; + case QImage::Format_ARGB8555_Premultiplied: + pixel = qargb8555(color.rgba()).rawValue(); + break; + case QImage::Format_ARGB6666_Premultiplied: + pixel = qargb6666(color.rgba()).rawValue(); + break; + case QImage::Format_ARGB4444_Premultiplied: + pixel = qargb4444(color.rgba()).rawValue(); + break; + default: + pixel = color.rgba(); + break; + } + //so premultiplied formats are supported and ARGB32 and RGB32 + blittable()->lock()->fill(pixel); + } + } QImage *QBlittablePixmapData::buffer() diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp index 0f6b5cf..1a1d5e0 100644 --- a/src/gui/painting/qpaintengine_blitter.cpp +++ b/src/gui/painting/qpaintengine_blitter.cpp @@ -63,6 +63,8 @@ public: bool canBlitterDrawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) const { + if (pm.pixmapData()->classId() != QPixmapData::BlitterClass) + return false; if ((!drawPixmapState) || drawPixmapState & drawPixmapMask) { if (m_capabilities & (QBlittable::SourceOverPixmapCapability | QBlittable::SourceOverScaledPixmapCapability)) { diff --git a/src/plugins/graphicssystems/minimaldfb/qblitter_directfb.cpp b/src/plugins/graphicssystems/minimaldfb/qblitter_directfb.cpp index c2e4b4f..ded57d3 100644 --- a/src/plugins/graphicssystems/minimaldfb/qblitter_directfb.cpp +++ b/src/plugins/graphicssystems/minimaldfb/qblitter_directfb.cpp @@ -33,6 +33,7 @@ QDirectFbBlitter::QDirectFbBlitter(const QRect &rect, IDirectFBSurface *surface) QDirectFbBlitter::~QDirectFbBlitter() { + unlock(); m_surface->Release(m_surface); } @@ -55,6 +56,7 @@ void QDirectFbBlitter::drawPixmap(const QRectF &rect, const QPixmap &pixmap, con Q_ASSERT(data->classId() == QPixmapData::BlitterClass); QBlittablePixmapData *blitPm = static_cast(data); QDirectFbBlitter *dfbBlitter = static_cast(blitPm->blittable()); + dfbBlitter->unlock(); IDirectFBSurface *s = dfbBlitter->m_surface; diff --git a/src/plugins/graphicssystems/minimaldfb/qdirectfbconvenience.cpp b/src/plugins/graphicssystems/minimaldfb/qdirectfbconvenience.cpp index 57d03fc..8594c09 100644 --- a/src/plugins/graphicssystems/minimaldfb/qdirectfbconvenience.cpp +++ b/src/plugins/graphicssystems/minimaldfb/qdirectfbconvenience.cpp @@ -5,11 +5,13 @@ IDirectFB *QDirectFbConvenience::dfbInterface() { - IDirectFB *dfb; - DFBResult result = DirectFBCreate(&dfb); - if (result != DFB_OK) { - DirectFBError("QDirectFBConvenience: error creating DirectFB interface",result); - return 0; + static IDirectFB *dfb = 0; + if (!dfb) { + DFBResult result = DirectFBCreate(&dfb); + if (result != DFB_OK) { + DirectFBError("QDirectFBConvenience: error creating DirectFB interface",result); + return 0; + } } return dfb; } diff --git a/src/plugins/graphicssystems/minimaldfb/qgraphicssystem_minimaldfb.cpp b/src/plugins/graphicssystems/minimaldfb/qgraphicssystem_minimaldfb.cpp index f1f2215..06ae800 100644 --- a/src/plugins/graphicssystems/minimaldfb/qgraphicssystem_minimaldfb.cpp +++ b/src/plugins/graphicssystems/minimaldfb/qgraphicssystem_minimaldfb.cpp @@ -130,6 +130,8 @@ QDirectFbGraphicsSystem::QDirectFbGraphicsSystem() } delete[] argv; + //init directfb + QDirectFbConvenience::dfbInterface(); mPrimaryScreen = new QDirectFbGraphicsSystemScreen(0); mScreens.append(mPrimaryScreen); diff --git a/src/plugins/graphicssystems/minimaldfb/qwindowsurface_minimaldfb.cpp b/src/plugins/graphicssystems/minimaldfb/qwindowsurface_minimaldfb.cpp index 7f3e165..4be61df 100644 --- a/src/plugins/graphicssystems/minimaldfb/qwindowsurface_minimaldfb.cpp +++ b/src/plugins/graphicssystems/minimaldfb/qwindowsurface_minimaldfb.cpp @@ -66,7 +66,7 @@ QDirectFbWindowSurface::QDirectFbWindowSurface(QDirectFbGraphicsSystemScreen *sc qDebug() << "WindowSurface format " << QDirectFbConvenience::imageFormatFromSurfaceFormat(format,caps); - QDirectFbBlitter *blitter = new QDirectFbBlitter(window->rect(), m_dfbSurface); + blitter = new QDirectFbBlitter(window->rect(), m_dfbSurface); m_pmdata = new QBlittablePixmapData(QPixmapData::PixmapType); m_pmdata->setBlittable(blitter); m_pixmap = new QPixmap(m_pmdata); @@ -88,7 +88,7 @@ void QDirectFbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const Q_UNUSED(widget); Q_UNUSED(offset); - m_dfbSurface->Unlock(m_dfbSurface); + blitter->unlock(); const quint8 windowOpacity = quint8(widget->windowOpacity() * 0xff); m_dfbWindow->SetOpacity(m_dfbWindow,windowOpacity); @@ -102,6 +102,7 @@ void QDirectFbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const void QDirectFbWindowSurface::setGeometry(const QRect &rect) { + blitter->unlock(); QWindowSurface::setGeometry(rect); m_dfbWindow->SetBounds(m_dfbWindow, rect.x(),rect.y(), rect.width(), rect.height()); @@ -123,6 +124,7 @@ static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int bool QDirectFbWindowSurface::scroll(const QRegion &area, int dx, int dy) { + blitter->unlock(); if (!m_dfbSurface || area.isEmpty()) return false; m_dfbSurface->SetBlittingFlags(m_dfbSurface, DSBLIT_NOFX); @@ -150,6 +152,7 @@ void QDirectFbWindowSurface::endPaint(const QRegion ®ion) void QDirectFbWindowSurface::setVisible(bool visible) { + blitter->unlock(); if (visible) { int x = this->geometry().x(); int y = this->geometry().y(); diff --git a/src/plugins/graphicssystems/minimaldfb/qwindowsurface_minimaldfb.h b/src/plugins/graphicssystems/minimaldfb/qwindowsurface_minimaldfb.h index f74fb29..088aeba 100644 --- a/src/plugins/graphicssystems/minimaldfb/qwindowsurface_minimaldfb.h +++ b/src/plugins/graphicssystems/minimaldfb/qwindowsurface_minimaldfb.h @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE class QDirectFbGraphicsSystemScreen; +class QDirectFbBlitter; class QDirectFbWindowSurface : public QWindowSurface { @@ -80,6 +81,7 @@ private: IDirectFBWindow *m_dfbWindow; IDirectFBSurface *m_dfbSurface; + QDirectFbBlitter *blitter; }; QT_END_NAMESPACE -- cgit v0.12