Loading...
Searching...
No Matches
Renderer.h
Go to the documentation of this file.
1/**************************************************************************************************
2 * This file is a part of Ultralight. *
3 * *
4 * See <https://ultralig.ht> for licensing and more. *
5 * *
6 * (C) 2024 Ultralight, Inc. *
7 **************************************************************************************************/
8#pragma once
10#include <Ultralight/RefPtr.h>
11#include <Ultralight/Session.h>
12#include <Ultralight/View.h>
14
15namespace ultralight {
16
17///
18/// Core renderer singleton for the library, coordinates all library functions.
19///
20/// The Renderer class is responsible for creating and painting View%s, managing Session%s, as well
21/// as coordinating network requests, events, JavaScript execution, and more.
22///
23/// ## Creating the Renderer
24///
25/// @note A Renderer will be created for you automatically when you call App::Create() (access it
26/// via App::renderer).
27///
28/// @note App::Create() is part of the AppCore API and automatically manages window creation, run
29/// loop, input, painting, and most platform-specific functionality. (Available on desktop
30/// platforms only)
31/// \endparblock
32///
33/// ### Defining Platform Handlers
34///
35/// Before creating the Renderer, you should define your platform handlers via the Platform
36/// singleton. This can be used to customize file loading, font loading, clipboard access, and other
37/// functionality typically provided by the OS.
38///
39/// Default implementations for most platform handlers are available in the
40/// [AppCore repo](https://github.com/ultralight-ux/AppCore/tree/master/src). You can use these
41/// stock implementations by copying the code into your project, or you can write your own.
42///
43/// At a minimum, you should provide a FileSystem and FontLoader otherwise Renderer creation will
44/// fail.
45///
46/// ### Setting Up the Config
47///
48/// You can configure various library options by creating a Config object and passing it to
49/// `Platform::instance().set_config()`.
50///
51/// ### Creating the Renderer
52///
53/// Once you've set up the Platform handlers and Config, you can create the Renderer by calling
54/// `Renderer::Create()`. You should store the result in a RefPtr to keep it alive.
55///
56/// @par Example creation code
57/// ```
58/// // Get the Platform singleton (maintains global library state)
59/// auto& platform = Platform::instance();
60///
61/// // Setup config
62/// Config my_config;
63/// platform.set_config(my_config);
64///
65/// // Create platform handlers (these are the minimum required)
66/// // (This is pseudo-code, you will need to define your own)
67/// MyFileSystem* file_system = new MyFileSystem();
68/// MyFontLoader* font_loader = new MyFontLoader();
69///
70/// // Setup platform handlers
71/// platform.set_file_system(file_system);
72/// platform.set_font_loader(font_loader);
73///
74/// // Create the Renderer
75/// RefPtr<Renderer> renderer = Renderer::Create();
76///
77/// // Create Views here
78/// ```
79///
80/// ## Updating Renderer Logic
81///
82/// You should call Renderer::Update() from your main update loop as often as possible to give the
83/// library an opportunity to dispatch events and timers:
84///
85/// @par Example update code
86/// ```
87/// void mainLoop()
88/// {
89/// while(true)
90/// {
91/// // Update program logic here
92/// renderer.Update();
93/// }
94/// }
95/// ```
96///
97/// ## Rendering Each Frame
98///
99/// When your program is ready to display a new frame (usually in synchrony with the monitor
100/// refresh rate), you should call `Renderer::RefreshDisplay()` and `Renderer::Render()` so the
101/// library can render all active View%s as needed.
102///
103/// @par Example per-frame render code
104/// ```
105/// void displayFrame()
106/// {
107/// // Notify the renderer that the main display has refreshed. This will update animations,
108/// // smooth scroll, and window.requestAnimationFrame() for all Views matching the display id.
109/// renderer.RefreshDisplay(0);
110///
111/// // Render all Views as needed
112/// renderer.Render();
113///
114/// // Each View will render to a
115/// // - Pixel-Buffer Surface (View::surface())
116/// // or
117/// // - GPU texture (View::render_target())
118/// // based on whether CPU or GPU rendering is used.
119/// //
120/// // You will need to display the image data here as needed.
121/// }
122/// }
123/// ```
124///
126 public:
127 ///
128 /// Create the core renderer singleton for the library.
129 ///
130 /// You should set up the Platform singleton before calling this function.
131 ///
132 /// @note You do not need to the call this if you're using the App class from AppCore.
133 ///
134 /// \parblock
135 /// @warning You'll need to define a FontLoader and FileSystem within the Platform singleton
136 /// or else this call will fail.
137 /// \endparblock
138 ///
139 /// \parblock
140 /// @warning You should only create one Renderer during the lifetime of your program.
141 /// \endparblock
142 ///
143 /// @return Renderer is ref-counted. This method returns a ref-pointer to a new instance, you
144 /// should store it in a RefPtr to keep the instance alive.
145 ///
147
148 ///
149 /// Create a unique, named Session to store browsing data in (cookies, local storage,
150 /// application cache, indexed db, etc).
151 ///
152 /// @note A default, persistent Session is already created for you. You only need to call this
153 /// if you want to create private, in-memory session or use a separate session for each
154 /// View.
155 ///
156 /// @param is_persistent Whether or not to store the session on disk. Persistent sessions will
157 /// be written to the path set in Config::cache_path
158 ///
159 /// @param name A unique name for this session, this will be used to generate a unique disk
160 /// path for persistent sessions.
161 ///
162 virtual RefPtr<Session> CreateSession(bool is_persistent, const String& name) = 0;
163
164 ///
165 /// Get the default Session. This session is persistent (backed to disk) and has the name
166 /// "default".
167 ///
169
170 ///
171 /// Create a new View to load and display web pages in.
172 ///
173 /// Views are similar to a tab in a browser. They have certain dimensions but are rendered to an
174 /// offscreen surface and must be forwarded all input events.
175 ///
176 /// @param width The initial width, in pixels.
177 ///
178 /// @param height The initial height, in pixels.
179 ///
180 /// @param config Configuration details for the View.
181 ///
182 /// @param session The session to store local data in. Pass a nullptr to use the default
183 /// session.
184 ///
185 /// @return Returns a ref-pointer to a new View instance.
186 ///
187 virtual RefPtr<View> CreateView(uint32_t width, uint32_t height, const ViewConfig& config,
188 RefPtr<Session> session)
189 = 0;
190
191 ///
192 /// Update timers and dispatch callbacks.
193 ///
194 /// You should call this as often as you can from your application's run loop.
195 ///
196 virtual void Update() = 0;
197
198 ///
199 /// Notify the renderer that a display has refreshed (you should call this after vsync).
200 ///
201 /// This updates animations, smooth scroll, and window.requestAnimationFrame() for all Views
202 /// matching the display id.
203 ///
204 virtual void RefreshDisplay(uint32_t display_id) = 0;
205
206 ///
207 /// Render all active views to their respective render-targets/surfaces.
208 ///
209 /// @note Views are only repainted if they actually need painting.
210 ///
211 virtual void Render() = 0;
212
213 ///
214 /// Render a subset of views to their respective surfaces and render targets.
215 ///
216 /// @param view_array A C-array containing a list of View pointers.
217 ///
218 /// @param view_array_len The length of the C-array.
219 ///
220 virtual void RenderOnly(View** view_array, size_t view_array_len) = 0;
221
222 ///
223 /// Attempt to release as much memory as possible.
224 ///
225 /// @warning Don't call this from any callbacks or driver code.
226 ///
227 virtual void PurgeMemory() = 0;
228
229 ///
230 /// Print detailed memory usage statistics to the log.
231 ///
232 /// @see Platform::set_logger
233 ///
234 virtual void LogMemoryUsage() = 0;
235
236 ///
237 /// Start the remote inspector server.
238 ///
239 /// While the remote inspector is active, Views that are loaded into this renderer
240 /// will be able to be remotely inspected from another Ultralight instance either locally
241 /// (another app on same machine) or remotely (over the network) by navigating a View to:
242 ///
243 /// \code
244 /// inspector://<ADDRESS>:<PORT>
245 /// \endcode
246 ///
247 /// @param address The address for the server to listen on (eg, "127.0.0.1")
248 ///
249 /// @param port The port for the server to listen on (eg, 9222)
250 ///
251 /// @return Returns whether the server started successfully or not.
252 ///
253 virtual bool StartRemoteInspectorServer(const char* address, uint16_t port) = 0;
254
255 ///
256 /// Describe the details of a gamepad, to be used with FireGamepadEvent and related
257 /// events below. This can be called multiple times with the same index if the details change.
258 ///
259 /// @param index The unique index (or "connection slot") of the gamepad. For example,
260 /// controller #1 would be "1", controller #2 would be "2" and so on.
261 ///
262 /// @param id A string ID representing the device, this will be made available
263 /// in JavaScript as gamepad.id
264 ///
265 /// @param axis_count The number of axes on the device.
266 ///
267 /// @param button_count The number of buttons on the device.
268 ///
269 virtual void SetGamepadDetails(uint32_t index, const String& id, uint32_t axis_count,
270 uint32_t button_count)
271 = 0;
272
273 ///
274 /// Fire a gamepad event (connection / disconnection).
275 ///
276 /// @note The gamepad should first be described via SetGamepadDetails before calling this
277 /// function.
278 ///
279 /// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad>
280 ///
281 virtual void FireGamepadEvent(const GamepadEvent& evt) = 0;
282
283 ///
284 /// Fire a gamepad axis event (to be called when an axis value is changed).
285 ///
286 /// @note The gamepad should be connected via a previous call to FireGamepadEvent.
287 ///
288 /// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad/axes>
289 ///
290 virtual void FireGamepadAxisEvent(const GamepadAxisEvent& evt) = 0;
291
292 ///
293 /// Fire a gamepad button event (to be called when a button value is changed).
294 ///
295 /// @note The gamepad should be connected via a previous call to FireGamepadEvent.
296 ///
297 /// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad/buttons>
298 ///
299 virtual void FireGamepadButtonEvent(const GamepadButtonEvent& evt) = 0;
300
301 protected:
302 virtual ~Renderer();
303};
304
305} // namespace ultralight
#define UExport
Definition Exports.h:25
Event representing a change in gamepad axis state (eg, pressing a stick in a certain direction).
Definition GamepadEvent.h:57
Event representing a change in gamepad button state (eg, pressing a button on a gamepad).
Definition GamepadEvent.h:85
Event representing a change in gamepad connection state.
Definition GamepadEvent.h:19
Interface for all ref-counted objects that will be managed using the RefPtr<> smart pointer.
Definition RefPtr.h:47
A nullable smart pointer.
Definition RefPtr.h:79
Core renderer singleton for the library, coordinates all library functions.
Definition Renderer.h:125
virtual void FireGamepadAxisEvent(const GamepadAxisEvent &evt)=0
Fire a gamepad axis event (to be called when an axis value is changed).
virtual void FireGamepadEvent(const GamepadEvent &evt)=0
Fire a gamepad event (connection / disconnection).
virtual RefPtr< Session > default_session()=0
Get the default Session.
virtual void Update()=0
Update timers and dispatch callbacks.
virtual void RenderOnly(View **view_array, size_t view_array_len)=0
Render a subset of views to their respective surfaces and render targets.
virtual void SetGamepadDetails(uint32_t index, const String &id, uint32_t axis_count, uint32_t button_count)=0
Describe the details of a gamepad, to be used with FireGamepadEvent and related events below.
virtual bool StartRemoteInspectorServer(const char *address, uint16_t port)=0
Start the remote inspector server.
virtual RefPtr< View > CreateView(uint32_t width, uint32_t height, const ViewConfig &config, RefPtr< Session > session)=0
Create a new View to load and display web pages in.
virtual void RefreshDisplay(uint32_t display_id)=0
Notify the renderer that a display has refreshed (you should call this after vsync).
virtual RefPtr< Session > CreateSession(bool is_persistent, const String &name)=0
Create a unique, named Session to store browsing data in (cookies, local storage, application cache,...
virtual void PurgeMemory()=0
Attempt to release as much memory as possible.
virtual void Render()=0
Render all active views to their respective render-targets/surfaces.
virtual void LogMemoryUsage()=0
Print detailed memory usage statistics to the log.
virtual void FireGamepadButtonEvent(const GamepadButtonEvent &evt)=0
Fire a gamepad button event (to be called when a button value is changed).
static RefPtr< Renderer > Create()
Create the core renderer singleton for the library.
Unicode string container with conversions for UTF-8, UTF-16, and UTF-32.
Definition String.h:34
Web-page container rendered to an offscreen surface.
Definition View.h:202
Definition App.h:14
View-specific configuration settings.
Definition View.h:28