Skip to content
SiteEmail

API

Regenerated the license keys used for initialization of the library

API

The window.load event no longer waits for images loaded through CSS

API

Samples for Microsoft UWP and GDK platforms now use the Microsoft Visual Studio 2022 toolset

API

Prebuilt Renoir rendering backends now use Microsoft Windows SDK 10 and the Microsoft Visual Studio 2022 toolset

API Unity

Deprecated View in favor of NativeView property of the CohtmlView component

API

Removed the PreferCPUWorkload option from backend's capabilities

API

Removed the GLES2 support

API

Removed the Shape Morphing support

API

Changed rendering backend's capabilities to fit for the new command batching flow. Read more in the migration guide.

API

Changed shaders' vertex layout to fit for the new command batching flow. Read more in the migration guide.

API

Added new commands in the rendering backend which need to be handled for the new command batching flow. Read more in the migration guide.

API

Changed constant buffers in the rendering backends to fit for the new command batching flow. Read more in the migration guide.

API

Removed support for Microsoft XDK (aka Durango) SDK for Microsoft Xbox One consoles

Feature

Added support for Touch and TouchEvent constructors for all platforms except UWP arm

Feature

Added support for capturing a screenshot in the inspector and through the dev tools protocol

Feature

Enhanced batching of the rendering commands which combines the CPU and GPU workload and improves the efficiency. Check the migration guide.

Feature

TouchEvent.touches now contains information about all touches

Feature

The Player application can now receive touch events on Microsoft Windows

Enhancement

Added resize logic for all samples using UI Composition, Surface Partitioning, and Backdrop Filter features

Enhancement

Added support for backface-visibility CSS style

Enhancement

Added support for GPOS kerning for fonts

Enhancement

Added partial support for SVG transform, width, height, and viewbox JavaScript properties

Enhancement Unreal Engine

Improved the sample hub UI

Enhancement

Updated FreeType to version 2.13.2

Enhancement

Added GPU memory tracking to profiling output

Enhancement

Optimized performance of border-image with SVG

Enhancement

Added support for sending input events to composited surfaces

Fix

Fixed a deadlock when scratch textures caches are being cleared

Fix

Fixed incorrect marking of scratch textures as not usable

Fix

Fixed a crash when try to read an invalid FreeType face

Fix

Fixed incorrect SVG clipping with clip-path and mask elements when using them in user space

Fix

Fixed positioning of nested elements when using cohinline

Fix

Fixed mouse events not firing correctly for cohinline elements

Fix Unity

Fixed rendering problems with OpenGL and C# Backend in Unity

Fix

Fixed leaking transformations when scaling SVGs to sizes smaller than 1 pixel

Fix

Fixed a crash in the Player with HTTP requests on quit

Fix

Fixed text nodes being 1 pixel larger then necessary that led to incorrect positioning when using right alignment

Fix

Fixed missing texture when an image is used for only one frame

Fix Unity

Fixed the errors encountered when the Samples were removed from the package

Fix Unity

Fixed the backdrop filter texture format type in HDR mode

Fix

Fixed requestAnimationFrame callbacks executing on the same frame

Fix Unity

Fixed the OnGUI events input regression caused by the latest input performance upgrades in Input Manager mode.

Fix

Passing an empty string to textContent property won't create empty text nodes

Fix

Fixed cases where event listeners are not fired when other unrelated event listeners are removed

Fix

Fixed excessive character vertical offset with certain fonts

Fix

Fixed a crash caused by improper use of GIFs as background images

Fix

Fixed a warning when setting the animation shorthand property to none

Fix Unreal Engine

Fixed safe zone and letter boxing on the Apple iPhone devices

Fix Unreal Engine

Removed forgotten experimental mentions from the documentation regarding Android and iOS platforms

Fix Unreal Engine

Address accumulation of frames for painting when UMG Widgets are hidden or minimized

Fix Unreal Engine

Fixed PlayerOverrides build issues

Fix Unreal Engine

Fixed UE package unzipping issue with the native Windows File Explorer manager

Fix

