From da98cee59c3ff8d26f1c10d203733cab24e7a57c Mon Sep 17 00:00:00 2001 From: Janne Kangas Date: Tue, 14 May 2019 11:02:30 +0300 Subject: Build glyphs for distance field texts earlier in OpenGL RT Build and cache glyphs for distance field texts at the first frame regardless of text initial state. Glyph building is a heavy operation that causes a visible freeze in the animation when a text element becomes active after initial inactivity. Additionally, build associated shaders at presentation load time. Task-id: QT3DS-3503 Change-Id: If1e0c81f26d731f1bbd1cd7bcd745400c8ff6920 Reviewed-by: Jere Tuliniemi Reviewed-by: Miikka Heikkinen --- .../runtimerender/Qt3DSDistanceFieldRenderer.cpp | 11 +++++++++++ .../runtimerender/Qt3DSDistanceFieldRenderer.h | 2 ++ .../rendererimpl/Qt3DSRenderableObjects.h | 1 + .../Qt3DSRendererImplLayerRenderPreparationData.cpp | 20 +++++++++++++------- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.cpp b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.cpp index 960e0a2f..290964b2 100644 --- a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.cpp +++ b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.cpp @@ -954,6 +954,7 @@ void Q3DSDistanceFieldRenderer::setContext(IQt3DSRenderContext &context) { m_context = &context; m_glyphCacheManager.setContext(context); + buildShaders(); } ITextRendererCore &ITextRendererCore::createDistanceFieldRenderer(NVFoundationBase &fnd) @@ -1046,4 +1047,14 @@ STextTextureAtlasEntryDetails Q3DSDistanceFieldRenderer::RenderAtlasEntry(QT3DSU return STextTextureAtlasEntryDetails(); } +bool Q3DSDistanceFieldRenderer::checkAndBuildGlyphs(SText &text) +{ + auto hashVal = getTextHashValue(text); + if (!m_glyphCache.contains(hashVal)) { + m_glyphCache[hashVal] = buildGlyphsPerTexture(text); + return true; + } + + return false; +} #endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.h b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.h index c82a0e80..3af19a98 100644 --- a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.h +++ b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.h @@ -105,6 +105,8 @@ public: void renderTextDepth(SText &text, const QT3DSMat44 &mvp); void setContext(IQt3DSRenderContext &context); + bool checkAndBuildGlyphs(SText &text); + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_foundation.getAllocator()) void AddSystemFontDirectory(const char8_t *dir) override; diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.h b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.h index 39e73e8e..a369f7a1 100644 --- a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.h +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRenderableObjects.h @@ -413,6 +413,7 @@ namespace render { m_RenderableFlags.SetCustom(false); m_RenderableFlags.SetText(false); m_RenderableFlags.setDistanceField(true); + m_distanceFieldText.checkAndBuildGlyphs(text); } void Render(const QT3DSVec2 &inCameraVec); diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp index d5aecc57..4f274574 100644 --- a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp @@ -415,8 +415,11 @@ namespace render { theFlags, inText.GetGlobalPos(), m_Renderer, inText, inText.m_Bounds, theMVP, inViewProjection, *inText.m_TextTexture, theTextOffset, theTextScale); #endif - - m_TransparentObjects.push_back(theRenderable); + // After preparation, do not push object back to queue if it is not + // active, because we prepare text elements regardless of their + // visibility (=active status). + if (inText.m_Flags.IsGloballyActive()) + m_TransparentObjects.push_back(theRenderable); } return retval; } @@ -1041,11 +1044,14 @@ namespace render { if (hasTextRenderer) { SText *theText = static_cast(theNode); theText->CalculateGlobalVariables(); - if (theText->m_Flags.IsGloballyActive()) { - bool wasTextDirty = PrepareTextForRender(*theText, inViewProjection, - theTextScaleFactor, ioFlags); - wasDataDirty = wasDataDirty || wasTextDirty; - } + // Omit check for global active flag intentionally and force + // render preparation for all Text items. This eliminates + // large delay for distance field text items becoming active + // mid-animation. + bool wasTextDirty = PrepareTextForRender(*theText, inViewProjection, + theTextScaleFactor, ioFlags); + wasDataDirty = wasDataDirty || wasTextDirty; + } } break; case GraphObjectTypes::Path: { -- cgit v1.2.3