From 60ed9bc9563197af53546603254dd45e02db36a4 Mon Sep 17 00:00:00 2001 From: Javon Prince Date: Thu, 10 Apr 2014 09:20:15 +0100 Subject: [PATCH] Text: Quality improvement 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 --- .../actor-attachments/text-attachment-impl.cpp | 5 ++++ .../render/renderers/scene-graph-text-renderer.cpp | 33 +++++++++++++++++++--- .../render/renderers/scene-graph-text-renderer.h | 7 +++++ .../shader-source/distance-field-font-glow.txt | 12 +++----- .../distance-field-font-outline-glow.txt | 18 ++++-------- .../shader-source/distance-field-font-outline.txt | 18 ++++-------- .../shader-source/distance-field-font-shadow.txt | 13 +++------ .../render/shader-source/distance-field-font.txt | 13 ++++----- .../scene-graph-text-attachment.cpp | 11 ++++++++ .../node-attachments/scene-graph-text-attachment.h | 18 ++++++++++++ 10 files changed, 95 insertions(+), 53 deletions(-) diff --git a/dali/internal/event/actor-attachments/text-attachment-impl.cpp b/dali/internal/event/actor-attachments/text-attachment-impl.cpp index 5374c7d..cf53078 100644 --- a/dali/internal/event/actor-attachments/text-attachment-impl.cpp +++ b/dali/internal/event/actor-attachments/text-attachment-impl.cpp @@ -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() ); + } } } diff --git a/dali/internal/render/renderers/scene-graph-text-renderer.cpp b/dali/internal/render/renderers/scene-graph-text-renderer.cpp index ed04693..b7e450a 100644 --- a/dali/internal/render/renderers/scene-graph-text-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-text-renderer.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -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) { } diff --git a/dali/internal/render/renderers/scene-graph-text-renderer.h b/dali/internal/render/renderers/scene-graph-text-renderer.h index 89762a2..89ad97d 100644 --- a/dali/internal/render/renderers/scene-graph-text-renderer.h +++ b/dali/internal/render/renderers/scene-graph-text-renderer.h @@ -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; }; diff --git a/dali/internal/render/shader-source/distance-field-font-glow.txt b/dali/internal/render/shader-source/distance-field-font-glow.txt index f86ccc6..8d29264 100644 --- a/dali/internal/render/shader-source/distance-field-font-glow.txt +++ b/dali/internal/render/shader-source/distance-field-font-glow.txt @@ -27,12 +27,10 @@ -#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; diff --git a/dali/internal/render/shader-source/distance-field-font-outline-glow.txt b/dali/internal/render/shader-source/distance-field-font-outline-glow.txt index 605cf56..a9088f9 100644 --- a/dali/internal/render/shader-source/distance-field-font-outline-glow.txt +++ b/dali/internal/render/shader-source/distance-field-font-outline-glow.txt @@ -27,14 +27,12 @@ -#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; @@ -45,12 +43,8 @@ // 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 ); @@ -58,14 +52,14 @@ 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; diff --git a/dali/internal/render/shader-source/distance-field-font-outline.txt b/dali/internal/render/shader-source/distance-field-font-outline.txt index 65c134f..118cbe3 100644 --- a/dali/internal/render/shader-source/distance-field-font-outline.txt +++ b/dali/internal/render/shader-source/distance-field-font-outline.txt @@ -27,34 +27,28 @@ -#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; diff --git a/dali/internal/render/shader-source/distance-field-font-shadow.txt b/dali/internal/render/shader-source/distance-field-font-shadow.txt index 36a272c..69cbb9d 100644 --- a/dali/internal/render/shader-source/distance-field-font-shadow.txt +++ b/dali/internal/render/shader-source/distance-field-font-shadow.txt @@ -29,12 +29,10 @@ -#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; @@ -47,11 +45,8 @@ 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; diff --git a/dali/internal/render/shader-source/distance-field-font.txt b/dali/internal/render/shader-source/distance-field-font.txt index 65ac917..eadb90a 100644 --- a/dali/internal/render/shader-source/distance-field-font.txt +++ b/dali/internal/render/shader-source/distance-field-font.txt @@ -32,13 +32,12 @@ -#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; diff --git a/dali/internal/update/node-attachments/scene-graph-text-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-text-attachment.cpp index 45da258..b76d5ef 100644 --- a/dali/internal/update/node-attachments/scene-graph-text-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-text-attachment.cpp @@ -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); diff --git a/dali/internal/update/node-attachments/scene-graph-text-attachment.h b/dali/internal/update/node-attachments/scene-graph-text-attachment.h index 365f296..4aad070 100644 --- a/dali/internal/update/node-attachments/scene-graph-text-attachment.h +++ b/dali/internal/update/node-attachments/scene-graph-text-attachment.h @@ -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; -- 2.7.4