macOS: Implement QCocoaBackingStore in terms of QRasterBackingStore

The previous detection of device pixel ratio changes in paintDevice()
is not needed, as QBackingStore::beginPaint() already does this check
and calls resize().

Change-Id: I9ee8410fa3a5404c5ec19d2cba4543a9e3359fe9
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Tor Arne Vestbø 2016-09-08 23:08:29 +02:00 committed by Tor Arne Vestbø
parent 41ab34d9e8
commit 2d2d90781a
6 changed files with 35 additions and 86 deletions

View File

@ -62,13 +62,20 @@ void QRasterBackingStore::resize(const QSize &size, const QRegion &staticContent
if (m_image.size() == effectiveBufferSize) if (m_image.size() == effectiveBufferSize)
return; return;
QImage::Format format = window()->format().hasAlpha() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; m_image = QImage(effectiveBufferSize, format());
m_image = QImage(effectiveBufferSize, format);
m_image.setDevicePixelRatio(windowDevicePixelRatio); m_image.setDevicePixelRatio(windowDevicePixelRatio);
if (format == QImage::Format_ARGB32_Premultiplied) if (m_image.format() == QImage::Format_ARGB32_Premultiplied)
m_image.fill(Qt::transparent); m_image.fill(Qt::transparent);
} }
QImage::Format QRasterBackingStore::format() const
{
if (window()->format().hasAlpha())
return QImage::Format_ARGB32_Premultiplied;
else
return QImage::Format_RGB32;
}
QPaintDevice *QRasterBackingStore::paintDevice() QPaintDevice *QRasterBackingStore::paintDevice()
{ {
return &m_image; return &m_image;

View File

@ -62,13 +62,16 @@ public:
QRasterBackingStore(QWindow *window); QRasterBackingStore(QWindow *window);
~QRasterBackingStore(); ~QRasterBackingStore();
QPaintDevice *paintDevice() Q_DECL_OVERRIDE; void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
QImage toImage() const Q_DECL_OVERRIDE;
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &region) Q_DECL_OVERRIDE; void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
QImage toImage() const Q_DECL_OVERRIDE;
protected: protected:
virtual QImage::Format format() const;
QImage m_image; QImage m_image;
}; };

View File

@ -29,6 +29,6 @@ unix:!darwin:qtConfig(dbus) {
include(dbusmenu/dbusmenu.pri) include(dbusmenu/dbusmenu.pri)
include(dbustray/dbustray.pri) include(dbustray/dbustray.pri)
} }
uikit: include(graphics/graphics.pri) darwin: include(graphics/graphics.pri)
load(qt_module) load(qt_module)

View File

