iOS: Retina display support.

Scale the OpenGL paint device size and physical dpi
by the device pixel ratio.

Change-Id: I8b576f23129aafc47371795151c548663e94ad52
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
bb10
Morten Johan Sorvig 2012-12-14 17:25:56 +01:00 committed by Tor Arne Vestbø
parent d665ba2a94
commit a593de41ed
5 changed files with 41 additions and 7 deletions

View File

@ -116,6 +116,7 @@ public:
qreal dpmx;
qreal dpmy;
qreal devicePixelRatio;
bool flipped;
@ -178,6 +179,7 @@ QOpenGLPaintDevicePrivate::QOpenGLPaintDevicePrivate(const QSize &sz)
, ctx(QOpenGLContext::currentContext())
, dpmx(qt_defaultDpiX() * 100. / 2.54)
, dpmy(qt_defaultDpiY() * 100. / 2.54)
, devicePixelRatio(1.0)
, flipped(false)
, engine(0)
{
@ -248,6 +250,14 @@ void QOpenGLPaintDevice::setSize(const QSize &size)
d_ptr->size = size;
}
/*!
Sets the device pixel ratio for the paint device to \a devicePixelRatio.
*/
void QOpenGLPaintDevice::setDevicePixelRatio(qreal devicePixelRatio)
{
d_ptr->devicePixelRatio = devicePixelRatio;
}
/*!
\reimp
*/
@ -272,9 +282,9 @@ int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
case PdmDpiY:
return qRound(d_ptr->dpmy * 0.0254);
case PdmPhysicalDpiX:
return qRound(d_ptr->dpmx * 0.0254);
return qRound(d_ptr->dpmx * 0.0254 * d_ptr->devicePixelRatio);
case PdmPhysicalDpiY:
return qRound(d_ptr->dpmy * 0.0254);
return qRound(d_ptr->dpmy * 0.0254 * d_ptr->devicePixelRatio);
default:
qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric);
return 0;

View File

@ -68,6 +68,7 @@ public:
QOpenGLContext *context() const;
QSize size() const;
void setSize(const QSize &size);
void setDevicePixelRatio(qreal devicePixelRatio);
qreal dotsPerMeterX() const;
qreal dotsPerMeterY() const;

View File

@ -71,12 +71,18 @@ void QIOSBackingStore::beginPaint(const QRegion &)
m_context->makeCurrent(window());
static_cast<QOpenGLPaintDevice *>(paintDevice())->setSize(window()->size());
QIOSWindow *iosWindow = static_cast<QIOSWindow *>(window()->handle());
static_cast<QOpenGLPaintDevice *>(paintDevice())->setSize(window()->size() * iosWindow->devicePixelRatio());
}
QPaintDevice *QIOSBackingStore::paintDevice()
{
if (!m_device)
m_device = new QOpenGLPaintDevice;
if (!m_device) {
QIOSWindow *iosWindow = static_cast<QIOSWindow *>(window()->handle());
QOpenGLPaintDevice *openGLDevice = new QOpenGLPaintDevice(window()->size() * iosWindow->devicePixelRatio());
openGLDevice->setDevicePixelRatio(iosWindow->devicePixelRatio());
m_device = openGLDevice;
}
return m_device;
}

View File

@ -90,6 +90,7 @@ public:
GLuint framebufferObject(const QIOSContext &context) const;
GLuint colorRenderbuffer(const QIOSContext &context) const;
qreal devicePixelRatio() const;
EAGLView *nativeView() const { return m_view; }
@ -104,6 +105,7 @@ private:
GLint renderbufferWidth;
GLint renderbufferHeight;
} m_glData;
qreal m_devicePixelRatio;
};
QT_END_NAMESPACE

View File

@ -126,8 +126,7 @@ static QRect fromCGRect(const CGRect &rect)
{
UITouch *touch = [touches anyObject];
CGPoint locationInView = [touch locationInView:self];
CGFloat scaleFactor = [self contentScaleFactor];
QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor);
QPoint p(locationInView.x , locationInView.y);
// TODO handle global touch point? for status bar?
QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons);
@ -204,11 +203,21 @@ QIOSWindow::QIOSWindow(QWindow *window)
, m_view([[EAGLView alloc] initWithQIOSWindow:this])
, m_requestedGeometry(QPlatformWindow::geometry())
, m_glData()
, m_devicePixelRatio(1.0)
{
if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]])
[[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view];
setWindowState(window->windowState());
// Retina support: get screen scale factor and set it in the content view.
// This will make framebufferObject() create a 2x frame buffer on retina
// displays. Also set m_devicePixelRatio which is used for scaling the
// paint device.
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES) {
m_devicePixelRatio = [[UIScreen mainScreen] scale];
[m_view setContentScaleFactor : m_devicePixelRatio];
}
}
QIOSWindow::~QIOSWindow()
@ -304,7 +313,8 @@ GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const
GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const
{
if (!m_glData.colorRenderbuffer ||
m_glData.renderbufferWidth != geometry().width() || m_glData.renderbufferHeight != geometry().height()) {
m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio ||
m_glData.renderbufferHeight != geometry().height() *m_devicePixelRatio) {
glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer);
[context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast<CAEAGLLayer *>(m_view.layer)];
@ -329,4 +339,9 @@ GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const
return m_glData.colorRenderbuffer;
}
qreal QIOSWindow::devicePixelRatio() const
{
return m_devicePixelRatio;
}
QT_END_NAMESPACE