aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@jollamobile.com>2014-08-01 12:41:59 +0200
committerGunnar Sletta <gunnar.sletta@jollamobile.com>2014-08-01 14:10:24 +0200
commit2b3493c1b216d1d2ce1cbac974db1a9ee449e01f (patch)
treeba70524cd2d04e00fbaa250018d079f42bc87124 /src
parent78923902089d0a70c096e5f47f42e24fbcd4fa56 (diff)
Support Canvas.antialiasing without multisample support.
FBO based rendering relies on framebuffer multisampling to do antialiasing, which is often not available on OpenGL ES and even on some desktop chips. As a high-level API, it is quite bad that Canvas users (on embedded in particular) have to choose between quality (Image) or performance (FBO). This change implements super sampling, rendering the content at twice the size and then scaling it down. [ChangeLog][QtQuick][Canvas] Implement antialiasing on FramebufferObject based render targets through super-sampling (SSAA) when framebuffer multisampling is not available. Change-Id: I373f3a645342dac157506b746c1e39b0f3f3f9f2 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp3
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h3
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture.cpp23
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture_p.h5
4 files changed, 28 insertions, 6 deletions
diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
index cb09c9d4ff..7b114ae45e 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
@@ -258,13 +258,14 @@ static void qt_drawImage(QPainter *p, QQuickContext2D::State& state, QImage imag
p->endNativePainting();
}
-void QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State& state)
+void QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State& state, const QVector2D &scaleFactor)
{
if (!p)
return;
reset();
+ p->scale(scaleFactor.x(), scaleFactor.y());
QTransform originMatrix = p->worldTransform();
QPen pen = makePen(state);
diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h b/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h
index 9e79333a0c..8c7ffb0524 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h
@@ -232,7 +232,8 @@ public:
inline QColor takeColor() { return colors[colorIdx++]; }
inline QBrush takeBrush() { return brushes[brushIdx++]; }
- void replay(QPainter* painter, QQuickContext2D::State& state);
+ void replay(QPainter* painter, QQuickContext2D::State& state, const QVector2D &scaleFactor);
+
private:
QPen makePen(const QQuickContext2D::State& state);
void setPainterState(QPainter* painter, const QQuickContext2D::State& state, const QPen& pen);
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp
index fbfd3df324..7e88e18c65 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture.cpp
+++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp
@@ -227,7 +227,7 @@ void QQuickContext2DTexture::paintWithoutTiles(QQuickContext2DCommandBuffer *ccb
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
- ccb->replay(&p, m_state);
+ ccb->replay(&p, m_state, scaleFactor());
endPainting();
markDirtyTexture();
}
@@ -268,7 +268,7 @@ void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb)
QQuickContext2D::State oldState = m_state;
foreach (QQuickContext2DTile* tile, m_tiles) {
if (tile->dirty()) {
- ccb->replay(tile->createPainter(m_smooth, m_antialiasing), oldState);
+ ccb->replay(tile->createPainter(m_smooth, m_antialiasing), oldState, scaleFactor());
tile->drawFinished();
tile->markDirty(false);
}
@@ -418,6 +418,14 @@ QQuickContext2DFBOTexture::~QQuickContext2DFBOTexture()
QOpenGLContext::currentContext()->functions()->glDeleteTextures(2, m_displayTextures);
}
+QVector2D QQuickContext2DFBOTexture::scaleFactor() const
+{
+ if (!m_fbo)
+ return QVector2D(1, 1);
+ return QVector2D(m_fbo->width() / m_fboSize.width(),
+ m_fbo->height() / m_fboSize.height());
+}
+
QSGTexture *QQuickContext2DFBOTexture::textureForNextFrame(QSGTexture *lastTexture)
{
QSGPlainTexture *texture = static_cast<QSGPlainTexture *>(lastTexture);
@@ -500,7 +508,7 @@ void QQuickContext2DFBOTexture::grabImage(const QRectF& rf)
QImage grabbed;
{
GLAcquireContext ctx(m_context->glContext(), m_context->surface());
- grabbed = m_fbo->toImage().mirrored().copy(rf.toRect());
+ grabbed = m_fbo->toImage().scaled(m_fboSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).mirrored().copy(rf.toRect());
}
m_context->setGrabbedImage(grabbed);
@@ -561,7 +569,14 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting()
} else {
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
- m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);
+ QSize s = m_fboSize;
+ if (m_antialiasing) { // do supersampling since multisampling is not available
+ GLint max;
+ QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
+ if (s.width() * 2 <= max && s.height() * 2 <= max)
+ s = s * 2;
+ }
+ m_fbo = new QOpenGLFramebufferObject(s, format);
}
}
diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h
index 186863c1aa..7c48453857 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture_p.h
+++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h
@@ -124,6 +124,8 @@ public Q_SLOTS:
virtual void grabImage(const QRectF& region = QRectF()) = 0;
protected:
+ virtual QVector2D scaleFactor() const { return QVector2D(1, 1); }
+
void paintWithoutTiles(QQuickContext2DCommandBuffer *ccb);
virtual QPaintDevice* beginPainting() {m_painting = true; return 0; }
virtual void endPainting() {m_painting = false;}
@@ -173,6 +175,9 @@ public:
QSGTexture *textureForNextFrame(QSGTexture *);
+protected:
+ QVector2D scaleFactor() const Q_DECL_OVERRIDE;
+
public Q_SLOTS:
virtual void grabImage(const QRectF& region = QRectF());