summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm26
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm15
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm31
8 files changed, 86 insertions, 14 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 0e1998170a..192ef00649 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -62,6 +62,7 @@ public:
void resize (const QSize &size, const QRegion &);
bool scroll(const QRegion &area, int dx, int dy);
CGImageRef getBackingStoreCGImage();
+ qreal getBackingStoreDevicePixelRatio();
private:
QImage m_qImage;
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 7bd7e4ce38..ec3168ce99 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -59,10 +59,22 @@ QCocoaBackingStore::~QCocoaBackingStore()
QPaintDevice *QCocoaBackingStore::paintDevice()
{
- if (m_qImage.size() != m_requestedSize) {
+ if (m_qImage.size() / m_qImage.devicePixelRatio() != m_requestedSize) {
CGImageRelease(m_cgImage);
m_cgImage = 0;
- m_qImage = QImage(m_requestedSize, QImage::Format_ARGB32_Premultiplied);
+
+ int scaleFactor = 1;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
+ if (cocoaWindow && cocoaWindow->m_contentView) {
+ scaleFactor = int([[cocoaWindow->m_contentView window] backingScaleFactor]);
+ }
+ }
+#endif
+
+ m_qImage = QImage(m_requestedSize * scaleFactor, QImage::Format_ARGB32_Premultiplied);
+ m_qImage.setDevicePixelRatio(scaleFactor);
}
return &m_qImage;
}
@@ -90,10 +102,11 @@ void QCocoaBackingStore::resize(const QSize &size, const QRegion &)
bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy)
{
extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
- QPoint qpoint(dx, dy);
+ const qreal devicePixelRatio = m_qImage.devicePixelRatio();
+ QPoint qpoint(dx * devicePixelRatio, dy * devicePixelRatio);
const QVector<QRect> qrects = area.rects();
for (int i = 0; i < qrects.count(); ++i) {
- const QRect &qrect = qrects.at(i);
+ const QRect &qrect = QRect(qrects.at(i).topLeft() * devicePixelRatio, qrects.at(i).size() * devicePixelRatio);
qt_scrollRectInImage(m_qImage, qrect, qpoint);
}
return true;
@@ -110,4 +123,9 @@ CGImageRef QCocoaBackingStore::getBackingStoreCGImage()
return m_cgImage;
}
+qreal QCocoaBackingStore::getBackingStoreDevicePixelRatio()
+{
+ return m_qImage.devicePixelRatio();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index d9bb9c60a9..99956a0b60 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -114,6 +114,18 @@ void QCocoaGLContext::setActiveWindow(QWindow *window)
cocoaWindow->setCurrentContext(this);
[(QNSView *) cocoaWindow->contentView() setQCocoaGLContext:this];
+
+ // Enable high-dpi OpenGL for retina displays. Enabling has the side
+ // effect that Cooca will start calling glViewport(0, 0, width, height),
+ // overriding any glViewport calls in application code. This is usually not a
+ // problem, except if the applcation wants to have a "custom" viewport.
+ // (like the hellogl example)
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
+ if (cocoaWindow->devicePixelRatio() > 1)
+ [cocoaWindow->contentView() setWantsBestResolutionOpenGLSurface:YES];
+ }
+#endif
}
void QCocoaGLContext::doneCurrent()
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index dae9872566..1bb46ea3ea 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -68,6 +68,7 @@ public:
QRect availableGeometry() const { return m_availableGeometry; }
int depth() const { return m_depth; }
QImage::Format format() const { return m_format; }
+ qreal devicePixelRatio() const;
QSizeF physicalSize() const { return m_physicalSize; }
QDpi logicalDpi() const { return m_logicalDpi; }
qreal refreshRate() const { return m_refreshRate; }
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 3767fa014d..393c471c25 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -115,6 +115,18 @@ void QCocoaScreen::updateGeometry()
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), availableGeometry());
}
+qreal QCocoaScreen::devicePixelRatio() const
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
+ return qreal([m_screen backingScaleFactor]);
+ } else
+#endif
+ {
+ return 1.0;
+ }
+}
+
extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index a9ea135b3e..228644c351 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -140,6 +140,8 @@ public:
void setMenubar(QCocoaMenuBar *mb);
QCocoaMenuBar *menubar() const;
+
+ qreal devicePixelRatio() const;
protected:
// NSWindow handling. The QCocoaWindow/QNSView can either be displayed
// in an existing NSWindow or in one created by Qt.
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 77073d9bc6..c3b2139998 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -39,6 +39,7 @@
**
****************************************************************************/
#include "qcocoawindow.h"
+#include "qcocoaintegration.h"
#include "qnswindowdelegate.h"
#include "qcocoaautoreleasepool.h"
#include "qcocoaeventdispatcher.h"
@@ -820,6 +821,20 @@ QCocoaMenuBar *QCocoaWindow::menubar() const
return m_menubar;
}
+qreal QCocoaWindow::devicePixelRatio() const
+{
+ if (!m_nsWindow)
+ return 1.0;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
+ return qreal([m_nsWindow backingScaleFactor]);
+ } else
+#endif
+ {
+ return 1.0;
+ }
+}
+
QMargins QCocoaWindow::frameMargins() const
{
NSRect frameW = [m_nsWindow frame];
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index d2a4685872..b608989e43 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -244,7 +244,7 @@ static QTouchDevice *touchDevice = 0;
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
{
m_backingStore = backingStore;
- m_backingStoreOffset = offset;
+ m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio();
QRect br = region.boundingRect();
[self setNeedsDisplayInRect:NSMakeRect(br.x(), br.y(), br.width(), br.height())];
}
@@ -275,33 +275,44 @@ static QTouchDevice *touchDevice = 0;
if (!m_backingStore)
return;
- CGRect dirtyCGRect = NSRectToCGRect(dirtyRect);
+ // Calculate source and target rects. The target rect is the dirtyRect:
+ CGRect dirtyWindowRect = NSRectToCGRect(dirtyRect);
+
+ // The backing store source rect will be larger on retina displays.
+ // Scale dirtyRect by the device pixel ratio:
+ const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio();
+ CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio,
+ dirtyRect.origin.y * devicePixelRatio,
+ dirtyRect.size.width * devicePixelRatio,
+ dirtyRect.size.height * devicePixelRatio);
+
NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext];
CGContextRef cgContext = (CGContextRef) [nsGraphicsContext graphicsPort];
// Translate coordiate system from CoreGraphics (bottom-left) to NSView (top-left):
CGContextSaveGState(cgContext);
- int dy = dirtyCGRect.origin.y + CGRectGetMaxY(dirtyCGRect);
+ int dy = dirtyWindowRect.origin.y + CGRectGetMaxY(dirtyWindowRect);
+
CGContextTranslateCTM(cgContext, 0, dy);
CGContextScaleCTM(cgContext, 1, -1);
// If a mask is set, modify the sub image accordingly:
CGImageRef subMask = 0;
if (m_maskImage) {
- subMask = CGImageCreateWithImageInRect(m_maskImage, dirtyCGRect);
- CGContextClipToMask(cgContext, dirtyCGRect, subMask);
+ subMask = CGImageCreateWithImageInRect(m_maskImage, dirtyWindowRect);
+ CGContextClipToMask(cgContext, dirtyWindowRect, subMask);
}
// Clip out and draw the correct sub image from the (shared) backingstore:
CGRect backingStoreRect = CGRectMake(
- dirtyRect.origin.x + m_backingStoreOffset.x(),
- dirtyRect.origin.y + m_backingStoreOffset.y(),
- dirtyRect.size.width,
- dirtyRect.size.height
+ dirtyBackingRect.origin.x + m_backingStoreOffset.x(),
+ dirtyBackingRect.origin.y + m_backingStoreOffset.y(),
+ dirtyBackingRect.size.width,
+ dirtyBackingRect.size.height
);
CGImageRef bsCGImage = m_backingStore->getBackingStoreCGImage();
CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect);
- CGContextDrawImage(cgContext, dirtyCGRect, cleanImg);
+ CGContextDrawImage(cgContext, dirtyWindowRect, cleanImg);
// Clean-up:
CGContextRestoreGState(cgContext);