From 183602a565147299a309fc4df3165b702f0d78f4 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 5 May 2009 11:25:28 -0700 Subject: Don't call prepare more than necessary Store the memory address of our last QRasterBuffer::prepare() call to make sure we reprepare if someone has unlocked and locked the device behind our back. Also optimize QDirectFBDevice::memory() since it might get called a fair bit. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbpaintdevice.cpp | 36 ++++++++++++---------- .../gfxdrivers/directfb/qdirectfbpaintdevice.h | 7 +++-- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 16 +++++++--- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index 9796280..72e0ce5 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -58,18 +58,18 @@ IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const void QDirectFBPaintDevice::lockDirectFB(uint flags) { - if (lockedImage) { - if (lockFlags & flags) - return; - unlockDirectFB(); - } - if (uchar *mem = QDirectFBScreen::lockSurface(dfbSurface, flags, &bpl)) { - const QSize s = size(); - lockedImage = new QImage(mem, s.width(), s.height(), bpl, - QDirectFBScreen::getImageFormat(dfbSurface)); - lockFlags = flags; - } else { - lockFlags = 0; + if (!(lock & flags)) { + if (lock) + unlockDirectFB(); + if ((mem = QDirectFBScreen::lockSurface(dfbSurface, flags, &bpl))) { + const QSize s = size(); + lockedImage = new QImage(mem, s.width(), s.height(), bpl, + QDirectFBScreen::getImageFormat(dfbSurface)); + lock = flags; + Q_ASSERT(mem); + } else { + lock = 0; + } } } @@ -82,15 +82,19 @@ void QDirectFBPaintDevice::unlockDirectFB() dfbSurface->Unlock(dfbSurface); delete lockedImage; lockedImage = 0; + mem = 0; + lock = 0; } void *QDirectFBPaintDevice::memory() const { - QDirectFBPaintDevice* that = const_cast(this); - that->lockDirectFB(DSLF_READ|DSLF_WRITE); - Q_ASSERT(that->lockedImage); - return that->lockedImage->bits(); + if (lock != (DSLF_READ|DSLF_WRITE)) { + QDirectFBPaintDevice *that = const_cast(this); + that->lockDirectFB(DSLF_READ|DSLF_WRITE); + Q_ASSERT(that->lockedImage); + } + return mem; } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index 1709d69..13f0a8f 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -69,6 +69,7 @@ public: int bytesPerLine() const; QSize size() const; int metric(QPaintDevice::PaintDeviceMetric metric) const; + uint lockFlags() const { return lock; } protected: // Shouldn't create QDirectFBPaintDevice by itself but only sub-class it: QDirectFBPaintDevice(QDirectFBScreen *scr = QDirectFBScreen::instance()) @@ -77,7 +78,8 @@ protected: lockedImage(0), screen(scr), forceRaster(false), - lockFlags(0) + lock(0), + mem(0) {} inline int dotsPerMeterX() const @@ -94,7 +96,8 @@ protected: QDirectFBScreen *screen; int bpl; bool forceRaster; - uint lockFlags; + uint lock; + uchar *mem; private: Q_DISABLE_COPY(QDirectFBPaintDevice) }; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index c77632c..c9752e9 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -336,6 +336,7 @@ private: bool dfbHandledClip; bool ignoreSystemClip; QDirectFBPaintDevice *dfbDevice; + void *lockedMemory; QDirectFBPaintEngine *q; }; @@ -345,7 +346,7 @@ QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p matrixRotShear(false), scale(NoScale), lastLockedHeight(-1), fbWidth(-1), fbHeight(-1), opacity(255), drawFlagsFromCompositionMode(0), blitFlagsFromCompositionMode(0), porterDuffRule(DSPD_SRC_OVER), dirtyClip(true), - dfbHandledClip(false), dfbDevice(0), q(p) + dfbHandledClip(false), dfbDevice(0), lockedMemory(0), q(p) { fb = QDirectFBScreen::instance()->dfb(); ignoreSystemClip = QDirectFBScreen::instance()->directFBFlags() & QDirectFBScreen::IgnoreSystemClip; @@ -392,16 +393,21 @@ void QDirectFBPaintEnginePrivate::lock() // We will potentially get a new pointer to the buffer after a // lock so we need to call the base implementation of prepare so // it updates its rasterBuffer to point to the new buffer address. - lastLockedHeight = dfbDevice->height(); - Q_ASSERT(dfbDevice); - prepare(dfbDevice); + if (dfbDevice->lockFlags() != (DSLF_WRITE|DSLF_READ) + || dfbDevice->height() != lastLockedHeight + || dfbDevice->memory() != lockedMemory) { + prepare(dfbDevice); + lastLockedHeight = dfbDevice->height(); + lockedMemory = dfbDevice->memory(); + } } void QDirectFBPaintEnginePrivate::unlock() { Q_ASSERT(dfbDevice); dfbDevice->unlockDirectFB(); + lockedMemory = 0; } void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m) @@ -436,6 +442,7 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", device->devType()); } + lockedMemory = 0; forceRasterPrimitives = dfbDevice->forceRasterPrimitives(); surface->GetSize(surface, &fbWidth, &fbHeight); @@ -451,6 +458,7 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) void QDirectFBPaintEnginePrivate::end() { + lockedMemory = 0; dfbDevice = 0; surface->ReleaseSource(surface); surface->SetClip(surface, NULL); -- cgit v0.12