commit 19284109753d6557f642ac0f4242e1a1efff9944 Author: Gareth Stockwell Date: Fri Aug 20 13:50:59 2010 +0100 Save backing store image each time flush() is called For both the Symbian raster graphics system backing store (QS60WindowSurface) and the OpenVG graphics system backing store (QVGWindowSurface), this patch causes the contents of the backing store to be saved to an image file each time drawing operations are flushed into it. Each image is saved to e:\backingstore__.png, where is a counter which is incremented with each save, and is the address of the top-level widget associated with the backing store. diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index 8bac1f5..bd90530 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -41,6 +41,8 @@ #include // for Q_WS_WIN define (non-PCH) +#include + #include #include #include @@ -185,6 +187,15 @@ void QS60WindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoi if (!drawRect.contains(qr)) widget->winId()->DrawDeferred(); } + + // Dump backing store contents to file system + static int imageIndex = 0; + const QString fileName = QString::fromLatin1("e:\\backingstore_%1_0x%2.png") + .arg(++imageIndex, 4, 10, QChar::fromAscii('0')) + .arg(int(window), 8, 16, QChar::fromAscii('0')); + qDebug() << "QS60WindowSurface::flush" << "fileName" << fileName; + const QImage *image = &(static_cast(d_ptr->device.data_ptr().data())->image); + image->save(fileName); } bool QS60WindowSurface::scroll(const QRegion &area, int dx, int dy) diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp index 55dcef3..ada3a8a 100644 --- a/src/openvg/qwindowsurface_vg.cpp +++ b/src/openvg/qwindowsurface_vg.cpp @@ -47,6 +47,7 @@ #if !defined(QT_NO_EGL) +#include #include #include @@ -81,6 +82,16 @@ void QVGWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoin Q_UNUSED(offset); QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); d_ptr->endPaint(parent, region); + + // Dump backing store contents to file system + static int imageIndex = 0; + const QString fileName = QString::fromLatin1("e:\\backingstore_%1_0x%2.png") + .arg(++imageIndex, 4, 10, QChar::fromAscii('0')) + .arg(int(parent), 8, 16, QChar::fromAscii('0')); + qDebug() << "QVGWindowSurface::flush" << "fileName" << fileName; + if (QImage *image = d_ptr->getSurfaceImage()) + image->save(fileName); + } void QVGWindowSurface::setGeometry(const QRect &rect) diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index e3f52f4..1ecbe46 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -45,6 +45,8 @@ #include "qvgimagepool_p.h" #include "qvg_p.h" +#include + #if !defined(QT_NO_EGL) QT_BEGIN_NAMESPACE @@ -433,12 +435,14 @@ QVGEGLWindowSurfacePrivate::QVGEGLWindowSurfacePrivate(QWindowSurface *win) { winSurface = win; engine = 0; + image = 0; } QVGEGLWindowSurfacePrivate::~QVGEGLWindowSurfacePrivate() { // Destroy the paint engine if it hasn't been destroyed already. destroyPaintEngine(); + delete image; } QVGPaintEngine *QVGEGLWindowSurfacePrivate::paintEngine() @@ -480,6 +484,21 @@ QSize QVGEGLWindowSurfacePrivate::windowSurfaceSize(QWidget *widget) const return newSize; } +QImage* QVGEGLWindowSurfacePrivate::getSurfaceImage() +{ + const QSize size = surfaceSize(); + const QImage::Format format = surfaceFormat(); + if (!image || ((size != image->size()) || (format != image->format()))) { + delete image; + image = 0; + if (QImage::Format_Invalid != format) + image = new QImage(size, format); + } + if (image) + readSurfaceImage(); + return image; +} + #if defined(QVG_VGIMAGE_BACKBUFFERS) QVGEGLWindowSurfaceVGImage::QVGEGLWindowSurfaceVGImage(QWindowSurface *win) @@ -605,6 +624,26 @@ EGLSurface QVGEGLWindowSurfaceVGImage::mainSurface() const return qt_vg_shared_surface(); } +QImage::Format QVGEGLWindowSurfaceVGImage::surfaceFormat() const +{ + return context ? qt_vg_config_to_image_format(context) : QImage::Format_Invalid; +} + +void QVGEGLWindowSurfaceVGImage::readSurfaceImage() +{ + Q_ASSERT(context); + Q_ASSERT(image); + const VGImage vgImage = surfaceImage(); + if (VG_INVALID_HANDLE != vgImage) { + const VGImageFormat format = qt_vg_config_to_vg_format(context); + const QSize size = surfaceSize(); + uchar* data = image->bits(); + const int stride = image->scanLine(1) - image->scanLine(0); + vgGetPixels(vgImage, 0, 0, 0, 0, size.width(), size.height()); + vgGetImageSubData(vgImage, data, stride, format, 0, 0, size.width(), size.height()); + } +} + #endif // QVG_VGIMAGE_BACKBUFFERS QVGEGLWindowSurfaceDirect::QVGEGLWindowSurfaceDirect(QWindowSurface *win) @@ -776,6 +815,22 @@ bool QVGEGLWindowSurfaceDirect::scroll(QWidget *widget, const QRegion& area, int return false; } +QImage::Format QVGEGLWindowSurfaceDirect::surfaceFormat() const +{ + return context ? qt_vg_config_to_image_format(context) : QImage::Format_Invalid; +} + +void QVGEGLWindowSurfaceDirect::readSurfaceImage() +{ + Q_ASSERT(context); + Q_ASSERT(image); + const VGImageFormat format = qt_vg_config_to_vg_format(context); + const QSize size = surfaceSize(); + uchar* data = image->bits(); + const int stride = image->scanLine(1) - image->scanLine(0); + vgReadPixels(data, stride, format, 0, 0, size.width(), size.height()); +} + QT_END_NAMESPACE #endif diff --git a/src/openvg/qwindowsurface_vgegl_p.h b/src/openvg/qwindowsurface_vgegl_p.h index fe62ed3..5557257 100644 --- a/src/openvg/qwindowsurface_vgegl_p.h +++ b/src/openvg/qwindowsurface_vgegl_p.h @@ -79,15 +79,20 @@ public: virtual QSize surfaceSize() const = 0; virtual bool supportsStaticContents() const { return false; } virtual bool scroll(QWidget *, const QRegion&, int, int) { return false; } + QImage* getSurfaceImage(); private: QVGPaintEngine *engine; + virtual QImage::Format surfaceFormat() const = 0; + virtual void readSurfaceImage() = 0; protected: QWindowSurface *winSurface; + QImage *image; void destroyPaintEngine(); QSize windowSurfaceSize(QWidget *widget) const; + }; #if defined(EGL_OPENVG_IMAGE) && !defined(QVG_NO_SINGLE_CONTEXT) @@ -106,6 +111,10 @@ public: VGImage surfaceImage() const; QSize surfaceSize() const { return size; } +private: + QImage::Format surfaceFormat() const; + void readSurfaceImage(); + protected: QEglContext *context; VGImage backBuffer; @@ -133,6 +142,10 @@ public: bool supportsStaticContents() const; bool scroll(QWidget *widget, const QRegion& area, int dx, int dy); +private: + QImage::Format surfaceFormat() const; + void readSurfaceImage(); + protected: QEglContext *context; QSize size;