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 #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 Flushes the given \a region from the specified \a window onto the
screen, and composes it with the specified \a textures. screen, and composes it with the specified \a textures.
@ -205,7 +227,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
context->makeCurrent(window); context->makeCurrent(window);
QOpenGLFunctions *funcs = context->functions(); 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) { if (!d_ptr->blitter) {
d_ptr->blitter = new QOpenGLTextureBlitter; d_ptr->blitter = new QOpenGLTextureBlitter;
@ -214,16 +236,18 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
d_ptr->blitter->bind(); d_ptr->blitter->bind();
QRect windowRect(QPoint(), window->size()); QRect windowRect(QPoint(), window->size() * window->devicePixelRatio());
for (int i = 0; i < textures->count(); ++i) { for (int i = 0; i < textures->count(); ++i) {
GLuint textureId = textures->textureId(i); GLuint textureId = textures->textureId(i);
funcs->glBindTexture(GL_TEXTURE_2D, textureId); 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); d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
} }
GLuint textureId = toTexture(region); GLuint textureId = toTexture(deviceRegion(region, window));
if (!textureId) if (!textureId)
return; return;

View File

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

View File

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