@ -40,33 +40,20 @@
#ifndef QBACKINGSTORE_COCOA_H #ifndef QBACKINGSTORE_COCOA_H
#define QBACKINGSTORE_COCOA_H #define QBACKINGSTORE_COCOA_H
#include <AppKit/AppKit.h> #include <QtPlatformSupport/private/qrasterbackingstore_p.h>
#include "qcocoawindow.h"
#include "qnsview.h"
#include <qpa/qplatformbackingstore.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QCocoaBackingStore : public QPlatformBackingStore class QCocoaBackingStore : public QRasterBackingStore
{ {
public: public:
QCocoaBackingStore(QWindow *window); QCocoaBackingStore(QWindow *window);
~QCocoaBackingStore(); ~QCocoaBackingStore();
QPaintDevice *paintDevice() Q_DECL_OVERRIDE; void flush(QWindow *, const QRegion &, const QPoint &) Q_DECL_OVERRIDE;
void flush(QWindow *widget, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
QImage toImage() const Q_DECL_OVERRIDE;
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
qreal getBackingStoreDevicePixelRatio();
private: private:
QImage m_qImage; QImage::Format format() const Q_DECL_OVERRIDE;
QSize m_requestedSize;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -38,13 +38,13 @@
****************************************************************************/ ****************************************************************************/
#include "qcocoabackingstore.h" #include "qcocoabackingstore.h"
#include <QtGui/QPainter>
#include "qcocoahelpers.h" #include "qcocoawindow.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QCocoaBackingStore::QCocoaBackingStore(QWindow *window) QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
: QPlatformBackingStore(window) : QRasterBackingStore(window)
{ {
} }
@ -54,69 +54,21 @@ QCocoaBackingStore::~QCocoaBackingStore()
[cocoaWindow->m_qtView clearBackingStore:this]; [cocoaWindow->m_qtView clearBackingStore:this];
} }
QPaintDevice *QCocoaBackingStore::paintDevice() QImage::Format QCocoaBackingStore::format() const
{ {
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle()); if (static_cast<QCocoaWindow *>(window()->handle())->m_drawContentBorderGradient)
int windowDevicePixelRatio = int(cocoaWindow->devicePixelRatio()); return QImage::Format_ARGB32_Premultiplied;
// Receate the backing store buffer if the effective buffer size has changed, return QRasterBackingStore::format();
// either due to a window resize or devicePixelRatio change.
QSize effectiveBufferSize = m_requestedSize * windowDevicePixelRatio;
if (m_qImage.size() != effectiveBufferSize) {
QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient)
? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
m_qImage = QImage(effectiveBufferSize, format);
m_qImage.setDevicePixelRatio(windowDevicePixelRatio);
if (format == QImage::Format_ARGB32_Premultiplied)
m_qImage.fill(Qt::transparent);
}
return &m_qImage;
} }
void QCocoaBackingStore::flush(QWindow *win, const QRegion &region, const QPoint &offset) void QCocoaBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{ {
if (!m_qImage.isNull()) { if (m_image.isNull())
if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(win->handle())) return;
if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle()))
[cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset]; [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset];
}
}
QImage QCocoaBackingStore::toImage() const
{
return m_qImage;
}
void QCocoaBackingStore::resize(const QSize &size, const QRegion &)
{
m_requestedSize = size;
}
bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy)
{
extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
const qreal devicePixelRatio = m_qImage.devicePixelRatio();
QPoint qpoint(dx * devicePixelRatio, dy * devicePixelRatio);
for (const QRect &rect : area) {
const QRect qrect(rect.topLeft() * devicePixelRatio, rect.size() * devicePixelRatio);
qt_scrollRectInImage(m_qImage, qrect, qpoint);
}
return true;
}
void QCocoaBackingStore::beginPaint(const QRegion &region)
{
if (m_qImage.hasAlphaChannel()) {
QPainter p(&m_qImage);
p.setCompositionMode(QPainter::CompositionMode_Source);
const QColor blank = Qt::transparent;
for (const QRect &rect : region)
p.fillRect(rect, blank);
}
}
qreal QCocoaBackingStore::getBackingStoreDevicePixelRatio()
{
return m_qImage.devicePixelRatio();
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -495,7 +495,7 @@ static bool _q_dontOverrideCtrlLMB = false;
qCDebug(lcQpaCocoaWindow) << "[QNSView flushBackingStore:]" << m_window << region.rectCount() << region.boundingRect() << offset; qCDebug(lcQpaCocoaWindow) << "[QNSView flushBackingStore:]" << m_window << region.rectCount() << region.boundingRect() << offset;
m_backingStore = backingStore; m_backingStore = backingStore;
m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio(); m_backingStoreOffset = offset * m_backingStore->paintDevice()->devicePixelRatio();
for (const QRect &rect : region) for (const QRect &rect : region)
[self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; [self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
} }
@ -577,7 +577,7 @@ static bool _q_dontOverrideCtrlLMB = false;
// The backing store source rect will be larger on retina displays. // The backing store source rect will be larger on retina displays.
// Scale dirtyRect by the device pixel ratio: // Scale dirtyRect by the device pixel ratio:
const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio(); const qreal devicePixelRatio = m_backingStore->paintDevice()->devicePixelRatio();
CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio, CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio,
dirtyRect.origin.y * devicePixelRatio, dirtyRect.origin.y * devicePixelRatio,
dirtyRect.size.width * devicePixelRatio, dirtyRect.size.width * devicePixelRatio,