Text: Quality improvement 91/20291/1
authorJavon Prince <javon.prince@samsung.com>
Thu, 10 Apr 2014 08:20:15 +0000 (09:20 +0100)
committerDavid Steele <david.steele@partner.samsung.com>
Thu, 1 May 2014 14:30:09 +0000 (15:30 +0100)
Adjust amount of anti-aliased pixels dependent on the font pixel size.
This will only be accurate for text that is not scaled and not rotated

[Issue#] (N/A)

[Problem]

[Cause]

[Solution]

Change-Id: If83426348a970a93c250e31d7abbd5e7fb221a4c
Signed-off-by: Javon Prince <javon.prince@samsung.com>
dali/internal/event/actor-attachments/text-attachment-impl.cpp
dali/internal/render/renderers/scene-graph-text-renderer.cpp
dali/internal/render/renderers/scene-graph-text-renderer.h
dali/internal/render/shader-source/distance-field-font-glow.txt
dali/internal/render/shader-source/distance-field-font-outline-glow.txt
dali/internal/render/shader-source/distance-field-font-outline.txt
dali/internal/render/shader-source/distance-field-font-shadow.txt
dali/internal/render/shader-source/distance-field-font.txt
dali/internal/update/node-attachments/scene-graph-text-attachment.cpp
dali/internal/update/node-attachments/scene-graph-text-attachment.h

index 5374c7d..cf53078 100644 (file)
@@ -593,6 +593,11 @@ void TextAttachment::SetTextChanges()
 
     // release the vertex buffer to pass  ownership to the scene-graph-text-attachment
     SetTextVertexBufferMessage( eventToUpdate, attachment, *mVertexBuffer.Release() );
+
+    if( mFontChanged )
+    {
+      SetTextFontSizeMessage( eventToUpdate, attachment, mFont->GetPixelSize() );
+    }
   }
 }
 
index ed04693..b7e450a 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/actors/text-actor.h>
 #include <dali/internal/common/text-parameters.h>
 #include <dali/internal/common/text-vertex-2d.h>
+#include <dali/internal/event/text/font-impl.h>
 #include <dali/internal/render/gl-resources/context.h>
 #include <dali/internal/render/common/performance-monitor.h>
 #include <dali/internal/render/shaders/program.h>
@@ -192,6 +193,11 @@ void TextRenderer::SetVertexData( TextVertexBuffer* vertexData )
   delete vertexData;
 }
 
+void TextRenderer::SetFontSize( float pixelSize )
+{
+  mPixelSize = pixelSize;
+}
+
 void TextRenderer::SetGradientColor( const Vector4& color )
 {
   AllocateTextParameters();
@@ -347,10 +353,23 @@ void TextRenderer::DoRender( BufferIndex bufferIndex, const Matrix& modelViewMat
     program.SetUniform1i( samplerLoc, 0 );
   }
 
+  const float SMOOTHING_ADJUSTMENT( 12.0f );
+  const float SMOOTHING_ADJUSTMENT_PIXEL_SIZE( 32.0f );
+
+  float smoothWidth = SMOOTHING_ADJUSTMENT / mPixelSize;
+  float smoothing = mSmoothing;
+
   const int smoothingLoc = program.GetUniformLocation( Program::UNIFORM_SMOOTHING );
   if( Program::UNIFORM_UNKNOWN != smoothingLoc )
   {
-    program.SetUniform1f( smoothingLoc, mSmoothing );
+    smoothWidth = min( min(mSmoothing, 1.0f - mSmoothing), smoothWidth );
+
+    if( mPixelSize < SMOOTHING_ADJUSTMENT_PIXEL_SIZE )
+    {
+      smoothing *= Lerp( mPixelSize / SMOOTHING_ADJUSTMENT_PIXEL_SIZE, 0.5f, 1.0f );
+    }
+
+    program.SetUniform2f( smoothingLoc, std::max(0.0f, smoothing - smoothWidth), std::min(1.0f, smoothing + smoothWidth) );
   }
 
   if( mTextParameters )
@@ -362,7 +381,11 @@ void TextRenderer::DoRender( BufferIndex bufferIndex, const Matrix& modelViewMat
 
       if( Program::UNIFORM_UNKNOWN != outlineLoc && Program::UNIFORM_UNKNOWN != outlineColorLoc )
       {
-        program.SetUniform2f(outlineLoc, mTextParameters->mOutline[0], mTextParameters->mOutline[1]);
+        float outlineWidth = mTextParameters->mOutline[1] + smoothWidth;
+        float outlineStart = mTextParameters->mOutline[0];
+        float outlineEnd = min( 1.0f, mTextParameters->mOutline[0] + outlineWidth );
+
+        program.SetUniform2f(outlineLoc, outlineStart, outlineEnd);
         program.SetUniform4f(outlineColorLoc, mTextParameters->mOutlineColor.r, mTextParameters->mOutlineColor.g, mTextParameters->mOutlineColor.b, mTextParameters->mOutlineColor.a);
       }
     }
@@ -390,9 +413,10 @@ void TextRenderer::DoRender( BufferIndex bufferIndex, const Matrix& modelViewMat
       {
         // convert shadow offset from tile to atlas coordinates
         const Vector2 offset( mTextParameters->mDropShadow / mTexture->GetWidth());
+        float shadowSmoothing = std::max(0.0f, smoothing - mTextParameters->mDropShadowSize );
         program.SetUniform2f(shadowLoc, offset.x, offset.y);
         program.SetUniform4f(shadowColorLoc, mTextParameters->mDropShadowColor.r, mTextParameters->mDropShadowColor.g, mTextParameters->mDropShadowColor.b, mTextParameters->mDropShadowColor.a);
-        program.SetUniform1f( shadowSmoothingLoc, std::max(0.0f, mSmoothing - mTextParameters->mDropShadowSize ) );
+        program.SetUniform2f( shadowSmoothingLoc, std::max(0.0f, shadowSmoothing - smoothWidth), std::min(1.0f, shadowSmoothing + smoothWidth) );
       }
     }
   }