Fixed composition with custom effects

Fix Unity

Fixed crashes when rapidly starting and stopping the Player in the Unity3D Editor

Fix Unity

Fixed order of touch events in Unity3D when Input Manager is used

Fix

Removed forgotten experimental mentions from the documentation regarding inline layout, complex text, and SDF on GPU features

Fix Unity

Removed forgotten experimental mentions from the documentation regarding the C# backend feature

Fix

Fixed a bug with upgrading cloned custom elements that prevented their lifetime callbacks to be invoked

Fix

The inspector now shows the views for inspection only when they have a valid document loaded

Fix

Fixed CSS calc functions failing when running with locale settings where the decimal symbol is not a dot

Fix

Fixed a crash when clearing SVG surfaces caches

Fix

Fixed invoking newly added event listeners during the dispatching of the event

With the introduction of the new rendering flow, we've decided to remove the CPU workload mode.

With that in mind, all resources and types connected to it are now removed. Such as:

  • All shaders that have *Batched* in their name
    • CohStandardBatchedVS.hlsl
    • CohStandardBatchedPS.hlsl
    • CohShadeGeometryBatched.ihlsl
  • All *Batched* shader types:
    • ST_StandardBatched
    • ST_StandardBatchedTexture
    • ST_BatchedText
    • ST_BatchedTextSDF
    • ST_BatchedTextSDFGPU
    • ST_BatchedTextMSDF
  • The member from the backend's RendererCaps called PreferCPUWorkload is removed

For the past months, we have been working on redesigning and improving the rendering flow in Renoir - the 2D library of Gameface. We're excited to announce a significant enhancement of the batching system that will help you create a more stunning UI that runs faster than ever.

What are the benefits:

  • Up to 60% less rendering commands
  • Up to 30% faster on CPU
  • 33% less GPU memory for Vertex buffers
  • Up to 50% less GPU memory for Constant buffers

We've decided to stop supporting GLES2 for a few reasons:

  • It is an old API and there are new which are more widespread and have better performance and support.
  • Its usage has declined. According to the Khronos Group, only 2% of mobile devices are shipped with GLES2 as a primary graphics API. This means that the vast majority of devices are with GLES or Vulkan.
  • Due to its limitations, we couldn't implement some features or they were turning the complexity of the code into a burden.
  • The most known engines such as Unreal and Unity3D already dropped the support for them.
  • One of the vertex attributes (CBInides in the StandardVertex for example) is used for passing encoded values from the CPU to the GPU, so we need to transfer the same bytes to the GPU. When we bind the vertex attribute in GLES3 we use glVertexAttribIPointer, however, it's not supported on GLES2, so we can't pass the same bytes to the GPU which is breaking the decoding process.
  • For the path rendering we use instance drawing which is not supported on GLES2

This was a feature that the predecessor of the CSS SVG animations and it was in a custom format. Since now you can achieve the same with CSS we've decided to remove it.

The following shader types are removed:

  • ST_StencilAnimatedPathBezier
  • ST_StencilAnimatedPathTriangle

One of the features we are excited to introduce is the new rendering flow, which allows us to batch the rendering commands more efficiently. Moreover, since we had 2 flows by now - GPU and CPU workloads, the new one will unify them by getting the good parts in both of them.

However, this feature required some modifications to the architecture of the rendering backends, which we will explain in this section.

  • Removed all of the current constant buffers

  • Created 2 new ones instead:

    • Data_VS - an array of float4 used only in the Vertex stage
    • Data_PS - an array of float4 used only in the Pixel stage
  • Note: The size of the arrays might differ between rendering APIs. Check RenoirBackends/Common/ShaderConstants.inl - COH_VS_BUFFER_SIZE and COH_PS_BUFFER_SIZE.

One of the objectives of the layout modifications is to minimize the amount of memory that each vertex consumes.

Previously, we have had 3 RGBA32_FLOAT attributes (Position, Color, Additional) for StandardVertex. Now it is:

  • The format of the Position is changed from RGBA32_FLOAT to RGB32_FLOAT
  • Added new attribute CBIndices which is RGBA8_UINT - here we'll encode the offsets in constant buffers(Vertex & Pixel) for each geometry
  • Removed the attribute Color
