X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Frendering%2Fatlas%2Ftext-atlas-renderer.cpp;h=9d34fd2c522c5cb72a44e08630b4f14c13715638;hp=cffbc6ea58c6671cd5ddbea67fb397bac1e7b044;hb=d15b9def82b922ae3013ea250e4f6fe260417a79;hpb=1c5674a11a51310ee689d6daf4e6b7d94dec607e diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index cffbc6e..9d34fd2 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -20,17 +20,16 @@ // EXTERNAL INCLUDES #include -#include +#include +#include +#include +#include +#include #include - - +#include // INTERNAL INCLUDES -#include -#include +#include #include -#include -#include -//#include using namespace Dali; using namespace Dali::Toolkit; @@ -42,70 +41,13 @@ namespace Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING"); #endif - const float ZERO( 0.0f ); - const float HALF( 0.5f ); - const float ONE( 1.0f ); - const float TWO( 2.0f ); - const uint32_t DEFAULT_ATLAS_WIDTH = 512u; - const uint32_t DEFAULT_ATLAS_HEIGHT = 512u; - - #define MAKE_SHADER(A)#A - - const char* VERTEX_SHADER = MAKE_SHADER( - attribute mediump vec2 aPosition; - attribute mediump vec2 aTexCoord; - uniform mediump mat4 uMvpMatrix; - uniform mediump vec3 uSize; - varying mediump vec2 vTexCoord; - - void main() - { - mediump vec4 position = vec4( aPosition, 0.0, 1.0 ); - position.xyz *= uSize; - gl_Position = uMvpMatrix * position; - vTexCoord = aTexCoord; - } - ); - - const char* FRAGMENT_SHADER = MAKE_SHADER( - uniform sampler2D sTexture; - varying mediump vec2 vTexCoord; - - void main() - { - //gl_FragColor = vec4( 1.0 ); - gl_FragColor = texture2D( sTexture, vTexCoord ); - } - ); - - const char* VERTEX_SHADER_SHADOW = MAKE_SHADER( - attribute mediump vec2 aPosition; - attribute mediump vec2 aTexCoord; - uniform mediump vec3 uSize; - varying mediump vec2 vTexCoord; - - void main() - { - mediump vec4 position = vec4( aPosition, 0.0, 1.0 ); - position.xyz *= uSize; - gl_Position = position; - vTexCoord = aTexCoord; - } - ); - - const char* FRAGMENT_SHADER_SHADOW = MAKE_SHADER( - uniform sampler2D sTexture; - uniform lowp vec4 uColor; - varying mediump vec2 vTexCoord; - - void main() - { - mediump vec4 color = texture2D( sTexture, vTexCoord ); - gl_FragColor = vec4(uColor.rgb, uColor.a*color.r); - } - ); +const float ZERO( 0.0f ); +const float HALF( 0.5f ); +const float ONE( 1.0f ); +const float TWO( 2.0f ); +const uint32_t DEFAULT_ATLAS_WIDTH = 512u; +const uint32_t DEFAULT_ATLAS_HEIGHT = 512u; } - struct AtlasRenderer::Impl : public ConnectionTracker { @@ -134,20 +76,28 @@ struct AtlasRenderer::Impl : public ConnectionTracker uint32_t mMeshRecordIndex; }; - struct AtlasRecord + struct MaxBlockSize { - uint32_t mImageId; + FontId mFontId; + uint32_t mNeededBlockWidth; + uint32_t mNeededBlockHeight; + }; + + struct CheckEntry + { + FontId mFontId; Text::GlyphIndex mIndex; }; - struct MaxBlockSize + struct TextCacheEntry { FontId mFontId; - uint32_t mNeededBlockWidth; - uint32_t mNeededBlockHeight; + Text::GlyphIndex mIndex; + uint32_t mImageId; }; Impl() + : mDepth( 0 ) { mGlyphManager = AtlasGlyphManager::Get(); mFontClient = TextAbstraction::FontClient::Get(); @@ -155,9 +105,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2; mQuadVertexFormat[ "aTexCoord" ] = Property::VECTOR2; mQuadIndexFormat[ "indices" ] = Property::UNSIGNED_INTEGER; - - mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); - mShadowShader = Shader::New( VERTEX_SHADER_SHADOW, FRAGMENT_SHADER_SHADOW ); } void AddGlyphs( const std::vector& positions, @@ -167,11 +114,14 @@ struct AtlasRenderer::Impl : public ConnectionTracker const Vector4& shadowColor, bool underlineEnabled, const Vector4& underlineColor, - float underlineHeight ) + float underlineHeight, + int depth ) { AtlasManager::AtlasSlot slot; std::vector< MeshRecord > meshContainer; Vector< Extent > extents; + TextCacheEntry textCacheEntry; + mDepth = depth; float currentUnderlinePosition = ZERO; float currentUnderlineThickness = underlineHeight; @@ -184,10 +134,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker style = STYLE_DROP_SHADOW; } - if ( mImageIds.Size() ) + if ( mTextCache.Size() ) { - // Unreference any currently used glyphs - RemoveText(); + // Update the glyph cache with any changes to current text + RemoveText( glyphs ); } CalculateBlocksSize( glyphs ); @@ -237,17 +187,9 @@ struct AtlasRenderer::Impl : public ConnectionTracker const Vector2& position = positions[ i ]; AtlasManager::Mesh2D newMesh; - mGlyphManager.Cached( glyph.fontId, glyph.index, slot ); - if ( slot.mImageId ) - { - // This glyph already exists so generate mesh data plugging in our supplied position - mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh ); - mImageIds.PushBack( slot.mImageId ); - } - else + if ( !mGlyphManager.Cached( glyph.fontId, glyph.index, slot ) ) { - // Select correct size for new atlas if needed....? if ( lastFontId != glyph.fontId ) { @@ -291,15 +233,16 @@ struct AtlasRenderer::Impl : public ConnectionTracker // Locate a new slot for our glyph mGlyphManager.Add( glyph, bitmap, slot ); - - // Generate mesh data for this quad, plugging in our supplied position - if ( slot.mImageId ) - { - mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh ); - mImageIds.PushBack( slot.mImageId ); - } } } + + // Generate mesh data for this quad, plugging in our supplied position + mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh ); + textCacheEntry.mFontId = glyph.fontId; + textCacheEntry.mImageId = slot.mImageId; + textCacheEntry.mIndex = glyph.index; + mTextCache.PushBack( textCacheEntry ); + // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas) StitchTextMesh( meshContainer, newMesh, @@ -309,7 +252,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker currentUnderlinePosition, currentUnderlineThickness, slot ); - lastFontId = glyph.fontId; + lastFontId = glyph.fontId; } } @@ -332,8 +275,9 @@ struct AtlasRenderer::Impl : public ConnectionTracker actor.Add( GenerateShadow( *mIt, shadowOffset, shadowColor ) ); } - if ( mActor ) + if( mActor ) { + actor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned mActor.Add( actor ); } else @@ -341,7 +285,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker mActor = actor; } } - mActor.OffStageSignal().Connect( this, &AtlasRenderer::Impl::OffStageDisconnect ); } #if defined(DEBUG_ENABLED) Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics(); @@ -377,8 +320,11 @@ struct AtlasRenderer::Impl : public ConnectionTracker Material material = mGlyphManager.GetMaterial( meshRecord.mAtlasId ); Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material ); - renderer.SetDepthIndex( 0 ); + renderer.SetDepthIndex( CONTENT_DEPTH_INDEX + mDepth ); Actor actor = Actor::New(); +#if defined(DEBUG_ENABLED) + actor.SetName( "Text renderable actor" ); +#endif actor.AddRenderer( renderer ); actor.SetSize( 1.0f, 1.0f ); actor.SetColor( meshRecord.mColor ); @@ -496,19 +442,56 @@ struct AtlasRenderer::Impl : public ConnectionTracker } } - // Unreference any glyphs that were used with this actor - void OffStageDisconnect( Dali::Actor actor ) + void RemoveText( const Vector& glyphs ) { - RemoveText(); - } + Vector< CheckEntry > checked; + CheckEntry checkEntry; - void RemoveText() - { - for ( uint32_t i = 0; i < mImageIds.Size(); ++i ) + for ( Vector< TextCacheEntry >::Iterator tCit = mTextCache.Begin(); tCit != mTextCache.End(); ++tCit ) { - mGlyphManager.Remove( mImageIds[ i ] ); + uint32_t index = tCit->mIndex; + uint32_t fontId = tCit->mFontId; + + // Check that this character has not already been checked... + bool wasChecked = false; + for ( Vector< CheckEntry >::Iterator cEit = checked.Begin(); cEit != checked.End(); ++cEit ) + { + if ( fontId == cEit->mFontId && index == cEit->mIndex ) + { + wasChecked = true; + } + } + + if ( !wasChecked ) + { + + int32_t newCount = 0; + int32_t oldCount = 0; + + // How many times does this character occur in the old text ? + for ( Vector< TextCacheEntry >::Iterator oTcit = mTextCache.Begin(); oTcit != mTextCache.End(); ++oTcit ) + { + if ( fontId == oTcit->mFontId && index == oTcit->mIndex ) + { + oldCount++; + } + } + + // And how many times in the new ? + for ( Vector< GlyphInfo >::Iterator cGit = glyphs.Begin(); cGit != glyphs.End(); ++cGit ) + { + if ( fontId == cGit->fontId && index == cGit->index ) + { + newCount++; + } + } + mGlyphManager.AdjustReferenceCount( fontId, tCit->mImageId, newCount - oldCount ); + checkEntry.mIndex = index; + checkEntry.mFontId = fontId; + checked.PushBack( checkEntry ); + } } - mImageIds.Resize( 0 ); + mTextCache.Resize( 0 ); } void CalculateBlocksSize( const Vector& glyphs ) @@ -663,11 +646,13 @@ struct AtlasRenderer::Impl : public ConnectionTracker quadGeometry.SetIndexBuffer( quadIndices ); Sampler sampler = Sampler::New( meshRecord.mBuffer, "sTexture" ); - Material material = Material::New( mShader ); + Material material = Material::New( mGlyphManager.GetEffectBufferShader() ); material.AddSampler( sampler ); Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material ); - renderer.SetDepthIndex( -1 ); + + // Ensure shadow is behind the text... + renderer.SetDepthIndex( CONTENT_DEPTH_INDEX + mDepth - 1 ); Actor actor = Actor::New(); actor.AddRenderer( renderer ); actor.SetSize( 1.0f, 1.0f ); @@ -691,7 +676,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker normGeometry.AddVertexBuffer( normVertices ); normGeometry.SetIndexBuffer( normIndices ); - Material normMaterial = Material::New( mShadowShader ); + Material normMaterial = Material::New( mGlyphManager.GetGlyphShadowShader() ); Sampler normSampler = mGlyphManager.GetSampler( meshRecord.mAtlasId ); normMaterial.AddSampler( normSampler ); Dali::Renderer normRenderer = Dali::Renderer::New( normGeometry, normMaterial ); @@ -735,14 +720,13 @@ struct AtlasRenderer::Impl : public ConnectionTracker Actor mActor; ///< The actor parent which renders the text AtlasGlyphManager mGlyphManager; ///< Glyph Manager to handle upload and caching - Vector< uint32_t > mImageIds; ///< A list of imageIDs used by the renderer TextAbstraction::FontClient mFontClient; ///> The font client used to supply glyph information - Shader mShader; ///> Shader used to render drop shadow buffer textures - Shader mShadowShader; ///> Shader used to render drop shadow into buffer std::vector< MaxBlockSize > mBlockSizes; ///> Maximum size needed to contain a glyph in a block within a new atlas std::vector< uint32_t > mFace; ///> Face indices for a quad + Vector< TextCacheEntry > mTextCache; Property::Map mQuadVertexFormat; Property::Map mQuadIndexFormat; + int mDepth; }; Text::RendererPtr AtlasRenderer::New() @@ -752,7 +736,7 @@ Text::RendererPtr AtlasRenderer::New() return Text::RendererPtr( new AtlasRenderer() ); } -Actor AtlasRenderer::Render( Text::ViewInterface& view ) +Actor AtlasRenderer::Render( Text::ViewInterface& view, int depth ) { UnparentAndReset( mImpl->mActor ); @@ -780,7 +764,8 @@ Actor AtlasRenderer::Render( Text::ViewInterface& view ) view.GetShadowColor(), view.IsUnderlineEnabled(), view.GetUnderlineColor(), - view.GetUnderlineHeight() ); + view.GetUnderlineHeight(), + depth ); } return mImpl->mActor; @@ -794,5 +779,7 @@ AtlasRenderer::AtlasRenderer() AtlasRenderer::~AtlasRenderer() { + Vector< GlyphInfo > emptyGlyphs; + mImpl->RemoveText( emptyGlyphs ); delete mImpl; }