docs
Loading...
Searching...
No Matches
CAPI_Renderer.h
Go to the documentation of this file.
1///
2/// Copyright (C) 2026 Ultralight, Inc. All rights reserved.
3/// A license is required for commercial use. https://ultralig.ht
4///
5
6///
7/// @file CAPI_Renderer.h
8///
9/// Core renderer singleton for the library, coordinates all library functions.
10///
11/// `#include <Ultralight/CAPI/CAPI_Renderer.h>`
12///
13/// The Renderer class is responsible for creating and painting Views, managing Sessions, as well
14/// as coordinating network requests, events, JavaScript execution, and more.
15///
16/// ## Creating the Renderer
17///
18/// \parblock
19/// @note A Renderer will be created for you automatically when you call ulCreateApp (access it
20/// via ulAppGetRenderer()).
21/// \endparblock
22///
23/// \parblock
24/// @note ulCreateApp() is part of the AppCore API and automatically manages window creation, run
25/// loop, input, painting, and most platform-specific functionality. (Available on desktop
26/// platforms only)
27/// \endparblock
28///
29/// ### Defining Platform Handlers
30///
31/// Before creating the Renderer, you should define your platform handlers via the Platform
32/// singleton (see CAPI_Platform.h). This can be used to customize file loading, font loading,
33/// clipboard access, and other functionality typically provided by the OS.
34///
35/// Default implementations for most platform handlers ship as Zlib-licensed source in the SDK's
36/// `platform` folder. You can use these stock implementations by copying the code into your
37/// project, or you can write your own.
38///
39/// At a minimum, you must provide a ULFileSystem and a ULFontLoader. Without them, the library
40/// exits the process with an error when it first needs them.
41///
42/// ### Creating the Renderer
43///
44/// Once you've set up the Platform handlers you can create the Renderer by calling
45/// `ulCreateRenderer()`.
46///
47/// @par Example creation code
48/// ```
49/// // Setup our config.
50/// ULConfig config = ulCreateConfig();
51///
52/// // Use the default platform font loader.
53/// ulEnablePlatformFontLoader();
54///
55/// // Use the default platform file system to load file:/// URLs from the OS.
56/// ULString base_dir = ulCreateString("./assets/");
57/// ulEnablePlatformFileSystem(base_dir);
58/// ulDestroyString(base_dir);
59///
60/// // Create the renderer.
61/// ULRenderer renderer = ulCreateRenderer(config);
62///
63/// // Destroy the config.
64/// ulDestroyConfig(config);
65///
66/// // Set up Views here...
67/// ```
68///
69/// ## Updating Renderer Logic
70///
71/// You should call ulUpdate() from your main update loop as often as possible to give the
72/// library an opportunity to dispatch events and timers:
73///
74/// @par Example update code
75/// ```
76/// void mainLoop()
77/// {
78/// while(true)
79/// {
80/// // Update program logic here
81/// ulUpdate(renderer);
82/// }
83/// }
84/// ```
85///
86/// ## Rendering Each Frame
87///
88/// When your program is ready to display a new frame (usually in sync with the monitor's
89/// refresh rate), you should call ulRefreshDisplay() and ulRender() so the library can render
90/// all active Views as needed.
91///
92/// Animations and smooth scrolling advance with each ulRefreshDisplay() call. Call it once per
93/// frame you present (once per display refresh for a vsynced loop, or once per rendered frame for
94/// a vsync-off or variable-refresh game loop).
95///
96/// @par Example per-frame render code
97/// ```
98/// void displayFrame()
99/// {
100/// // Notify the renderer that the main display has refreshed. This updates animations,
101/// // smooth scrolling, and window.requestAnimationFrame() for all Views on that display.
102/// ulRefreshDisplay(renderer, 0);
103///
104/// // Render all Views as needed
105/// ulRender(renderer);
106///
107/// // Each View renders to a
108/// // - Pixel-Buffer Surface (ulViewGetSurface())
109/// // or
110/// // - GPU texture (ulViewGetRenderTarget())
111/// // based on whether CPU or GPU rendering is used.
112/// //
113/// // You will need to display the image data here as needed.
114/// }
115/// ```
116///
117#ifndef ULTRALIGHT_CAPI_RENDERER_H
118#define ULTRALIGHT_CAPI_RENDERER_H
119
121
122#ifdef __cplusplus
123extern "C" {
124#endif
125
126///
127/// Create the core renderer singleton for the library.
128///
129/// You should set up the Platform singleton (see CAPI_Platform.h) before calling this function.
130///
131/// @param config The configuration to use for the renderer.
132///
133/// @return Returns the new renderer instance, or NULL on failure. You must call
134/// ulDestroyRenderer() when finished.
135///
136/// \parblock
137/// @note You do not need to call this if you're using ulCreateApp() from AppCore.
138/// \endparblock
139///
140/// \parblock
141/// @warning You must define a ULFontLoader and a ULFileSystem in the Platform singleton.
142/// Without them, the library exits the process with an error when it first needs
143/// them.
144/// \endparblock
145///
146/// \parblock
147/// @warning You should only create one Renderer during the lifetime of your program.
148/// \endparblock
149///
151
152///
153/// Destroy a renderer previously created with ulCreateRenderer().
154///
155/// @param renderer The renderer instance to destroy (can be NULL).
156///
158
159///
160/// Update timers and dispatch internal callbacks (JavaScript and network).
161///
162/// @param renderer The active renderer instance.
163///
165
166/// ## Rendering Each Frame
167///
168/// When your program is ready to display a new frame (usually in synchrony with the monitor
169/// refresh rate), you should call ulRefreshDisplay() and ulRender() so the library can render
170/// all active Views as needed.
171///
172/// Animations and smooth scroll advance to each ulRefreshDisplay() call. Call it once per frame
173/// you present (once per display refresh for a vsynced loop, or once per rendered frame for a
174/// vsync-off or variable-refresh game loop).
175///
176
177///
178/// Notify the renderer that a display has refreshed.
179///
180/// Call this once per frame you present, for each display (usually right after vsync). It
181/// advances animations, smooth scrolling, and `window.requestAnimationFrame()` for the Views on
182/// that display, so they can repaint during the next ulRender().
183///
184/// @param renderer The active renderer instance.
185///
186/// @param display_id The id of the display that refreshed (see ulViewConfigSetDisplayId()).
187///
188/// \parblock
189/// @note Keep calling this even while ulViewGetNeedsPaint() returns false: animations only
190/// request a repaint from this call.
191/// \endparblock
192///
193/// \parblock
194/// @note Call this on the thread the renderer was created on.
195/// \endparblock
196///
197ULExport void ulRefreshDisplay(ULRenderer renderer, unsigned int display_id);
198
199///
200/// Notify the renderer that a display has refreshed, and when the resulting frame will be
201/// shown.
202///
203/// This works like ulRefreshDisplay(), but animation time follows your timestamps instead of the
204/// wall clock, so animations are timed for the moment the frame reaches the screen.
205///
206/// @param renderer The active renderer instance.
207///
208/// @param display_id The id of the display that refreshed.
209///
210/// @param target_timestamp When this frame will be shown, in seconds. Use the system's
211/// monotonic clock (eg, the target time your display link reports),
212/// or your own timeline after calling
213/// ulRendererSetDisplayUsesCustomClock(). Timestamps must never
214/// decrease.
215///
216/// @note `performance.now()` stays on the wall clock, so pages that compare it to
217/// `window.requestAnimationFrame()` timestamps will see the difference.
218///
219/// @see ulRendererSetDisplayRefreshRate(), ulRendererSetDisplayUsesCustomClock()
220///
221ULExport void ulRefreshDisplayWithTimestamp(ULRenderer renderer, unsigned int display_id,
222 double target_timestamp);
223
224///
225/// Declare a display's refresh rate.
226///
227/// Pages see the declared rate through `window.requestAnimationFrame()` scheduling. Call this
228/// when the display's mode changes (eg, a variable-rate display switching between 120 Hz and
229/// 48 Hz). Small changes are absorbed, and a change reaches pages at most once a second.
230///
231/// @param renderer The active renderer instance.
232///
233/// @param display_id The id of the display.
234///
235/// @param refresh_rate The display mode's nominal refresh rate in Hz (eg, 60.0, 59.94,
236/// 120.0), or 0 to clear it (the library then measures how often
237/// ulRefreshDisplay() is called).
238///
239/// @note Call this on the thread the renderer was created on.
240///
241ULExport void ulRendererSetDisplayRefreshRate(ULRenderer renderer, unsigned int display_id,
242 double refresh_rate);
243
244///
245/// Get the refresh rate declared for a display.
246///
247/// @param renderer The active renderer instance.
248///
249/// @param display_id The display ID.
250///
251/// @return Returns the display's declared refresh rate (in Hz), or 0 if
252/// ulRendererSetDisplayRefreshRate() was never called for it.
253///
254ULExport double ulRendererGetDisplayRefreshRate(ULRenderer renderer, unsigned int display_id);
255
256///
257/// Declare that a display's refresh timestamps are on your own timeline rather than the system
258/// clock (Default = False).
259///
260/// By default, the timestamps you pass to ulRefreshDisplayWithTimestamp() are treated as
261/// readings of the system's monotonic clock. Declare a custom clock when they're on a timeline
262/// of your own (eg, a media timeline for offline rendering, or simulation time): animation then
263/// follows your timestamps exactly.
264///
265/// @param renderer The active renderer instance.
266///
267/// @param display_id The id of the display.
268///
269/// @param uses_custom_clock True if timestamps for this display are on your own timeline.
270///
271/// @pre Call this before the display's first timed refresh.
272///
273/// @note Call this on the thread the renderer was created on.
274///
275ULExport void ulRendererSetDisplayUsesCustomClock(ULRenderer renderer, unsigned int display_id,
276 bool uses_custom_clock);
277
278///
279/// Get whether a display was declared to use a custom clock.
280///
281/// @param renderer The active renderer instance.
282///
283/// @param display_id The display ID.
284///
285/// @return Returns the value last passed to ulRendererSetDisplayUsesCustomClock() for the
286/// display, or false if it was never called.
287///
288ULExport bool ulRendererGetDisplayUsesCustomClock(ULRenderer renderer, unsigned int display_id);
289
290///
291/// Render all active Views to their respective surfaces and render targets.
292///
293/// @param renderer The active renderer instance.
294///
296
297typedef void (*ULRendererTaskCallback)(void* user_data);
298
299///
300/// Post a task to run on the Renderer's thread during a future call to ulUpdate().
301///
302/// You can use this to hand work from your other threads to the thread that drives the Renderer
303/// (the only thread that may touch Views and the DOM API).
304///
305/// Tasks run in posting order during the next ulUpdate() after they are posted. A task posted
306/// while ulUpdate() is draining tasks runs at the following ulUpdate().
307///
308/// @param renderer The active renderer instance.
309///
310/// @param task Invoked once on the Renderer's thread with `user_data`. A NULL
311/// task posts nothing; `destroy_user_data` then runs at once.
312///
313/// @param user_data Pointer passed through to `task` (can be NULL).
314///
315/// @param destroy_user_data Invoked exactly once after `task` runs, or without `task` running
316/// if the Renderer is destroyed first or `renderer` is NULL (can be
317/// NULL).
318///
319/// \parblock
320/// @note Safe to call from any thread.
321/// \endparblock
322///
323/// \parblock
324/// @note With AppCore, ulAppPostTask() posts to this same queue and also wakes the app's loop,
325/// so prefer it there.
326/// \endparblock
327///
329 ULUserDataDestroyCallback destroy_user_data);
330
331///
332/// Post a task to run on the Renderer's thread once a delay has elapsed.
333///
334/// The delay is measured against the ulUpdate() cadence rather than a background timer. The task
335/// runs during the first ulUpdate() at or after the deadline, so delivery waits while ulUpdate()
336/// is not being called (for example, a paused application). Tasks whose deadlines fall in the
337/// same ulUpdate() run in posting order.
338///
339/// @param renderer The active renderer instance.
340///
341/// @param delay_ms Minimum delay before the task may run, in milliseconds.
342///
343/// @param task Invoked once on the Renderer's thread with `user_data`.
344///
345/// @param user_data Pointer passed through to `task` (can be NULL).
346///
347/// @param destroy_user_data Invoked exactly once after `task` runs, or without `task` running
348/// if the Renderer is destroyed first or `renderer` is NULL (can be
349/// NULL).
350///
351/// @see ulRendererPostTask()
352///
353ULExport void ulRendererPostDelayedTask(ULRenderer renderer, double delay_ms,
354 ULRendererTaskCallback task, void* user_data,
355 ULUserDataDestroyCallback destroy_user_data);
356
357///
358/// Controls how aggressively ulRecycle() reclaims memory.
359///
360/// @see Renderer::RecycleMode
361///
362typedef enum {
363 ///
364 /// A quick recycle, cheap enough to call every frame (the same work the automatic recycler
365 /// does).
366 ///
368
369 ///
370 /// A thorough recycle, for idle periods or transitions (eg, a loading screen). A call within a
371 /// second of the last one does nothing.
372 ///
375
376///
377/// Recycle internal caches and memory.
378///
379/// @param renderer The active renderer instance.
380///
381/// @param mode How aggressively to reclaim memory.
382///
383/// @see Renderer::Recycle()
384///
386
387///
388/// Attempt to release as much memory as possible.
389///
390/// This also discards all compiled JavaScript code, so pages run slower for a while as it's
391/// recompiled.
392///
393/// @param renderer The active renderer instance.
394///
395/// @warning Don't call this while the renderer is rendering (eg, from a GPU driver callback):
396/// the rendering caches can't be released then, and are skipped with a warning.
397///
399
400///
401/// Print detailed memory usage statistics to the log.
402///
403/// @param renderer The active renderer instance.
404///
405/// @see ulPlatformSetLogger()
406///
408
409///
410/// Start the remote inspector server.
411///
412/// While it runs, another Ultralight app (on the same machine or over the network) can inspect
413/// this renderer's Views by loading this URL in a View:
414///
415/// \code
416/// inspector://<ADDRESS>:<PORT>
417/// \endcode
418///
419/// @param renderer The active renderer instance.
420///
421/// @param address The address for the server to listen on (eg, "127.0.0.1")
422///
423/// @param port The port for the server to listen on (eg, 9222)
424///
425/// @return Returns whether the server started successfully or not.
426///
427/// @pre Not available in the Free edition (always returns false there).
428///
429ULExport bool ulStartRemoteInspectorServer(ULRenderer renderer, const char* address,
430 unsigned short port);
431
432///
433/// Describe the details of a gamepad, to be used with ulFireGamepadEvent and related
434/// events below. This can be called multiple times with the same index if the details change.
435///
436/// @param renderer The active renderer instance.
437///
438/// @param index The gamepad's connection slot, and the array position the page sees. A
439/// gamepad described at index 1 arrives as `navigator.getGamepads()[1]`
440/// with `gamepad.index` 1, leaving slot 0 `null`. Number your controllers
441/// from 0.
442///
443/// @param id A string ID representing the device, this will be made available
444/// in JavaScript as gamepad.id
445///
446/// @param axis_count The number of axes on the device.
447///
448/// @param button_count The number of buttons on the device.
449///
450ULExport void ulSetGamepadDetails(ULRenderer renderer, unsigned int index, ULString id,
451 unsigned int axis_count, unsigned int button_count);
452
453///
454/// Fire a gamepad event (connection / disconnection).
455///
456/// @note The gamepad should first be described via ulSetGamepadDetails before calling this
457/// function.
458///
459/// @param renderer The active renderer instance.
460///
461/// @param evt The event to fire.
462///
463/// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad>
464///
466
467///
468/// Fire a gamepad axis event (to be called when an axis value is changed).
469///
470/// @note The gamepad should be connected via a previous call to ulFireGamepadEvent.
471///
472/// @param renderer The active renderer instance.
473///
474/// @param evt The event to fire.
475///
476/// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad/axes>
477///
479
480///
481/// Fire a gamepad button event (to be called when a button value is changed).
482///
483/// @note The gamepad should be connected via a previous call to ulFireGamepadEvent.
484///
485/// @param renderer The active renderer instance.
486///
487/// @param evt The event to fire.
488///
489/// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad/buttons>
490///
492
493///
494/// Render a subset of Views to their respective surfaces and render targets.
495///
496/// @param renderer The active renderer instance.
497///
498/// @param view_array A C-array of ULView handles to render.
499///
500/// @param view_array_len The number of elements in the array.
501///
502/// @deprecated Use ulRender() instead. To stop a View from painting, pause it with
503/// ulViewSetVisible() (ulRender() skips hidden Views).
504///
505ULExport UL_DEPRECATED("Use ulRender() instead.") void ulRenderOnly(ULRenderer renderer, ULView* view_array, unsigned int view_array_len);
506
507///
508/// Get formatted memory usage statistics as a string.
509///
510/// This is the same information ulLogMemoryUsage() prints, in a form you can show in a debug
511/// overlay or capture programmatically.
512///
513/// @param renderer The active renderer instance.
514///
515/// @return Returns a new ULString holding the memory usage report. You must call
516/// ulDestroyString() when finished.
517///
519
520///
521/// Set the system color scheme that Views report to pages via the `prefers-color-scheme` CSS
522/// media feature. (Default = kColorScheme_Light)
523///
524/// The library never reads the OS setting itself, so the scheme stays Light until you call this.
525///
526/// A change re-evaluates `prefers-color-scheme` media queries in every View whose preferred color
527/// scheme is kColorScheme_Auto. Views pinned to Light or Dark are unaffected.
528///
529/// @param renderer The active renderer instance.
530///
531/// @param scheme kColorScheme_Light or kColorScheme_Dark. kColorScheme_Auto or an
532/// out-of-range value logs a warning and is ignored.
533///
534/// @see ulViewSetPreferredColorScheme()
535///
537
538///
539/// Get the current system color scheme.
540///
541/// @param renderer The active renderer instance.
542///
543/// @return Returns the scheme last set with ulRendererSetSystemColorScheme(), or
544/// kColorScheme_Light if it was never called.
545///
547
548#if UL_HAS(RENDER_TRACE)
549///
550/// Begin recording a render trace to the specified file path.
551///
552/// @param renderer The active renderer instance.
553///
554/// @param path Output file path (eg, "render_trace.perfetto-trace").
555///
556/// @param verbose If true, enables verbose mode (args + events in addition to scopes).
557///
558/// @return Returns whether or not the trace started (false if a trace is already active or the
559/// trace file can't be opened).
560///
561/// @pre Requires the Enterprise edition or higher.
562///
563ULExport bool ulRendererBeginRenderTrace(ULRenderer renderer, const char* path, bool verbose);
564
565///
566/// End the current render trace.
567///
568/// The trace file is finished and closed shortly after this returns (on the next ulUpdate()).
569///
570/// @param renderer The active renderer instance.
571///
572/// @pre Requires the Enterprise edition or higher.
573///
575
576///
577/// Check if a render trace is currently being recorded.
578///
579/// @param renderer The active renderer instance.
580///
581/// @return Returns whether a render trace session is active.
582///
583/// @pre Requires the Enterprise edition or higher.
584///
586#endif // UL_HAS(RENDER_TRACE)
587
588#if UL_HAS(GC_LISTENER)
589///
590/// How much compiled JavaScript code a collection discards.
591///
592/// Compiled code keeps some JavaScript objects alive, so discarding it lets a collection free more
593/// memory. Pages then run slower for a while as their code is compiled again.
594///
595/// @see ulRendererCollectNow(), ulRecycleEx()
596///
597typedef enum {
598 ///
599 /// Keep all compiled code.
600 ///
602
603 ///
604 /// Discard compiled code but keep parsed scripts (pages recompile but don't re-parse).
605 ///
607
608 ///
609 /// Discard compiled code and parsed scripts (pages re-parse and recompile).
610 ///
613
614///
615/// A snapshot of the JavaScript heap's state.
616///
617/// @see ulRendererGetGCStatus()
618///
619typedef struct {
620 ///
621 /// How much reclaimable memory has built up, from 0 (none) to 1 (a collection is overdue).
622 ///
623 double pressure;
624
625 ///
626 /// Milliseconds since the last full collection (0 before the first one).
627 ///
629
630 ///
631 /// The JavaScript heap's in-use size in bytes (it drops when a collection frees memory).
632 ///
633 unsigned long long heap_bytes;
634} ULGCInfo;
635
636///
637/// Called when the engine wants to run a collection on your thread.
638///
639/// The Renderer collects JavaScript garbage continuously in the background on other threads, so
640/// most collection work never touches your thread. Occasionally it needs a larger collection that
641/// runs on the thread that calls ulUpdate() and pauses it while it runs.
642///
643/// Your application knows better than the engine when a pause won't be noticed (eg, a loading
644/// screen or a quiet moment in your update loop). So the engine asks first, when there's been no
645/// input for a while (see ulConfigSetIdleGCEnabled()). One idle period can bring two requests: a
646/// lighter one first, then, if the app stays idle, one that drops more compiled code. A request you
647/// don't act on isn't offered again until new input ends the idle period.
648///
649/// From the callback, call ulRendererCollectNow() with `code` to collect right away, or call it
650/// later at a moment you choose, or skip the collection. With no callback set, the engine collects
651/// right away.
652///
653/// @param user_data The pointer you passed to ulRendererSetGCRequestGCCallback().
654///
655/// @param caller The Renderer to collect on.
656///
657/// @param info The current heap state.
658///
659/// @param code How much compiled code the engine recommends discarding (pass it to
660/// ulRendererCollectNow()).
661///
662typedef void (*ULGCRequestGCCallback)(void* user_data, ULRenderer caller,
663 ULGCInfo info, ULCodeDropMode code);
664
665///
666/// Called when reclaimable memory rises past a threshold (see ULGCInfo).
667///
668/// You can use this to decide when to reclaim memory yourself (eg, with ulRendererCollectNow()).
669/// It fires again only after the pressure drops and rises again.
670///
671/// @param user_data The pointer you passed to ulRendererSetGCPressureChangedCallback().
672///
673/// @param caller The Renderer.
674///
675/// @param info The current heap state.
676///
677typedef void (*ULGCPressureChangedCallback)(void* user_data, ULRenderer caller,
678 ULGCInfo info);
679
680///
681/// Called after a collection on your thread finishes.
682///
683/// This covers the engine's own collections and the ones you start with ulRendererCollectNow(),
684/// ulRecycle(), ulRecycleEx(), or ulPurgeMemory(). It's called during the next ulUpdate().
685///
686/// @param user_data The pointer you passed to ulRendererSetGCCollectCompleteCallback().
687///
688/// @param caller The Renderer.
689///
690/// @param info The heap state when this is called.
691///
692/// @param code How much compiled code the collection was asked to discard.
693///
694/// @param duration_ms How long the collection took in milliseconds.
695///
696/// @param bytes_reclaimed How many bytes the collection freed.
697///
698typedef void (*ULGCCollectCompleteCallback)(void* user_data, ULRenderer caller,
699 ULGCInfo info, ULCodeDropMode code,
700 double duration_ms,
701 unsigned long long bytes_reclaimed);
702
703///
704/// Set the callback for when the engine wants to run a collection on your thread (see
705/// ULGCRequestGCCallback).
706///
707/// Setting a callback replaces the previous one. With no callback set, the engine collects right
708/// away.
709///
710/// @param renderer The Renderer.
711///
712/// @param callback The callback to invoke, or NULL to remove it.
713///
714/// @param user_data Pointer passed through to `callback` (can be NULL). Ownership
715/// transfers to the Renderer.
716///
717/// @param destroy_user_data Invoked exactly once on `user_data` when the callback is replaced or
718/// the Renderer is destroyed (never while the callback is running), or
719/// right away if `renderer` is NULL. Can be NULL.
720///
721/// \parblock
722/// @note All GC callbacks run during ulUpdate() on the thread that calls it.
723/// \endparblock
724///
725/// \parblock
726/// @note Each setter owns its `user_data` separately, so pass a shared context with a NULL
727/// `destroy_user_data` to all but one setter.
728/// \endparblock
729///
730/// @warning Don't remove a GC callback from inside a GC callback.
731///
732/// @pre Requires the Pro edition or higher.
733///
735 ULGCRequestGCCallback callback, void* user_data,
736 ULUserDataDestroyCallback destroy_user_data);
737
738///
739/// Set the callback for when reclaimable memory rises past a threshold (see
740/// ULGCPressureChangedCallback).
741///
742/// @param renderer The Renderer.
743///
744/// @param callback The callback to invoke, or NULL to remove it.
745///
746/// @param user_data Pointer passed through to `callback` (can be NULL). Ownership
747/// transfers to the Renderer.
748///
749/// @param destroy_user_data Invoked exactly once on `user_data` when the callback is replaced or
750/// the Renderer is destroyed, or right away if `renderer` is NULL. Can
751/// be NULL.
752///
753/// @pre Requires the Pro edition or higher.
754///
755/// @see ulRendererSetGCRequestGCCallback()
756///
759 void* user_data,
760 ULUserDataDestroyCallback destroy_user_data);
761
762///
763/// Set the callback for when a collection on your thread finishes (see
764/// ULGCCollectCompleteCallback).
765///
766/// @param renderer The Renderer.
767///
768/// @param callback The callback to invoke, or NULL to remove it.
769///
770/// @param user_data Pointer passed through to `callback` (can be NULL). Ownership
771/// transfers to the Renderer.
772///
773/// @param destroy_user_data Invoked exactly once on `user_data` when the callback is replaced or
774/// the Renderer is destroyed, or right away if `renderer` is NULL. Can
775/// be NULL.
776///
777/// @pre Requires the Pro edition or higher.
778///
779/// @see ulRendererSetGCRequestGCCallback()
780///
783 void* user_data,
784 ULUserDataDestroyCallback destroy_user_data);
785
786///
787/// Get a snapshot of the JavaScript heap's state.
788///
789/// @param renderer The Renderer.
790///
791/// @return Returns the current heap state (see ULGCInfo).
792///
793/// @pre Requires the Pro edition or higher.
794///
796
797///
798/// Reclaim memory, choosing how much compiled code to discard.
799///
800/// This works like ulRecycle(). With kRecycleMode_Full, `code` sets how much compiled code the
801/// collection discards (it has no effect with kRecycleMode_Lightweight).
802///
803/// @param renderer The Renderer.
804///
805/// @param mode How aggressively to reclaim memory.
806///
807/// @param code How much compiled code to discard.
808///
809/// @pre Requires the Pro edition or higher.
810///
811/// @see ulRecycle()
812///
814
815///
816/// Collect the JavaScript heap now, leaving rendering and GPU caches intact.
817///
818/// Unlike ulRecycle(), this reclaims only the JavaScript heap, so rendering stays fast. You can
819/// call it from your ULGCRequestGCCallback or at any moment when a short pause won't be noticed.
820///
821/// @param renderer The Renderer.
822///
823/// @param code How much compiled code to discard.
824///
825/// @param sync If true, collect before returning. If false, collect in the background.
826///
827/// \parblock
828/// @note If you call this while JavaScript is running (eg, from a JS callback), the collection
829/// waits until the script returns, even with `sync` set to true.
830/// \endparblock
831///
832/// \parblock
833/// @note The collect-complete callback fires only for a synchronous collection.
834/// \endparblock
835///
836/// @pre Requires the Pro edition or higher.
837///
839#endif // UL_HAS(GC_LISTENER)
840
841#ifdef __cplusplus
842} // extern "C"
843#endif
844
845#endif // ULTRALIGHT_CAPI_RENDERER_H
void(*) ULGCRequestGCCallback(void *user_data, ULRenderer caller, ULGCInfo info, ULCodeDropMode code)
Called when the engine wants to run a collection on your thread.
Definition CAPI_Renderer.h:662
ULRecycleMode
Controls how aggressively ulRecycle() reclaims memory.
Definition CAPI_Renderer.h:362
@ kRecycleMode_Lightweight
A quick recycle, cheap enough to call every frame (the same work the automatic recycler does).
Definition CAPI_Renderer.h:367
@ kRecycleMode_Full
A thorough recycle, for idle periods or transitions (eg, a loading screen).
Definition CAPI_Renderer.h:373
void ulRefreshDisplayWithTimestamp(ULRenderer renderer, unsigned int display_id, double target_timestamp)
Notify the renderer that a display has refreshed, and when the resulting frame will be shown.
void ulRenderOnly(ULRenderer renderer, ULView *view_array, unsigned int view_array_len)
Render a subset of Views to their respective surfaces and render targets.
ULColorScheme ulRendererGetSystemColorScheme(ULRenderer renderer)
Get the current system color scheme.
void(*) ULGCPressureChangedCallback(void *user_data, ULRenderer caller, ULGCInfo info)
Called when reclaimable memory rises past a threshold (see ULGCInfo).
Definition CAPI_Renderer.h:677
void ulUpdate(ULRenderer renderer)
Update timers and dispatch internal callbacks (JavaScript and network).
bool ulRendererIsRenderTraceActive(ULRenderer renderer)
Check if a render trace is currently being recorded.
ULCodeDropMode
How much compiled JavaScript code a collection discards.
Definition CAPI_Renderer.h:597
@ kCodeDropMode_Linked
Discard compiled code but keep parsed scripts (pages recompile but don't re-parse).
Definition CAPI_Renderer.h:606
@ kCodeDropMode_Nothing
Keep all compiled code.
Definition CAPI_Renderer.h:601
@ kCodeDropMode_All
Discard compiled code and parsed scripts (pages re-parse and recompile).
Definition CAPI_Renderer.h:611
ULRenderer ulCreateRenderer(ULConfig config)
Create the core renderer singleton for the library.
ULString ulGetMemoryUsage(ULRenderer renderer)
Get formatted memory usage statistics as a string.
void ulRendererSetSystemColorScheme(ULRenderer renderer, ULColorScheme scheme)
Set the system color scheme that Views report to pages via the prefers-color-scheme CSS media feature...
bool ulRendererBeginRenderTrace(ULRenderer renderer, const char *path, bool verbose)
Begin recording a render trace to the specified file path.
void ulRendererSetGCPressureChangedCallback(ULRenderer renderer, ULGCPressureChangedCallback callback, void *user_data, ULUserDataDestroyCallback destroy_user_data)
Set the callback for when reclaimable memory rises past a threshold (see ULGCPressureChangedCallback)...
void(*) ULGCCollectCompleteCallback(void *user_data, ULRenderer caller, ULGCInfo info, ULCodeDropMode code, double duration_ms, unsigned long long bytes_reclaimed)
Called after a collection on your thread finishes.
Definition CAPI_Renderer.h:698
void ulFireGamepadAxisEvent(ULRenderer renderer, ULGamepadAxisEvent evt)
Fire a gamepad axis event (to be called when an axis value is changed).
void ulRendererPostTask(ULRenderer renderer, ULRendererTaskCallback task, void *user_data, ULUserDataDestroyCallback destroy_user_data)
Post a task to run on the Renderer's thread during a future call to ulUpdate().
void ulRefreshDisplay(ULRenderer renderer, unsigned int display_id)
Notify the renderer that a display has refreshed.
void ulRendererSetDisplayRefreshRate(ULRenderer renderer, unsigned int display_id, double refresh_rate)
Declare a display's refresh rate.
void ulRecycleEx(ULRenderer renderer, ULRecycleMode mode, ULCodeDropMode code)
Reclaim memory, choosing how much compiled code to discard.
void ulRendererPostDelayedTask(ULRenderer renderer, double delay_ms, ULRendererTaskCallback task, void *user_data, ULUserDataDestroyCallback destroy_user_data)
Post a task to run on the Renderer's thread once a delay has elapsed.
void ulRendererCollectNow(ULRenderer renderer, ULCodeDropMode code, bool sync)
Collect the JavaScript heap now, leaving rendering and GPU caches intact.
void ulRecycle(ULRenderer renderer, ULRecycleMode mode)
Recycle internal caches and memory.
bool ulStartRemoteInspectorServer(ULRenderer renderer, const char *address, unsigned short port)
Start the remote inspector server.
void ulPurgeMemory(ULRenderer renderer)
Attempt to release as much memory as possible.
void ulDestroyRenderer(ULRenderer renderer)
Destroy a renderer previously created with ulCreateRenderer().
bool ulRendererGetDisplayUsesCustomClock(ULRenderer renderer, unsigned int display_id)
Get whether a display was declared to use a custom clock.
void ulSetGamepadDetails(ULRenderer renderer, unsigned int index, ULString id, unsigned int axis_count, unsigned int button_count)
Describe the details of a gamepad, to be used with ulFireGamepadEvent and related events below.
void ulLogMemoryUsage(ULRenderer renderer)
Print detailed memory usage statistics to the log.
void ulRendererSetGCCollectCompleteCallback(ULRenderer renderer, ULGCCollectCompleteCallback callback, void *user_data, ULUserDataDestroyCallback destroy_user_data)
Set the callback for when a collection on your thread finishes (see ULGCCollectCompleteCallback).
void(*) ULRendererTaskCallback(void *user_data)
Definition CAPI_Renderer.h:297
double ulRendererGetDisplayRefreshRate(ULRenderer renderer, unsigned int display_id)
Get the refresh rate declared for a display.
void ulFireGamepadButtonEvent(ULRenderer renderer, ULGamepadButtonEvent evt)
Fire a gamepad button event (to be called when a button value is changed).
void ulRender(ULRenderer renderer)
Render all active Views to their respective surfaces and render targets.
void ulRendererEndRenderTrace(ULRenderer renderer)
End the current render trace.
ULGCInfo ulRendererGetGCStatus(ULRenderer renderer)
Get a snapshot of the JavaScript heap's state.
void ulRendererSetDisplayUsesCustomClock(ULRenderer renderer, unsigned int display_id, bool uses_custom_clock)
Declare that a display's refresh timestamps are on your own timeline rather than the system clock (De...
void ulRendererSetGCRequestGCCallback(ULRenderer renderer, ULGCRequestGCCallback callback, void *user_data, ULUserDataDestroyCallback destroy_user_data)
Set the callback for when the engine wants to run a collection on your thread (see ULGCRequestGCCallb...
void ulFireGamepadEvent(ULRenderer renderer, ULGamepadEvent evt)
Fire a gamepad event (connection / disconnection).
Various defines and utility functions for the C API.
#define UL_DEPRECATED(msg)
Marks a C API function as deprecated; calls to it produce a compiler warning with msg.
Definition CAPI_Defines.h:52
struct C_GamepadButtonEvent * ULGamepadButtonEvent
Opaque handle to a GamepadButtonEvent object.
Definition CAPI_Defines.h:119
struct C_View * ULView
Opaque handle to a View object.
Definition CAPI_Defines.h:87
struct C_String * ULString
Opaque handle to a String object.
Definition CAPI_Defines.h:96
struct C_Config * ULConfig
Opaque handle to a Config object.
Definition CAPI_Defines.h:75
#define ULExport
Definition CAPI_Defines.h:42
struct C_GamepadAxisEvent * ULGamepadAxisEvent
Opaque handle to a GamepadAxisEvent object.
Definition CAPI_Defines.h:116
void(*) ULUserDataDestroyCallback(void *user_data)
Callback invoked exactly once when the library finally drops a piece of user data.
Definition CAPI_Defines.h:139
ULColorScheme
A page color scheme, as reported to pages via the prefers-color-scheme CSS media feature.
Definition CAPI_Defines.h:147
struct C_Renderer * ULRenderer
Opaque handle to a Renderer object.
Definition CAPI_Defines.h:78
struct C_GamepadEvent * ULGamepadEvent
Opaque handle to a GamepadEvent object.
Definition CAPI_Defines.h:113
A snapshot of the JavaScript heap's state.
Definition CAPI_Renderer.h:619
unsigned long long heap_bytes
The JavaScript heap's in-use size in bytes (it drops when a collection frees memory).
Definition CAPI_Renderer.h:633
double time_since_last_collect_ms
Milliseconds since the last full collection (0 before the first one).
Definition CAPI_Renderer.h:628
double pressure
How much reclaimable memory has built up, from 0 (none) to 1 (a collection is overdue).
Definition CAPI_Renderer.h:623