Merge "Moves shader creation from Text Atlas Renderer to GlyphManager" into devel...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / text-atlas-renderer.cpp
index e3b4827..2f7677a 100644 (file)
 // EXTERNAL INCLUDES
 #include <dali/dali.h>
 #include <dali/integration-api/debug.h>
-//#include <dali/public-api/actors/renderer.h>
-#include <dali/public-api/text-abstraction/text-abstraction.h>
+#include <dali/devel-api/text-abstraction/font-client.h>
+
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/internal/atlas-manager/atlas-manager.h>
+#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
-#include <dali-toolkit/internal/text/rendering/shaders/text-basic-shader.h>
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_ATLAS_RENDERER");
-#endif
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -38,70 +34,17 @@ using namespace Dali::Toolkit::Text;
 
 namespace
 {
-  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;
+#if defined(DEBUG_ENABLED)
+  Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
+#endif
 
-  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
 {
 
@@ -151,9 +94,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<Vector2>& positions,
@@ -188,9 +128,9 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 
     CalculateBlocksSize( glyphs );
 
-    for ( uint32_t i = 0; i < glyphs.Size(); ++i )
+    for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i )
     {
-      GlyphInfo glyph = glyphs[ i ];
+      const GlyphInfo& glyph = glyphs[ i ];
 
       // No operation for white space
       if ( glyph.width && glyph.height )
@@ -231,7 +171,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
           }
         }
 
-        Vector2 position = positions[ i ];
+        const Vector2& position = positions[ i ];
         AtlasManager::Mesh2D newMesh;
         mGlyphManager.Cached( glyph.fontId, glyph.index, slot );
 
@@ -262,36 +202,38 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 
           // Create a new image for the glyph
           BufferImage bitmap = mFontClient.CreateBitmap( glyph.fontId, glyph.index );
-
-          // Ensure that the next image will fit into the current block size
-          bool setSize = false;
-          if ( bitmap.GetWidth() > mBlockSizes[ currentBlockSize ].mNeededBlockWidth )
+          if ( bitmap )
           {
-            setSize = true;
-            mBlockSizes[ currentBlockSize ].mNeededBlockWidth = bitmap.GetWidth();
-          }
-          if ( bitmap.GetHeight() > mBlockSizes[ currentBlockSize ].mNeededBlockHeight )
-          {
-            setSize = true;
-            mBlockSizes[ currentBlockSize ].mNeededBlockHeight = bitmap.GetHeight();
-          }
+            // Ensure that the next image will fit into the current block size
+            bool setSize = false;
+            if ( bitmap.GetWidth() > mBlockSizes[ currentBlockSize ].mNeededBlockWidth )
+            {
+              setSize = true;
+              mBlockSizes[ currentBlockSize ].mNeededBlockWidth = bitmap.GetWidth();
+            }
+            if ( bitmap.GetHeight() > mBlockSizes[ currentBlockSize ].mNeededBlockHeight )
+            {
+              setSize = true;
+              mBlockSizes[ currentBlockSize ].mNeededBlockHeight = bitmap.GetHeight();
+            }
 
-          if ( setSize )
-          {
-            mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH,
-                                           DEFAULT_ATLAS_HEIGHT,
-                                           mBlockSizes[ currentBlockSize ].mNeededBlockWidth,
-                                           mBlockSizes[ currentBlockSize ].mNeededBlockHeight );
-          }
+            if ( setSize )
+            {
+              mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH,
+                                             DEFAULT_ATLAS_HEIGHT,
+                                             mBlockSizes[ currentBlockSize ].mNeededBlockWidth,
+                                             mBlockSizes[ currentBlockSize ].mNeededBlockHeight );
+            }
 
-          // Locate a new slot for our glyph
-          mGlyphManager.Add( glyph, bitmap, slot );
+            // 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
+            if ( slot.mImageId )
+            {
+              mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
+              mImageIds.PushBack( slot.mImageId );
+            }
           }
         }
         // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
@@ -339,7 +281,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     }
 #if defined(DEBUG_ENABLED)
     Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics();
