X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fquick%2Fitems%2Fcontext2d%2Fqquickcontext2dcommandbuffer.cpp;h=47f7e1a90dcdcdcbc598999be2fe6bb45eac57c2;hb=4236e7f7ee1d78c5adfebe719afb8b8a6dcd094b;hp=591fc216a4201640db6bd476240bedac5569c8de;hpb=0284817d6cd7e17afa8da26ee6e9199100754446;p=profile%2Fivi%2Fqtdeclarative.git diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp index 591fc21..47f7e1a 100644 --- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp +++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp @@ -43,6 +43,10 @@ #include "qquickcanvasitem_p.h" #include #include +#include +#include +#include +#include #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) @@ -236,7 +278,7 @@ void QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State& s reset(); - QTransform originMatrix = p->transform(); + QTransform originMatrix = p->worldTransform(); QPen pen = makePen(state); setPainterState(p, state, pen); @@ -247,7 +289,7 @@ void QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State& s case QQuickContext2D::UpdateMatrix: { state.matrix = takeMatrix(); - p->setTransform(state.matrix * originMatrix); + p->setWorldTransform(state.matrix * originMatrix); break; } case QQuickContext2D::ClearRect: @@ -303,36 +345,42 @@ void QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State& s state.strokeStyle = takeStrokeStyle(); state.strokePatternRepeatX = takeBool(); state.strokePatternRepeatY = takeBool(); - pen.setBrush(state.strokeStyle); - p->setPen(pen); + QPen nPen = p->pen(); + nPen.setBrush(state.strokeStyle); + p->setPen(nPen); break; } case QQuickContext2D::LineWidth: { state.lineWidth = takeLineWidth(); - pen.setWidth(state.lineWidth); - p->setPen(pen); + QPen nPen = p->pen(); + + nPen.setWidthF(state.lineWidth); + p->setPen(nPen); break; } case QQuickContext2D::LineCap: { state.lineCap = takeLineCap(); - pen.setCapStyle(state.lineCap); - p->setPen(pen); + QPen nPen = p->pen(); + nPen.setCapStyle(state.lineCap); + p->setPen(nPen); break; } case QQuickContext2D::LineJoin: { state.lineJoin = takeLineJoin(); - pen.setJoinStyle(state.lineJoin); - p->setPen(pen); + QPen nPen = p->pen(); + nPen.setJoinStyle(state.lineJoin); + p->setPen(nPen); break; } case QQuickContext2D::MiterLimit: { state.miterLimit = takeMiterLimit(); - pen.setMiterLimit(state.miterLimit); - p->setPen(pen); + QPen nPen = p->pen(); + nPen.setMiterLimit(state.miterLimit); + p->setPen(nPen); break; } case QQuickContext2D::TextAlign: @@ -377,33 +425,51 @@ 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 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(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(); + if (p->paintEngine()->type() == QPaintEngine::OpenGL2) { + QOpenGL2PaintEngineEx *engine = static_cast(p->paintEngine()); + engine->drawTexture(dr, tex->textureId(), tex->textureSize(), sr); + } } - p->drawImage(dx, dy, image); } break; } @@ -425,12 +491,19 @@ QQuickContext2DCommandBuffer::QQuickContext2DCommandBuffer() , intIdx(0) , boolIdx(0) , realIdx(0) + , rectIdx(0) , colorIdx(0) , matrixIdx(0) , brushIdx(0) , pathIdx(0) , imageIdx(0) + , pixmapIdx(0) { + static bool registered = false; + if (!registered) { + qRegisterMetaType("QQuickContext2DCommandBuffer*"); + registered = true; + } } @@ -444,11 +517,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(); } @@ -458,12 +533,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 -