@@ -480,7 +504,8 @@ TextRenderer::TextRenderer( RenderDataProvider& dataprovider )
   mTextureId( 0 ),
   mTexture( NULL ),
   mTextColor( NULL ),
-  mSmoothing( Dali::TextStyle::DEFAULT_SMOOTH_EDGE_DISTANCE_FIELD )
+  mSmoothing( Dali::TextStyle::DEFAULT_SMOOTH_EDGE_DISTANCE_FIELD ),
+  mPixelSize(0.0f)
 {
 }
 
index 89762a2..89ad97d 100644 (file)
@@ -68,6 +68,12 @@ public:
   void SetVertexData( TextVertexBuffer* vertexData );
 
   /**
+   * Set the pixel size of the font, required by the shader
+   * @param pixelSize The pixel size
+   */
+  void SetFontSize( float pixelSize );
+
+  /**
    * @copydoc Dali::TextActor::SetGradientColor()
    */
   void SetGradientColor( const Vector4& color );
@@ -174,6 +180,7 @@ private:
   OwnerPointer< TextParameters > mTextParameters; ///< Optional text parameters
   Vector4* mTextColor;
   float   mSmoothing;
+  float   mPixelSize;
 
 };
 
index f86ccc6..8d29264 100644 (file)
 
 <FragmentShader>
 
-#extension GL_OES_standard_derivatives : enable
-
   uniform mediump sampler2D sTexture;
   uniform lowp    vec4      uColor;
-  uniform mediump float     uSmoothing;
-  uniform mediump float     uGlow;
+  uniform highp   vec2      uSmoothing;
+  uniform highp   float     uGlow;
   uniform lowp    vec4      uGlowColor;
 
   varying mediump vec2      vTexCoord;
@@ -43,9 +41,7 @@
     // sample distance field
     mediump float distance = texture2D(sTexture, vTexCoord).a;
 
-    mediump float smoothWidth = fwidth(distance) * 0.8;
-
-    mediump float glowBlend = smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);
+    mediump float glowBlend = smoothstep(uSmoothing[0], uSmoothing[1], distance);
 
     // blend fragment color between glow color and text color
     lowp vec4 clampedColor = clamp( vColor, 0.0, 1.0 );
@@ -53,7 +49,7 @@
     lowp vec4 color = mix(glowColor, clampedColor, glowBlend);
 
     // fade out glow between uSmoothing and uGlow
-    color.a *= smoothstep(uGlow, uSmoothing, distance);
+    color.a *= smoothstep(uGlow, uSmoothing[0], distance);
 
     // final color multiplied by Actor color
     gl_FragColor = uColor * color;
