QOpenGLWidget retina support.

Use device pixels where appropriate. 

Change-Id: Ia953e6da4034eecbfccf798701ec1b850eea9d5b
Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
This commit is contained in:
Morten Johan Sørvig 2014-03-18 13:36:10 +01:00 committed by The Qt Project
parent 07549de92b
commit 5e03c4d97f
3 changed files with 34 additions and 9 deletions

View File

@ -186,6 +186,28 @@ void QPlatformTextureList::clear()
*/
#ifndef QT_NO_OPENGL
static QRect deviceRect(const QRect &rect, QWindow *window)
{
QRect deviceRect(rect.topLeft() * window->devicePixelRatio(),
rect.size() * window->devicePixelRatio());
return deviceRect;
}
static QRegion deviceRegion(const QRegion &region, QWindow *window)
{
if (!(window->devicePixelRatio() > 1))
return region;
QVector<QRect> rects;
foreach (QRect rect, region.rects())
rects.append(deviceRect(rect, window));
QRegion deviceRegion;
deviceRegion.setRects(rects.constData(), rects.count());
return deviceRegion;
}
/*!
Flushes the given \a region from the specified \a window onto the
screen, and composes it with the specified \a textures.
@ -205,7 +227,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
context->makeCurrent(window);
QOpenGLFunctions *funcs = context->functions();
funcs->glViewport(0, 0, window->width(), window->height());
funcs->glViewport(0, 0, window->width() * window->devicePixelRatio(), window->height() * window->devicePixelRatio());
if (!d_ptr->blitter) {
d_ptr->blitter = new QOpenGLTextureBlitter;
@ -214,16 +236,18 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
d_ptr->blitter->bind();
QRect windowRect(QPoint(), window->size());
QRect windowRect(QPoint(), window->size() * window->devicePixelRatio());
for (int i = 0; i < textures->count(); ++i) {
GLuint textureId = textures->textureId(i);
funcs->glBindTexture(GL_TEXTURE_2D, textureId);
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), windowRect);
QRect targetRect = deviceRect(textures->geometry(i), window);
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect);
d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
}
GLuint textureId = toTexture(region);
GLuint textureId = toTexture(deviceRegion(region, window));
if (!textureId)
return;

View File

@ -163,7 +163,7 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *)
d->context.makeCurrent(d->surface());
delete d->fbo; // recreate when resized
d->fbo = new QOpenGLFramebufferObject(size());
d->fbo = new QOpenGLFramebufferObject(size() * devicePixelRatio());
d->fbo->bind();
QOpenGLFunctions *funcs = d->context.functions();
funcs->glBindTexture(GL_TEXTURE_2D, d->fbo->texture());

View File

@ -61,8 +61,8 @@
class OpenGLWidgetPrivate
{
public:
OpenGLWidgetPrivate()
: m_program(0), m_frame(0)
OpenGLWidgetPrivate(QWidget *q)
: m_program(0), m_frame(0), q(q)
{
}
@ -82,13 +82,14 @@ public:
int m_frame;
int w,h;
QWidget *q;
};
OpenGLWidget::OpenGLWidget(QWidget *parent)
: QOpenGLWidget(parent)
{
d = new OpenGLWidgetPrivate;
d = new OpenGLWidgetPrivate(this);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateGL()));
timer->start(30);
@ -147,7 +148,7 @@ void OpenGLWidgetPrivate::initialize()
void OpenGLWidgetPrivate::render()
{
const qreal retinaScale = 1.0;//devicePixelRatio();
const qreal retinaScale = q->devicePixelRatio();
glViewport(0, 0, width() * retinaScale, height() * retinaScale);
glClearColor(0.0, 0.0, 0.0, 1.0);