diff options
Diffstat (limited to 'src/plugins')
6 files changed, 149 insertions, 44 deletions
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp index e4ce81bd24..be013f027b 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -66,6 +66,16 @@ static inline QWindowsDirect2DPlatformPixmap *platformPixmap(QPixmap *p) return static_cast<QWindowsDirect2DPlatformPixmap *>(p->handle()); } +static inline QWindowsDirect2DBitmap *bitmap(QPixmap *p) +{ + return platformPixmap(p)->bitmap(); +} + +static inline QWindowsDirect2DWindow *nativeWindow(QWindow *window) +{ + return static_cast<QWindowsDirect2DWindow *>(window->handle()); +} + QWindowsDirect2DBackingStore::QWindowsDirect2DBackingStore(QWindow *window) : QPlatformBackingStore(window) { @@ -77,36 +87,40 @@ QWindowsDirect2DBackingStore::~QWindowsDirect2DBackingStore() void QWindowsDirect2DBackingStore::beginPaint(const QRegion &) { - platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->begin(); + bitmap(nativeWindow(window())->pixmap())->deviceContext()->begin(); } void QWindowsDirect2DBackingStore::endPaint() { - platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->end(); + bitmap(nativeWindow(window())->pixmap())->deviceContext()->end(); } QPaintDevice *QWindowsDirect2DBackingStore::paintDevice() { - return m_pixmap.data(); + return nativeWindow(window())->pixmap(); } -void QWindowsDirect2DBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +void QWindowsDirect2DBackingStore::flush(QWindow *targetWindow, const QRegion ®ion, const QPoint &offset) { - QPlatformWindow *pw = window->handle(); - if (pw && m_pixmap) - static_cast<QWindowsDirect2DWindow *>(pw)->flush(platformPixmap(m_pixmap.data())->bitmap(), region, offset); + if (targetWindow != window()) { + QSharedPointer<QWindowsDirect2DBitmap> copy(nativeWindow(window())->copyBackBuffer()); + nativeWindow(targetWindow)->flush(copy.data(), region, offset); + } + + nativeWindow(targetWindow)->present(); } void QWindowsDirect2DBackingStore::resize(const QSize &size, const QRegion ®ion) { - Q_UNUSED(region); + QPixmap old = nativeWindow(window())->pixmap()->copy(); - QScopedPointer<QPixmap> oldPixmap(m_pixmap.take()); - m_pixmap.reset(new QPixmap(size.width(), size.height())); + nativeWindow(window())->resizeSwapChain(size); + QPixmap *newPixmap = nativeWindow(window())->pixmap(); - if (oldPixmap) { - foreach (const QRect &rect, region.rects()) - platformPixmap(m_pixmap.data())->copy(oldPixmap->handle(), rect); + if (!old.isNull()) { + foreach (const QRect &rect, region.rects()) { + platformPixmap(newPixmap)->copy(old.handle(), rect); + } } } diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h index fc6802aaa2..71e9437274 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE +class QWindowsDirect2DWindow; + class QWindowsDirect2DBackingStore : public QPlatformBackingStore { Q_DISABLE_COPY(QWindowsDirect2DBackingStore) @@ -62,11 +64,8 @@ public: void endPaint(); QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; + void flush(QWindow *targetWindow, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE; - -private: - QScopedPointer<QPixmap> m_pixmap; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp index 072c4b3c0e..d9f7c595ca 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -56,12 +56,27 @@ class QWindowsDirect2DPlatformPixmapPrivate { public: QWindowsDirect2DPlatformPixmapPrivate() - : bitmap(new QWindowsDirect2DBitmap) - , device(new QWindowsDirect2DPaintDevice(bitmap.data(), QInternal::Pixmap)) + : owns_bitmap(true) + , bitmap(new QWindowsDirect2DBitmap) + , device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap)) , devicePixelRatio(1.0) {} - QScopedPointer<QWindowsDirect2DBitmap> bitmap; + QWindowsDirect2DPlatformPixmapPrivate(QWindowsDirect2DBitmap *bitmap) + : owns_bitmap(false) + , bitmap(bitmap) + , device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap)) + , devicePixelRatio(1.0) + {} + + ~QWindowsDirect2DPlatformPixmapPrivate() + { + if (owns_bitmap) + delete bitmap; + } + + bool owns_bitmap; + QWindowsDirect2DBitmap *bitmap; QScopedPointer<QWindowsDirect2DPaintDevice> device; qreal devicePixelRatio; }; @@ -75,6 +90,19 @@ QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(PixelType pixelTy setSerialNumber(qt_d2dpixmap_serno++); } +QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixelType pixelType, + QWindowsDirect2DBitmap *bitmap) + : QPlatformPixmap(pixelType, Direct2DClass) + , d_ptr(new QWindowsDirect2DPlatformPixmapPrivate(bitmap)) +{ + setSerialNumber(qt_d2dpixmap_serno++); + + is_null = false; + w = bitmap->size().width(); + h = bitmap->size().height(); + this->d = 32; +} + QWindowsDirect2DPlatformPixmap::~QWindowsDirect2DPlatformPixmap() { @@ -173,7 +201,7 @@ void QWindowsDirect2DPlatformPixmap::setDevicePixelRatio(qreal scaleFactor) QWindowsDirect2DBitmap *QWindowsDirect2DPlatformPixmap::bitmap() const { Q_D(const QWindowsDirect2DPlatformPixmap); - return d->bitmap.data(); + return d->bitmap; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h index e6684ea423..1936ef0622 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -55,6 +55,9 @@ class QWindowsDirect2DPlatformPixmap : public QPlatformPixmap Q_DECLARE_PRIVATE(QWindowsDirect2DPlatformPixmap) public: QWindowsDirect2DPlatformPixmap(PixelType pixelType); + + // We do NOT take ownership of the bitmap through this constructor! + QWindowsDirect2DPlatformPixmap(PixelType pixelType, QWindowsDirect2DBitmap *bitmap); ~QWindowsDirect2DPlatformPixmap(); virtual void resize(int width, int height); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index 50d0cb81f5..15ec0c3526 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -43,6 +43,7 @@ #include "qwindowsdirect2dwindow.h" #include "qwindowsdirect2ddevicecontext.h" #include "qwindowsdirect2dhelpers.h" +#include "qwindowsdirect2dplatformpixmap.h" #include <d3d11.h> #include <d2d1_1.h> @@ -87,6 +88,13 @@ QWindowsDirect2DWindow::~QWindowsDirect2DWindow() { } +QPixmap *QWindowsDirect2DWindow::pixmap() +{ + setupBitmap(); + + return m_pixmap.data(); +} + void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion ®ion, const QPoint &offset) { DXGI_SWAP_CHAIN_DESC1 desc; @@ -102,32 +110,38 @@ void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion if (!m_bitmap) return; - m_bitmap->deviceContext()->begin(); - - ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get(); - if (!m_needsFullFlush) { - QRegion clipped = region; - clipped &= QRect(0, 0, desc.Width, desc.Height); - - foreach (const QRect &rect, clipped.rects()) { - QRectF rectF(rect); + if (bitmap != m_bitmap.data()) { + m_bitmap->deviceContext()->begin(); + + ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get(); + if (!m_needsFullFlush) { + QRegion clipped = region; + clipped &= QRect(0, 0, desc.Width, desc.Height); + + foreach (const QRect &rect, clipped.rects()) { + QRectF rectF(rect); + dc->DrawBitmap(bitmap->bitmap(), + to_d2d_rect_f(rectF), + 1.0, + D2D1_INTERPOLATION_MODE_LINEAR, + to_d2d_rect_f(rectF.translated(offset.x(), offset.y()))); + } + } else { + QRectF rectF(0, 0, desc.Width, desc.Height); dc->DrawBitmap(bitmap->bitmap(), to_d2d_rect_f(rectF), 1.0, D2D1_INTERPOLATION_MODE_LINEAR, to_d2d_rect_f(rectF.translated(offset.x(), offset.y()))); + m_needsFullFlush = false; } - } else { - QRectF rectF(0, 0, desc.Width, desc.Height); - dc->DrawBitmap(bitmap->bitmap(), - to_d2d_rect_f(rectF), - 1.0, - D2D1_INTERPOLATION_MODE_LINEAR, - to_d2d_rect_f(rectF.translated(offset.x(), offset.y()))); - m_needsFullFlush = false; + + m_bitmap->deviceContext()->end(); } +} - m_bitmap->deviceContext()->end(); +void QWindowsDirect2DWindow::present() +{ m_swapChain->Present(0, 0); } @@ -136,6 +150,7 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size) if (!m_swapChain) return; + m_pixmap.reset(); m_bitmap.reset(); m_deviceContext->SetTarget(Q_NULLPTR); @@ -149,6 +164,43 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size) m_needsFullFlush = true; } +QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() const +{ + const QSharedPointer<QWindowsDirect2DBitmap> null_result; + + if (!m_bitmap) + return null_result; + + D2D1_PIXEL_FORMAT format = m_bitmap->bitmap()->GetPixelFormat(); + D2D1_SIZE_U size = m_bitmap->bitmap()->GetPixelSize(); + + FLOAT dpiX, dpiY; + m_bitmap->bitmap()->GetDpi(&dpiX, &dpiY); + + D2D1_BITMAP_PROPERTIES1 properties = { + format, // D2D1_PIXEL_FORMAT pixelFormat; + dpiX, // FLOAT dpiX; + dpiY, // FLOAT dpiY; + D2D1_BITMAP_OPTIONS_TARGET, // D2D1_BITMAP_OPTIONS bitmapOptions; + Q_NULLPTR // _Field_size_opt_(1) ID2D1ColorContext *colorContext; + }; + ComPtr<ID2D1Bitmap1> copy; + HRESULT hr = m_deviceContext.Get()->CreateBitmap(size, NULL, 0, properties, ©); + + if (FAILED(hr)) { + qWarning("%s: Could not create staging bitmap: %#x", __FUNCTION__, hr); + return null_result; + } + + hr = copy.Get()->CopyFromBitmap(NULL, m_bitmap->bitmap(), NULL); + if (FAILED(hr)) { + qWarning("%s: Could not copy from bitmap! %#x", __FUNCTION__, hr); + return null_result; + } + + return QSharedPointer<QWindowsDirect2DBitmap>(new QWindowsDirect2DBitmap(copy.Get(), Q_NULLPTR)); +} + void QWindowsDirect2DWindow::setupBitmap() { if (m_bitmap) @@ -175,6 +227,10 @@ void QWindowsDirect2DWindow::setupBitmap() } m_bitmap.reset(new QWindowsDirect2DBitmap(backBufferBitmap.Get(), m_deviceContext.Get())); + + QWindowsDirect2DPlatformPixmap *pp = new QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixmapType, + m_bitmap.data()); + m_pixmap.reset(new QPixmap(pp)); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h index 7996904639..47c790da5d 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h @@ -56,16 +56,21 @@ public: QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data); ~QWindowsDirect2DWindow(); + QPixmap *pixmap(); void flush(QWindowsDirect2DBitmap *bitmap, const QRegion ®ion, const QPoint &offset); + void present(); + void resizeSwapChain(const QSize &size); + + QSharedPointer<QWindowsDirect2DBitmap> copyBackBuffer() const; private: - void resizeSwapChain(const QSize &size); void setupBitmap(); private: Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain; Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_deviceContext; QScopedPointer<QWindowsDirect2DBitmap> m_bitmap; + QScopedPointer<QPixmap> m_pixmap; bool m_needsFullFlush; }; |