From 0e9cd8b4098661bf611fa73a787c58c85e7d7338 Mon Sep 17 00:00:00 2001
From: Gunnar Sletta <gunnar.sletta@digia.com>
Date: Sat, 18 May 2013 08:20:30 +0200
Subject: [PATCH] Cut performance cost in QSGContext::prepareMaterial()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The hash-lookup in this function is costing us a lot, and
since we're looking up the same materials again and again,
and the material has a place holder for it, we can store it
directly in the material at no extra cost. This was a 10%
gain in this particular benchmark.

Change-Id: I46b67791ce39f453fa86d1ee82f6f5c7785b46a1
Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
---
 src/quick/scenegraph/coreapi/qsgmaterial.cpp | 1 +
 src/quick/scenegraph/coreapi/qsgmaterial.h   | 1 +
 src/quick/scenegraph/qsgcontext.cpp          | 9 ++++++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
index c0794d0d69..9346236db9 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
@@ -556,6 +556,7 @@ static void qt_print_material_count()
 
 QSGMaterial::QSGMaterial()
     : m_flags(0)
+    , m_reserved(0)
 {
 #ifndef QT_NO_DEBUG
     if (qsg_leak_check) {
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.h b/src/quick/scenegraph/coreapi/qsgmaterial.h
index ee8889deac..20ab21ad28 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.h
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.h
@@ -133,6 +133,7 @@ public:
     void setFlag(Flags flags, bool on = true);
 
 private:
+    friend class QSGContext;
     Flags m_flags;
     void *m_reserved;
     Q_DISABLE_COPY(QSGMaterial)
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 14f0fabbdd..d3710c7bd5 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -478,10 +478,16 @@ QSGDepthStencilBufferManager *QSGContext::depthStencilBufferManager()
 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
 {
     Q_D(QSGContext);
+
+    if (material->m_reserved)
+        return reinterpret_cast<QSGMaterialShader *>(material->m_reserved);
+
     QSGMaterialType *type = material->type();
     QSGMaterialShader *shader = d->materials.value(type);
-    if (shader)
+    if (shader) {
+        material->m_reserved = shader;
         return shader;
+    }
 
 #ifndef QSG_NO_RENDER_TIMING
     if (qsg_render_timing  || QQmlProfilerService::enabled)
@@ -489,6 +495,7 @@ QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
 #endif
 
     shader = material->createShader();
+    material->m_reserved = shader;
     shader->compile();
     shader->initialize();
     d->materials[type] = shader;
-- 
GitLab