From: Alan Alpert Date: Fri, 11 May 2012 10:38:26 +0000 (+1000) Subject: Calculate vertex positions on CPU X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=5997955449f1717cfa81091e4127699320c31ec1;p=konrad%2Fqtdeclarative.git Calculate vertex positions on CPU Easier for SG to optimize with, not really gaining anything putting it on the GPU for these Elements. Change-Id: I239e70dafce441f5281ded185de63bc1afd7d85a Reviewed-by: Glenn Watson --- diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index a5e5d99..52b9f1c 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -57,10 +57,10 @@ QT_BEGIN_NAMESPACE static const char vertexShaderCode[] = + "attribute highp vec2 vPos;\n" "attribute highp vec2 vTex;\n" "uniform highp vec3 animData;// w,h(premultiplied of anim), interpolation progress\n" "uniform highp vec4 animPos;//x,y, x,y (two frames for interpolation)\n" - "uniform highp vec2 size;//w,h of element\n" "\n" "uniform highp mat4 qt_Matrix;\n" "\n" @@ -75,7 +75,7 @@ static const char vertexShaderCode[] = " //Next frame is also passed, for interpolation\n" " fTexS.zw = animPos.zw + vTex.xy * animData.xy;\n" "\n" - " gl_Position = qt_Matrix * vec4(size.x * vTex.x, size.y * vTex.y, 0, 1);\n" + " gl_Position = qt_Matrix * vec4(vPos.x, vPos.y, 0, 1);\n" "}\n"; static const char fragmentShaderCode[] = @@ -110,8 +110,6 @@ public: float animY2; float animW; float animH; - float elementWidth; - float elementHeight; }; QQuickAnimatedSpriteMaterial::QQuickAnimatedSpriteMaterial() @@ -123,8 +121,6 @@ QQuickAnimatedSpriteMaterial::QQuickAnimatedSpriteMaterial() , animY2(0.0f) , animW(1.0f) , animH(1.0f) - , elementWidth(1.0f) - , elementHeight(1.0f) { setFlag(Blending, true); } @@ -157,7 +153,6 @@ public: program()->setUniformValue(m_opacity_id, state.opacity()); program()->setUniformValue(m_animData_id, m->animW, m->animH, m->animT); program()->setUniformValue(m_animPos_id, m->animX1, m->animY1, m->animX2, m->animY2); - program()->setUniformValue(m_size_id, m->elementWidth, m->elementHeight); if (state.isMatrixDirty()) program()->setUniformValue(m_matrix_id, state.combinedMatrix()); @@ -168,7 +163,6 @@ public: m_opacity_id = program()->uniformLocation("qt_Opacity"); m_animData_id = program()->uniformLocation("animData"); m_animPos_id = program()->uniformLocation("animPos"); - m_size_id = program()->uniformLocation("size"); } virtual const char *vertexShader() const { return vertexShaderCode; } @@ -176,6 +170,7 @@ public: virtual char const *const *attributeNames() const { static const char *attr[] = { + "vPos", "vTex", 0 }; @@ -186,7 +181,6 @@ public: int m_opacity_id; int m_animData_id; int m_animPos_id; - int m_size_id; static float chunkOfBytes[1024]; }; @@ -199,6 +193,8 @@ QSGMaterialShader *QQuickAnimatedSpriteMaterial::createShader() const } struct AnimatedSpriteVertex { + float x; + float y; float tx; float ty; }; @@ -374,6 +370,10 @@ QQuickAnimatedSprite::QQuickAnimatedSprite(QQuickItem *parent) : setFlag(ItemHasContents); connect(this, SIGNAL(runningChanged(bool)), this, SLOT(update())); + connect(this, SIGNAL(widthChanged()), + this, SLOT(sizeVertices())); + connect(this, SIGNAL(heightChanged()), + this, SLOT(sizeVertices())); } void QQuickAnimatedSprite::reloadImage() @@ -458,16 +458,36 @@ void QQuickAnimatedSprite::createEngine() } static QSGGeometry::Attribute AnimatedSprite_Attributes[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT), // tex + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // pos + QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // tex }; static QSGGeometry::AttributeSet AnimatedSprite_AttributeSet = { - 1, // Attribute Count - 2 * sizeof(float), + 2, // Attribute Count + (2+2) * sizeof(float), AnimatedSprite_Attributes }; +void QQuickAnimatedSprite::sizeVertices() +{ + if (!m_node) + return; + + AnimatedSpriteVertices *p = (AnimatedSpriteVertices *) m_node->geometry()->vertexData(); + p->v1.x = 0; + p->v1.y = 0; + + p->v2.x = width(); + p->v2.y = 0; + + p->v3.x = 0; + p->v3.y = height(); + + p->v4.x = width(); + p->v4.y = height(); +} + QSGGeometryNode* QQuickAnimatedSprite::buildNode() { if (!m_spriteEngine) { @@ -498,8 +518,6 @@ QSGGeometryNode* QQuickAnimatedSprite::buildNode() m_material->animY2 = m_material->animY1; m_material->animW = m_spriteEngine->spriteWidth() / m_sheetSize.width(); m_material->animH = m_spriteEngine->spriteHeight() / m_sheetSize.height(); - m_material->elementWidth = width(); - m_material->elementHeight = height(); int vCount = 4; int iCount = 6; @@ -520,6 +538,7 @@ QSGGeometryNode* QQuickAnimatedSprite::buildNode() p->v4.tx = 1.0; p->v4.ty = 1.0; + quint16 *indices = g->indexDataAsUShort(); indices[0] = 0; indices[1] = 1; @@ -534,6 +553,7 @@ QSGGeometryNode* QQuickAnimatedSprite::buildNode() m_node->setGeometry(g); m_node->setMaterial(m_material); m_node->setFlag(QSGGeometryNode::OwnsMaterial); + sizeVertices(); return m_node; } @@ -572,8 +592,6 @@ void QQuickAnimatedSprite::prepareNextFrame() int timeInt = m_timestamp.elapsed() + m_pauseOffset; qreal time = timeInt / 1000.; - m_material->elementHeight = height(); - m_material->elementWidth = width(); double frameAt; //double just for modf qreal progress; diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h index bb9c7ac..c9a74b2 100644 --- a/src/quick/items/qquickanimatedsprite_p.h +++ b/src/quick/items/qquickanimatedsprite_p.h @@ -346,6 +346,8 @@ public slots: private slots: void createEngine(); + void sizeVertices(); + protected: void reset(); void componentComplete(); diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp index 7f7d1cc..28849ac 100644 --- a/src/quick/items/qquickspritesequence.cpp +++ b/src/quick/items/qquickspritesequence.cpp @@ -57,10 +57,10 @@ QT_BEGIN_NAMESPACE static const char vertexShaderCode[] = + "attribute highp vec2 vPos;\n" "attribute highp vec2 vTex;\n" "uniform highp vec3 animData;// w,h(premultiplied of anim), interpolation progress\n" "uniform highp vec4 animPos;//x,y, x,y (two frames for interpolation)\n" - "uniform highp vec2 size;//w,h of element\n" "\n" "uniform highp mat4 qt_Matrix;\n" "\n" @@ -75,7 +75,7 @@ static const char vertexShaderCode[] = " //Next frame is also passed, for interpolation\n" " fTexS.zw = animPos.zw + vTex.xy * animData.xy;\n" "\n" - " gl_Position = qt_Matrix * vec4(size.x * vTex.x, size.y * vTex.y, 0, 1);\n" + " gl_Position = qt_Matrix * vec4(vPos.x, vPos.y, 0, 1);\n" "}\n"; static const char fragmentShaderCode[] = @@ -110,8 +110,6 @@ public: float animY2; float animW; float animH; - float elementWidth; - float elementHeight; }; QQuickSpriteSequenceMaterial::QQuickSpriteSequenceMaterial() @@ -122,8 +120,6 @@ QQuickSpriteSequenceMaterial::QQuickSpriteSequenceMaterial() , animY2(0.0f) , animW(1.0f) , animH(1.0f) - , elementWidth(1.0f) - , elementHeight(1.0f) { setFlag(Blending, true); } @@ -156,7 +152,6 @@ public: program()->setUniformValue(m_opacity_id, state.opacity()); program()->setUniformValue(m_animData_id, m->animW, m->animH, m->animT); program()->setUniformValue(m_animPos_id, m->animX1, m->animY1, m->animX2, m->animY2); - program()->setUniformValue(m_size_id, m->elementWidth, m->elementHeight); if (state.isMatrixDirty()) program()->setUniformValue(m_matrix_id, state.combinedMatrix()); @@ -167,7 +162,6 @@ public: m_opacity_id = program()->uniformLocation("qt_Opacity"); m_animData_id = program()->uniformLocation("animData"); m_animPos_id = program()->uniformLocation("animPos"); - m_size_id = program()->uniformLocation("size"); } virtual const char *vertexShader() const { return vertexShaderCode; } @@ -175,6 +169,7 @@ public: virtual char const *const *attributeNames() const { static const char *attr[] = { + "vPos", "vTex", 0 }; @@ -185,7 +180,6 @@ public: int m_opacity_id; int m_animData_id; int m_animPos_id; - int m_size_id; static float chunkOfBytes[1024]; }; @@ -198,6 +192,8 @@ QSGMaterialShader *QQuickSpriteSequenceMaterial::createShader() const } struct SpriteVertex { + float x; + float y; float tx; float ty; }; @@ -279,6 +275,10 @@ QQuickSpriteSequence::QQuickSpriteSequence(QQuickItem *parent) : setFlag(ItemHasContents); connect(this, SIGNAL(runningChanged(bool)), this, SLOT(update())); + connect(this, SIGNAL(widthChanged()), + this, SLOT(sizeVertices())); + connect(this, SIGNAL(heightChanged()), + this, SLOT(sizeVertices())); } void QQuickSpriteSequence::jumpTo(const QString &sprite) @@ -315,16 +315,36 @@ void QQuickSpriteSequence::createEngine() } static QSGGeometry::Attribute SpriteSequence_Attributes[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT), // tex + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // pos + QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // tex }; static QSGGeometry::AttributeSet SpriteSequence_AttributeSet = { - 1, // Attribute Count - 2 * sizeof(float), + 2, // Attribute Count + (2+2) * sizeof(float), SpriteSequence_Attributes }; +void QQuickSpriteSequence::sizeVertices() +{ + if (!m_node) + return; + + SpriteVertices *p = (SpriteVertices *) m_node->geometry()->vertexData(); + p->v1.x = 0; + p->v1.y = 0; + + p->v2.x = width(); + p->v2.y = 0; + + p->v3.x = 0; + p->v3.y = height(); + + p->v4.x = width(); + p->v4.y = height(); +} + QSGGeometryNode* QQuickSpriteSequence::buildNode() { if (!m_spriteEngine) { @@ -355,8 +375,6 @@ QSGGeometryNode* QQuickSpriteSequence::buildNode() m_material->animY2 = m_material->animY1; m_material->animW = m_spriteEngine->spriteWidth() / m_sheetSize.width(); m_material->animH = m_spriteEngine->spriteHeight() / m_sheetSize.height(); - m_material->elementWidth = width(); - m_material->elementHeight = height(); m_curState = m_spriteEngine->state(m_spriteEngine->curState())->name(); emit currentSpriteChanged(m_curState); @@ -393,6 +411,7 @@ QSGGeometryNode* QQuickSpriteSequence::buildNode() m_node->setGeometry(g); m_node->setMaterial(m_material); m_node->setFlag(QSGGeometryNode::OwnsMaterial); + sizeVertices(); return m_node; } @@ -431,8 +450,6 @@ void QQuickSpriteSequence::prepareNextFrame() uint timeInt = m_timestamp.elapsed(); qreal time = timeInt / 1000.; - m_material->elementHeight = height(); - m_material->elementWidth = width(); //Advance State m_spriteEngine->updateSprites(timeInt); diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h index a2f9e41..ce5d92d 100644 --- a/src/quick/items/qquickspritesequence_p.h +++ b/src/quick/items/qquickspritesequence_p.h @@ -120,6 +120,8 @@ public slots: private slots: void createEngine(); + void sizeVertices(); + protected: void reset(); QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);