-    DALI_LOG_INFO( gLogFilter, Debug::Concise, "TextAtlasRenderer::GlyphManager::GlyphCount: %i, AtlasCount: %i, TextureMemoryUse: %iK\n",
+    DALI_LOG_INFO( gLogFilter, Debug::General, "TextAtlasRenderer::GlyphManager::GlyphCount: %i, AtlasCount: %i, TextureMemoryUse: %iK\n",
                                                 metrics.mGlyphCount,
                                                 metrics.mAtlasMetrics.mAtlasCount,
                                                 metrics.mAtlasMetrics.mTextureMemoryUsed / 1024 );
@@ -360,8 +302,8 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 
   Actor CreateMeshActor( const MeshRecord& meshRecord )
   {
-    PropertyBuffer quadVertices = PropertyBuffer::New( PropertyBuffer::STATIC, mQuadVertexFormat, meshRecord.mMesh.mVertices.Size() );
-    PropertyBuffer quadIndices = PropertyBuffer::New( PropertyBuffer::STATIC, mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
+    PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, meshRecord.mMesh.mVertices.Size() );
+    PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
     quadVertices.SetData( const_cast< AtlasManager::Vertex2D* >( &meshRecord.mMesh.mVertices[ 0 ] ) );
     quadIndices.SetData( const_cast< unsigned int* >( &meshRecord.mMesh.mIndices[ 0 ] ) );
 
@@ -371,7 +313,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 
     Material material = mGlyphManager.GetMaterial( meshRecord.mAtlasId );
     Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material );
-    renderer.SetDepthIndex( 0 );
     Actor actor = Actor::New();
     actor.AddRenderer( renderer );
     actor.SetSize( 1.0f, 1.0f );
@@ -640,8 +581,8 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 
     // We will render a quad into this buffer
     unsigned int indices[ 6 ] = { 1, 0, 2, 2, 3, 1 };
-    PropertyBuffer quadVertices = PropertyBuffer::New( PropertyBuffer::STATIC, mQuadVertexFormat, 4u );
-    PropertyBuffer quadIndices = PropertyBuffer::New( PropertyBuffer::STATIC, mQuadIndexFormat, sizeof(indices)/sizeof(indices[0]) );
+    PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, 4u );
+    PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat, sizeof(indices)/sizeof(indices[0]) );
 
     AtlasManager::Vertex2D vertices[ 4 ] = {
     { Vector2( tlx + shadowOffset.x, tly + shadowOffset.y ), Vector2( ZERO, ZERO ) },
@@ -657,11 +598,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.0f );
+
+    // Ensure shadow is behind the text...
+    renderer.SetDepthIndex( CONTENT_DEPTH_INDEX - 1 );
     Actor actor = Actor::New();
     actor.AddRenderer( renderer );
     actor.SetSize( 1.0f, 1.0f );
@@ -676,8 +619,8 @@ struct AtlasRenderer::Impl : public ConnectionTracker
       normVertexList.PushBack( vertex );
     }
 
-    PropertyBuffer normVertices = PropertyBuffer::New( PropertyBuffer::STATIC, mQuadVertexFormat, normVertexList.Size() );
-    PropertyBuffer normIndices = PropertyBuffer::New( PropertyBuffer::STATIC, mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
+    PropertyBuffer normVertices = PropertyBuffer::New( mQuadVertexFormat, normVertexList.Size() );
+    PropertyBuffer normIndices = PropertyBuffer::New( mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
     normVertices.SetData( const_cast< AtlasManager::Vertex2D* >( &normVertexList[ 0 ] ) );
     normIndices.SetData( const_cast< unsigned int* >( &meshRecord.mMesh.mIndices[ 0 ] ) );
 
@@ -685,7 +628,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 );
@@ -731,8 +674,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker
   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
   Property::Map mQuadVertexFormat;
@@ -741,26 +682,32 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 
 Text::RendererPtr AtlasRenderer::New()
 {
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Text::AtlasRenderer::New()\n" );
+
   return Text::RendererPtr( new AtlasRenderer() );
 }
 
 Actor AtlasRenderer::Render( Text::ViewInterface& view )
 {
-
   UnparentAndReset( mImpl->mActor );
 
-  Text::Length numberOfGlyphs = view.GetNumberOfGlyphs();
+  Length numberOfGlyphs = view.GetNumberOfGlyphs();
 
-  if( numberOfGlyphs > 0 )
+  if( numberOfGlyphs > 0u )
   {
     Vector<GlyphInfo> glyphs;
     glyphs.Resize( numberOfGlyphs );
 
-    view.GetGlyphs( &glyphs[0], 0, numberOfGlyphs );
-
     std::vector<Vector2> positions;
     positions.resize( numberOfGlyphs );
-    view.GetGlyphPositions( &positions[0], 0, numberOfGlyphs );
+
+    numberOfGlyphs = view.GetGlyphs( glyphs.Begin(),
+                                     &positions[0],
+                                     0u,
+                                     numberOfGlyphs );
+    glyphs.Resize( numberOfGlyphs );
+    positions.resize( numberOfGlyphs );
+
     mImpl->AddGlyphs( positions,
                       glyphs,
                       view.GetTextColor(),
@@ -770,6 +717,7 @@ Actor AtlasRenderer::Render( Text::ViewInterface& view )
                       view.GetUnderlineColor(),
                       view.GetUnderlineHeight() );
   }
+
   return mImpl->mActor;
 }