index 605cf56..a9088f9 100644 (file)
 
 <FragmentShader>
 
-#extension GL_OES_standard_derivatives : enable
-
   uniform mediump sampler2D sTexture;
   uniform lowp    vec4      uColor;
-  uniform mediump float     uSmoothing;
-  uniform mediump vec2      uOutline;
+  uniform highp   vec2      uSmoothing;
+  uniform highp   vec2      uOutline;
   uniform lowp    vec4      uOutlineColor;
-  uniform mediump float     uGlow;
+  uniform highp   float     uGlow;
   uniform lowp    vec4      uGlowColor;
 
   varying mediump vec2      vTexCoord;
     // sample distance field
     mediump float distance = texture2D(sTexture, vTexCoord).a;
 
-    mediump float smoothWidth = fwidth(distance) * 0.8;
-
-    mediump float outlineWidth = uOutline[1] + smoothWidth;
-
     // blend fragment color between outline color and text color
-    mediump float outlineBlend = smoothstep(uOutline[0] - outlineWidth, uOutline[0] + outlineWidth, distance);
+    mediump float outlineBlend = smoothstep(uOutline[0], uOutline[1], distance);
 
     lowp vec4 clampedColor = clamp( vColor, 0.0, 1.0 );
 
     lowp vec4 outlineColor = vec4( uOutlineColor.rgb, uOutlineColor.a * clampedColor.a );
     lowp vec4 color = mix(outlineColor, clampedColor, outlineBlend);
 
-    mediump float glowBlend = smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);
+    mediump float glowBlend = smoothstep(uSmoothing[0], uSmoothing[1], distance);
 
     // blend fragment color between glow color and text color
     lowp vec4 glowColor = vec4( uGlowColor.rgb, uGlowColor.a * clampedColor.a );
     color = mix(glowColor, color, glowBlend);
 
     // fade out glow between uSmoothing and uGlow
-    color.a *= smoothstep(uGlow, uSmoothing, distance);
+    color.a *= smoothstep(uGlow, uSmoothing[0], distance);
 
     // final color multiplied by Actor color
     gl_FragColor = uColor * color;
index 65c134f..118cbe3 100644 (file)
 
 <FragmentShader>
 
-#extension GL_OES_standard_derivatives : enable
-
   uniform mediump sampler2D sTexture;
   uniform lowp    vec4      uColor;
-  uniform mediump float     uSmoothing;
+  uniform highp   vec2      uSmoothing;
   uniform mediump vec2      uOutline;
   uniform lowp    vec4      uOutlineColor;
 
-  varying mediump vec2      vTexCoord;
-  varying lowp vec4         vColor;
+  varying highp   vec2      vTexCoord;
+  varying lowp    vec4      vColor;
 
   void main()
   {
     // sample distance field
-    mediump float distance = texture2D(sTexture, vTexCoord).a;
-
-    mediump float smoothWidth = fwidth(distance) * 0.8;
-
-    mediump float outlineWidth = uOutline[1] + smoothWidth;
+    highp float distance = texture2D(sTexture, vTexCoord).a;
 
     // blend fragment color between outline color and text color
-    mediump float outlineBlend = smoothstep(uOutline[0] - outlineWidth, uOutline[0] + outlineWidth, distance);
+    highp float outlineBlend = smoothstep(uOutline[0], uOutline[1], distance);
     lowp vec4 clampedColor = clamp( vColor, 0.0, 1.0 );
     lowp vec4 outlineColor = vec4( uOutlineColor.rgb, uOutlineColor.a * clampedColor.a );
     lowp vec4 color = mix(outlineColor, clampedColor, outlineBlend);
 
     // adjust fragment alpha by sampled distance
-    color.a *= smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);
+    color.a *= smoothstep(uSmoothing[0], uSmoothing[1], distance);
 
     // final color multiplied by Actor color
     gl_FragColor = uColor * color;
index 36a272c..69cbb9d 100644 (file)
 
 <FragmentShader>
 
-#extension GL_OES_standard_derivatives : enable
-
   uniform mediump sampler2D sTexture;
   uniform lowp    vec4      uColor;
-  uniform mediump float     uSmoothing;
-  uniform mediump float     uShadowSmoothing;
+  uniform highp   vec2      uSmoothing;
+  uniform highp   vec2      uShadowSmoothing;
   uniform lowp    vec4      uShadowColor;
 
   varying highp   vec2      vTexCoord;
     mediump float distance = texture2D(sTexture, vTexCoord).a;
     mediump float shadow_distance = texture2D(sTexture, vShadowCoord).a;
 
