cohtmlnamespace. This document will use the name of the library (Cohtml) instead of the name of SDK (Gameface) for the rest of it.
Cohtml draws the UI (a View) in a user-provided texture.This happens by calling
cohtml::ViewRenderer::SetRenderTarget. The texture must have 4 color channels and depth and stencil buffers attached. On OpenGL, a complete frame buffer must be passed with all its attachments set.
Cohtml performs incremental rendering by updating only the parts of the UI texture that have changed. It will not redraw everything in the UI, which improves performance significantly. The user should not draw anything on the UI texture, except the output of Cohtml. Internally Cohtml uses the Coherent Labs Renoir graphics library.
Cohtml asynchronously records rendering commands that are later executed on the render thread
cohtml::ViewRenderer::Paint(). This method draws the new frame if one was recorded, or returns immediately if nothing in the UI has changed.
This is the reason every
View object has a corresponding
View lives on the main thread and “controls” the page, while the
ViewRenderer is only in charge of drawing it and lives on the render thread.
On different platforms, Cohtml can draw with different rendering APIs. The API-specific code is encapsulated in a Renoir backend.
The application can also define its rendering backend that uses the graphics facilities it has, or modify the existing backends provided in the Cohtml package.
The backend is registered and used with a call to
cohtml::SystemRenderer::RegisterRenderThread. This call tells Cohtml which is the render thread and what backend to use during View rendering.
The backends themselves are objects that implement the
renoir::RendererBackend interface. The backends provided in the Cohtml package can be used as a starting point for modification, or for implementing new backends.
Cohtml comes with the following backends:
- DirectX 11
- OpenGL 3.3+
- OpenGL ES 2
- OpenGL ES 3
- DirectX 12
VkViewportin order to force y-inversion of the clip-space to framebuffer-space transform.
Rendering Platform Specifics
The Vulkan SDK includes validation layers, which hook into API entry points and provide debugging functionality. In our samples we enable Vulkan validation layers by default on Windows, but not on Android. The motivation for this is, that on Android the layers should be explicitly packaged in the
apk. Generally, the following guide should be followed. Alternatively, if you want to package the validation layers in an already built
apk, you can use ApkTool and SignApk to do so. This can be achieved by extracting all the tools in the
apk output directory and executing a script similar to the following one:
@ECHO OFF SETLOCAL SET FileName=ActivityCohtml SET Platform=armeabi-v7a SET AndroidNDKPath=C:\Microsoft\AndroidNDK64\android-ndk-r16b SET ValidationLayerFolder=%AndroidNDKPath%\sources\third_party\vulkan\src\build-android\jniLibs\%Platform% SET ApkTool=apktool_2.3.3.jar ECHO %FileName% java -jar %ApkTool% d %FileName%.apk` copy /Y %ValidationLayerFolder%\libVkLayer_core_validation.so %FileName%\lib\%Platform%\ copy /Y %ValidationLayerFolder%\libVkLayer_image.so %FileName%\lib\%Platform%\ copy /Y %ValidationLayerFolder%\libVkLayer_object_tracker.so %FileName%\lib\%Platform%\ copy /Y %ValidationLayerFolder%\libVkLayer_parameter_validation.so %FileName%\lib\%Platform%\ copy /Y %ValidationLayerFolder%\libVkLayer_swapchain.so %FileName%\lib\%Platform%\ copy /Y %ValidationLayerFolder%\libVkLayer_threading.so %FileName%\lib\%Platform%\ copy /Y %ValidationLayerFolder%\libVkLayer_unique_objects.so %FileName%\lib\%Platform%\ java -jar %ApkTool% b %FileName% move %FileName%\dist\%FileName%.apk %FileName%_UNALIGNED.apk java -jar signapk.jar certificate.pem key.pk8 %FileName%_UNALIGNED.apk %FileName%.apk del %FileName%_UNALIGNED.apk rmdir /s /q %FileName% ENDLOCAL
Advanced Rendering Debugging
Developers can gain further insight into the rendering commands generated during runtime by calling the
View::EmitRenderingMetadata method. Metadata markers will be inserted in the rendering command stream that can be hooked to third-party tools like PIX, RenderDoc, Razor etc., or internal engine profilers. The markers will show which elements generate every rendering command in the stream. The backend should also implement the marker-related commands, for the DirectX 11 backend you should enable the
DX11_ANNOTATE_EVENTS define, which by default is enabled only in
Reusing command buffer memory
Gameface uses Command Buffers for serializing the rendering commands, generated by the CoHTML library. These buffers are then passed to the Renoir graphics library, which traverses them and transforms them into Backend Command Buffers, usable by the graphics backend implemented by the client. This transformation process is executed by the Command Processor, which owns the Backend Command Buffers.
Drawing a frame requires allocations for all these buffers so it makes sense to create a pool of them for reuse, and thus decreasing the amount of allocations from the OS.
Clients can control both the amount of objects and size in bytes in the Command Buffer/Processor pools. This is done using the APIs
View::QueueClearCaches and the likes. The new enumeration entries
cohtml::InternalCaches::ICACHE_GfxCommandProcessors control the Command Buffer/Processor cache counts, respectively.
Font generation on the GPU
SDF on GPU - Font generation on the GPU.
Combating gradient banding
Dithering the gradient rendering - Gradients dithering.
Resource state transitions
Resource state transitions - Support for resource state transitions generated by the rendering library.