Technical Overview
On this page
cohtml
namespace. The name of the library (Cohtml) is used throughout the rest of this document, instead of the name of the SDK (Prysm).At a high-level Cohtml does the following things to render your UI:
- Load and parse HTML files.
- Build a DOM of the page.
- Load and parse CSS styles. Styling allows for having very rich interfaces with a complex layout and visuals.
- Load image files and fonts.
- Images should use premultiplied alpha for correct display
- It is recommended to use DirectXTex/texconv for converting DDS files.
- The correct command line for texconv includes the “-dx10” and “-pmalpha” arguments, for example
texconv.exe -ft dds -pmalpha -f BC7_UNORM -dx10 input.png
- Images should use premultiplied alpha for correct display
- Load and execute JavaScript code. JavaScript is used to code more advanced logic for the user interface.
- Communicate with the client application to send/receive commands or input.
- Render the page in a texture. Cohtml uses Renoir - Coherent Labs' internal rendering library that draws the page in a texture that can be used by the client application.
In Prysm terms, a page along with its styles, DOM and JS code is called a
CohtmlView
component
. You can have as many Views as you need in your application.
Cohtml has an advanced task-based architecture that tries to make the best use of all cores and computational power of the device while saving battery at the same time. Key technical features of Cohtml include:
- Task-based architecture. Many operations in Cohtml run on worker threads, which improves scalability, overall performance and battery duration.
- Data-oriented design. Internally Cohtml owes much of its performance to a modern data-oriented design.
- High-performance rendering with advanced batching. An additional performance boost is given by the fact that only changed parts of a page are re-drawn each frame - not the whole UI.
- Asynchronous resource loading. All resources are loaded in worker threads so that the main UI thread doesn’t get stalled.
- Full control over memory allocations, file loading, logging and rendering. Users can control how memory and files are loaded. Custom rendering backends can be easily developed with the provided interfaces.
- Support for iOS, Android, Windows, PlayStation 4, Xbox One, UWP and Mac OS X and Linux.
Multithreading
Key to the scalability and performance of Cohtml is its multithreaded architecture. In the context of Cohtml, the UI thread can be defined as the thread where the
cohtml.Net.View.Advance
method is being called. This is often the main thread of the application and usually the thread where the user interacts with the UI logic - sending events, input and executing JavaScript. Typically, using the app’s main thread as the UI thread is the preferred approach, as it allows for more seamless integration and data synchronization. Nevertheless, all of the System
and View
methods, unless explicitly stated otherwise, can be invoked from any thread if needed(e.g. to move some/all of the UI logic onto a separate thread). These calls must not execute concurrently on multiple threads(e.g. View methods must not be called on another thread while Advance is running).
The other thread on which the user interacts with Cohtml is the “Render” thread. This is usually the thread that submits commands to the GPU. On that thread, the methods of the ViewRenderer
should be called which will, in turn, execute the necessary rendering commands. Additional work includes View resource loading, View Layout, JavaScript garbage collection, etc. All these operations must be scheduled by the user on worker threads, or dedicated threads should be created to handle those tasks.
Cohtml will not create threads behind the scenes as they might interfere with the workload of the application.
Library::Initialize
was called as the UI thread. In previous versions, calling View
/System
APIs on different threads is not allowed(unless otherwise specified, see documentation for the specific version in the package).The different work “channels” are:
- UI thread: holds the DOM and executes the JavaScript code. Generally, this is the thread on which the
cohtml.Net.View.Advance
method is called. In most cases, this is also the main thread of the application. - Render thread: the
ViewRenderer
methods are called on this thread. It should have access to the rendering subsystem and the rendering commands will be executed on it. This is usually the render thread of the application. It can change, but you can only execute one “Paint” concurrently. - N Worker threads & Layout threads: Cohtml generates work for worker threads for many activities including resource loading; parsing, layout etc. The Layout operation can also happen on the UI thread in the
cohtml.Net.View.Advance
method. This is controlled by thecohtml.Net.LibraryParamsWithExternalRenderingLibrary.UseDedicatedLayoutThread
flag. The Layout is a heavy operation and it’s strongly recommended to let it happen on a worker thread. Using a layout thread is highly recommended as it will significantly reduce thecohtml.Net.View.Advance
time and improve scalability.
Worker threads execute Resources and Layout tasks. Resources tasks are global for all Cohtml Views, as they share the image loading and caching, parsing etc. resources. However, the Layout tasks can be scheduled per View. This allows better scalability and having a separate thread per View Layout is thus possible, although not recommended.
It’s possible for Layout tasks to depend on resources, hence not executing Resources tasks can lead to delays of the Layout tasks, which can potentially lead to blocking on the next frame until the previous Layout completes. For example, text layout depends on font glyph data. Because fonts are loaded partially in Cohtml,
cohtml.Net.View.Advance
can schedule tasks for loading specific glyph data from registered fonts. Layout tasks will be scheduled only after glyph loading tasks are complete. This is required for each new glyph in the document to properly layout elements on a page.
ContextMenu->Prysm->DevTools
. Click on the Performance
tab and start recording for as long as you need.