Before (48 bytes):
const D3D11_INPUT_ELEMENT_DESC StandardVertexLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
New (32 bytes):
const D3D11_INPUT_ELEMENT_DESC StandardVertexLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R8G8B8A8_UINT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

The vertex used for path rendering was only 1 RGBA32_FLOAT for Position but now, because of the constant buffers we need to pass additional data per instance which is in the CBIndices - a RGBA8_UINT attribute. There is no path vertex size change, however, now we create a new type of vertex buffer VT_SlimInstanceData for the instancing data and when we render paths we set 2 vertex buffer streams.

Old Path Vertex:
const D3D11_INPUT_ELEMENT_DESC SlimVertexLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
New Path Vertex:
const D3D11_INPUT_ELEMENT_DESC SlimVertexLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "VS_SEMANTIC_INSTANCED", 0, DXGI_FORMAT_R8G8B8A8_UINT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, // the last param is the stream index
};

Due to the StandardVertex changes we need to introduce a new vertex used only for drawing SDF atlases called GlyphVertex:

const D3D11_INPUT_ELEMENT_DESC GlyphVertexLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R8G8B8A8_UINT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

From the vertex layout explanation, we talked about the CBIndices attribute. To use it in the shaders we need to decode the information from it. Let's see how we do that:

* The example for decoding in DX11. The code is taken from CohPlatform.ihlsl.
void decode(uint4 encoded, inout int vs_cb_offset, inout int ps_cb_offset, inout int ps_type)
{
// 0/x 1/y 2/z 3/w
// [vs_cb] [vs_cb4|ps_cb4] [ps_cb] [ps_type]
vs_cb_offset = ((encoded[1] & 0xF) << 8) | encoded[0];
ps_cb_offset = (encoded[2] << 4) | ((encoded[1] & 0xF0) >> 4);
ps_type = encoded.w;
}

In each CBIndices attribute we have:

  • 12 bits for the offset in the vertex constant buffer
  • 12 bits for the offset in the pixel constant buffer
  • 8 bits for the pixel shader type by which we decide how exactly to shade the pixel

Two new backend commands are introduced which need to be handled:

  • BC_SetMultipleVertexBuffers
    • As we said earlier we set 2 buffers for the path rendering - 1 for the path data, 1 for the instancing
  • BC_DrawIndexedInstanced
    • To draw geometry using instancing - used for path rendering

With the new rendering pipeline, we made changes to the BackendCaps structure which fills the capabilities of the backend for specific graphics API.

  • Added properties:

    • PersistentConstantBuffersCount - This is the count of the constant buffer we'll keep alive per Stage (Vertex and Pixel)
    • MaxRegistersForVertexConstantBuffer - The maximum count of float4 to be used in the constant buffer
    • MaxRegistersForPixelConstantBuffer - The maximum count of float4 to be used in the constant buffer
  • Removed properties:

    • ConstantBufferBlocksCount - Changed to PersistentConstantBuffersCount - The count of the constant buffers that will live through the whole lifetime of the library. If a scene uses more than that for a frame - they will be destroyed.
    • ConstantBufferBlockAlignment - The alignment now will be applied only when the buffer is being allocated, so we don't need to pass it internally to Renoir.
    • SupportsSharedIndexBuffers - It was an optimization that reuses a sequence from the index buffer to more than 1 batch of rectangles. Now we can't use it anymore because we batch more geometries that differ in their indices.
    • PreferCPUWorkload - The rendering flow that was designed mainly for mobile platforms, due to its more CPU and less GPU usage.
    • RequiresDrawFences - Hints that the API required explicit draw fences - it was unused
    • RequiresShaderTypeInShader - Tells if the user has set a shader mapping or not. Now it's always true.
    • SupportsNPOTTextureOps - Tells if the backend supports linear sampling on NPOT texture - all supported graphics APIs are supporting that, so no there is no need to have it.