-    mediump float smoothWidth = fwidth(distance) * 0.8;
-    mediump float shadow_smoothWidth = fwidth(shadow_distance) * 0.8;
-
-    mediump float inText = smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);
-    mediump float inShadow = smoothstep(uShadowSmoothing - shadow_smoothWidth, uShadowSmoothing + shadow_smoothWidth, shadow_distance);
+    mediump float inText = smoothstep(uSmoothing[0], uSmoothing[1], distance);
+    mediump float inShadow = smoothstep(uShadowSmoothing[0], uShadowSmoothing[1], shadow_distance);
 
     lowp vec4 color;
 
index 65ac917..eadb90a 100644 (file)
 
 <FragmentShader>
 
-#extension GL_OES_standard_derivatives : enable
-
   uniform mediump sampler2D sTexture;
+  uniform highp   vec4      sTextureRect;
   uniform lowp    vec4      uColor;
-  uniform mediump float     uSmoothing;
+  uniform highp   vec2      uSmoothing;
 
-  varying mediump vec2      vTexCoord;
+  varying highp vec2      vTexCoord;
 
 #ifdef USE_GRADIENT
   varying lowp    vec4      vColor;
@@ -49,9 +48,7 @@
   void main()
   {
     // sample distance field
-    mediump float distance = texture2D(sTexture, vTexCoord).a;
-
-    mediump float smoothWidth = fwidth(distance) * 0.8;
+    highp float distance = texture2D(sTexture, vTexCoord).a;
 
 #ifdef USE_GRADIENT
     lowp vec4 color = clamp(vColor, 0.0, 1.0);
@@ -60,7 +57,7 @@
 #endif
 
     // adjust fragment alpha by sampled distance
-    color.a *= smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);
+    color.a *= smoothstep(uSmoothing[0], uSmoothing[1], distance );
 
     // final color multiplied by Actor color
     gl_FragColor = uColor * color;
index 45da258..b76d5ef 100644 (file)
@@ -119,6 +119,17 @@ void TextAttachment::SetTextVertexBuffer( BufferIndex updateBufferIndex, TextVer
   }
 }
 
+void TextAttachment::SetTextFontSize( BufferIndex updateBufferIndex, float pixelSize )
+{
+  typedef MessageValue1< TextRenderer, float > DerivedType;
+
+  // Reserve some memory inside the render queue
+  unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+
+  // Construct message in the render queue memory; note that delete should not be called on the return value
+  new (slot) DerivedType( mTextRenderer, &TextRenderer::SetFontSize, pixelSize );
+}
+
 void TextAttachment::SetGradientColor( BufferIndex updateBufferIndex, const Vector4& color )
 {
   DALI_ASSERT_DEBUG(mSceneController);
index 365f296..4aad070 100644 (file)
@@ -75,6 +75,13 @@ public:
   void SetTextVertexBuffer( BufferIndex updateBufferIndex, TextVertexBuffer* vertexBuffer );
 
   /**
+   * Set the pixel size of the font, this is passed to the renderer
+   * @param updateBufferIndex The current update buffer index.
+   * @param pixelSize The new pixel size
+   */
+  void SetTextFontSize( BufferIndex updateBufferIndex, float pixelSize );
+
+  /**
    * Set the color associated with the gradient end point.
    * @param[in] updateBufferIndex The current update buffer index.
    * @param[in] color The gradient color (end-point color)
@@ -216,6 +223,17 @@ inline void SetTextVertexBufferMessage( EventToUpdate& eventToUpdate, const Text
   new (slot) LocalType( &attachment, &TextAttachment::SetTextVertexBuffer, &buffer );
 }
 
+inline void SetTextFontSizeMessage( EventToUpdate& eventToUpdate, const TextAttachment& attachment, float pixelSize )
+{
+  typedef MessageDoubleBuffered1< TextAttachment, float > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new (slot) LocalType( &attachment, &TextAttachment::SetTextFontSize, pixelSize );
+}
+
 inline void SetGradientColorMessage( EventToUpdate& eventToUpdate, const TextAttachment& attachment, const Vector4& color )
 {
   typedef MessageDoubleBuffered1< TextAttachment, Vector4 > LocalType;