Porting from 1.2 to 1.3

Resources Now Load via FileSystem

The library requires several files (currently icudt67l.dat and cacert.pem as of this writing) to function properly.

Previously, the library would load these files directly from disk using the resources path set in Config.

Now, the library will load these files from the FileSystem API-- for example, the library will now call FileSystem::OpenFile() with the path resources/cacert.pem when it needs to load the SSL certificate chain. (Customizable via Config::resource_path_prefix)

Furthermore, failure to load these files will now cause the library to trigger a fatal assertion (eg, exit(-1);).

FileSystem Now Required to Be Defined

For the above reason, you must now define a valid FileSystem implementation via Platform::set_file_system() before calling Renderer::Create().

(You don't need to define one when using App::Create(), it provides a default implementation for each OS).

Portions of Config Have Been Moved to ViewConfig

You can now set a number of config options on a per-View basis (instead of setting these values globally). You do this by passing a new ViewConfig struct to Renderer::CreateView().

For example, if you're using the low-level Renderer API, you can now have each View use the CPU or GPU renderer via the new is_accelerated option in ViewConfig.

/// Whether to render using the GPU renderer (accelerated) or the CPU renderer (unaccelerated).
/// This option is only valid if you're managing the Renderer yourself (eg, you've previously
/// called Renderer::Create() instead of App::Create()).
/// When true, the View will be rendered to an offscreen GPU texture using the GPU driver set in
/// Platform::set_gpu_driver. You can fetch details for the texture via View::render_target.
/// When false (the default), the View will be rendered to an offscreen pixel buffer using the
/// multithreaded CPU renderer. This pixel buffer can optionally be provided by the user--
/// for more info see Platform::set_surface_factory and View::surface.
bool is_accelerated = false;

You can also now set a separate device scale (DPI scale) for each View via initial_device_scale:

double initial_device_scale = 1.0;

This device scale can be changed during runtime via View::set_device_scale().

CPU and GPU Renderers Now Use the Same Compositing Pipeline

The CPU and GPU renderers previously used separate compositing/blending math and font compositing routines which caused subtle differences in the visual output (especially when alpha-blending certain transparent PNGs and CSS opacity layers).

The pipelines have now been rewritten to blend in sRGB space which better matches what Chrome and Firefox are doing in their renderers.

Furthermore, alpha correction of fonts has been improved to be more robust when rendering against transparent backgrounds (important for compositing text in games).

Ref<> Has Been Removed, RefPtr<> Now Used For All Ref-Counted Types

RefPtr<> is now used to manage all ref-counted objects in the Ultralight API.

We previously had a non-nullable version of RefPtr<> called Ref<> but this has been removed for the sake of clarity and correctness.

Multi-Window Support in AppCore

AppCore now allows users to create multiple windows in a single app-- you no longer need to call App::set_window()-- just create a window and it will appear on screen.

You can also now create hidden windows and show them at a later time (important for pre-loading content).

You Must Now Call App::Quit() Manually in AppCore

Previously, apps would automatically call App::Quit() when the window was closed.

Since apps now support multiple windows, it's indetermine which one of these should cause the app to quit.

For that reason, you must now call App::Quit() yourself to exit the run loop. We recommend handling WindowListener::OnClose() and calling this yourself when your "main window" is closed.