aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
diff options
context:
space:
mode:
authorCharles Yin <charles.yin@nokia.com>2012-06-04 16:34:17 +1000
committerQt by Nokia <qt-info@nokia.com>2012-06-05 12:32:58 +0200
commit1dcfa8aa2ae6460f26d9843c197532024447e43b (patch)
tree10b5243607d603443a4abe9f89e2a453757ffaeb /src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
parent332fe582d1bd590b59618cc7b732be9bf7f9f475 (diff)
Introduce QQuickCanvasPixmap
1. QQuickPixmap now only store textures instead of QImage data, however context2d still need to access the QImage in some places, so cache the loaded images to avoid the expensive GL readback operations. 2. Use texture directly if the render target is FBO. Change-Id: I6228011e5698fa00f2e3420a3a4a305995b8a238 Reviewed-by: Yunqiao Yin <charles.yin@nokia.com>
Diffstat (limited to 'src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp')
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp121
1 files changed, 90 insertions, 31 deletions
diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
index 6f20b699c9..d231609151 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
@@ -43,6 +43,10 @@
#include "qquickcanvasitem_p.h"
#include <qqml.h>
#include <QtCore/QMutex>
+#include <QtQuick/qsgtexture.h>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QPaintEngine>
+#include <QtGui/private/qopenglpaintengine_p.h>
#define HAS_SHADOW(offsetX, offsetY, blur, color) (color.isValid() && color.alpha() && (blur || offsetX || offsetY))
@@ -229,6 +233,44 @@ void QQuickContext2DCommandBuffer::setPainterState(QPainter* p, const QQuickCont
p->setCompositionMode(state.globalCompositeOperation);
}
+static void qt_drawImage(QPainter *p, QQuickContext2D::State& state, QImage image, const QRectF& sr, const QRectF& dr, bool shadow = false)
+{
+ Q_ASSERT(p);
+
+ if (image.isNull())
+ return;
+
+ qreal sx = sr.x();
+ qreal sy = sr.y();
+ qreal sw = sr.width();
+ qreal sh = sr.height();
+ qreal dx = dr.x();
+ qreal dy = dr.y();
+ qreal dw = dr.width();
+ qreal dh = dr.height();
+
+ if (sw == -1 || sh == -1) {
+ sw = image.width();
+ sh = image.height();
+ }
+ if (sx != 0 || sy != 0 || sw != image.width() || sh != image.height())
+ image = image.copy(sx, sy, sw, sh);
+
+ if (sw != dw || sh != dh)
+ image = image.scaled(dw, dh);
+
+ if (shadow) {
+ QImage shadow = makeShadowImage(image, state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
+ qreal shadow_dx = dx + (state.shadowOffsetX < 0? state.shadowOffsetY:0);
+ qreal shadow_dy = dy + (state.shadowOffsetX < 0? state.shadowOffsetY:0);
+ p->drawImage(shadow_dx, shadow_dy, shadow);
+ }
+ //Strange OpenGL painting behavior here, without beginNativePainting/endNativePainting, only the first image is painted.
+ p->beginNativePainting();
+ p->drawImage(dx, dy, image);
+ p->endNativePainting();
+}
+
void QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State& state)
{
if (!p)
@@ -383,37 +425,49 @@ void QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State& s
}
case QQuickContext2D::DrawImage:
{
- qreal sx = takeReal();
- qreal sy = takeReal();
- qreal sw = takeReal();
- qreal sh = takeReal();
- qreal dx = takeReal();
- qreal dy = takeReal();
- qreal dw = takeReal();
- qreal dh = takeReal();
- QImage image = takeImage();
-
- if (!image.isNull()) {
- if (sw == -1 || sh == -1) {
- sw = image.width();
- sh = image.height();
- }
- if (sx != 0 || sy != 0 || sw != image.width() || sh != image.height())
- image = image.copy(sx, sy, sw, sh);
-
- image = image.scaled(dw, dh);
-
- if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor)) {
- QImage shadow = makeShadowImage(image, state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
- qreal shadow_dx = dx + (state.shadowOffsetX < 0? state.shadowOffsetY:0);
- qreal shadow_dy = dy + (state.shadowOffsetX < 0? state.shadowOffsetY:0);
- p->drawImage(shadow_dx, shadow_dy, shadow);
+ QRectF sr = takeRect();
+ QRectF dr = takeRect();
+ qt_drawImage(p, state, takeImage(), sr, dr, HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor));
+ break;
+ }
+ case QQuickContext2D::DrawPixmap:
+ {
+ QRectF sr = takeRect();
+ QRectF dr = takeRect();
+
+ QQmlRefPointer<QQuickCanvasPixmap> pix = takePixmap();
+ Q_ASSERT(!pix.isNull());
+
+ const bool hasShadow = HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
+ if (p->paintEngine()->type() != QPaintEngine::OpenGL2 || hasShadow){
+ //TODO: generate shadow blur with shaders
+ qt_drawImage(p, state, pix->image(), sr, dr, hasShadow);
+ } else if (pix->texture()){
+ QSGTexture *tex = pix->texture();
+ QSGDynamicTexture *dynamicTexture = qobject_cast<QSGDynamicTexture *>(tex);
+ if (dynamicTexture)
+ dynamicTexture->updateTexture();
+
+ if (tex->textureId()) {
+
+ if (sr.width() < 0)
+ sr.setWidth(tex->textureSize().width());
+ if (sr.height() < 0)
+ sr.setHeight(tex->textureSize().height());
+
+ if (dr.width() < 0)
+ dr.setWidth(sr.width());
+ if (dr.height() < 0)
+ dr.setHeight(sr.height());
+
+ qreal srBottom = sr.bottom();
+ sr.setBottom(sr.top());
+ sr.setTop(srBottom);
+
+ tex->bind();
+ QOpenGL2PaintEngineEx *engine = dynamic_cast<QOpenGL2PaintEngineEx *>(p->paintEngine());
+ engine->drawTexture(dr, tex->textureId(), tex->textureSize(), sr);
}
-
- //Strange OpenGL painting behavior here, without beginNativePainting/endNativePainting, only the first image is painted.
- p->beginNativePainting();
- p->drawImage(dx, dy, image);
- p->endNativePainting();
}
break;
}
@@ -435,11 +489,13 @@ QQuickContext2DCommandBuffer::QQuickContext2DCommandBuffer()
, intIdx(0)
, boolIdx(0)
, realIdx(0)
+ , rectIdx(0)
, colorIdx(0)
, matrixIdx(0)
, brushIdx(0)
, pathIdx(0)
, imageIdx(0)
+ , pixmapIdx(0)
{
}
@@ -454,11 +510,13 @@ void QQuickContext2DCommandBuffer::clear()
ints.clear();
bools.clear();
reals.clear();
+ rects.clear();
colors.clear();
matrixes.clear();
brushes.clear();
pathes.clear();
images.clear();
+ pixmaps.clear();
reset();
}
@@ -468,12 +526,13 @@ void QQuickContext2DCommandBuffer::reset()
intIdx = 0;
boolIdx = 0;
realIdx = 0;
+ rectIdx = 0;
colorIdx = 0;
matrixIdx = 0;
brushIdx = 0;
pathIdx = 0;
imageIdx = 0;
+ pixmapIdx = 0;
}
QT_END_NAMESPACE
-