Loading...
Searching...
No Matches
Surface.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/Bitmap.h>
12#include <Ultralight/Geometry.h>
13
14namespace ultralight {
15
16///
17/// User-defined pixel buffer surface.
18///
19/// The library uses this to store pixel data when rendering Views on the CPU (see
20/// ViewConfig::is_accelerated).
21///
22/// You can provide the library with your own Surface implementation to reduce the latency of
23/// displaying pixels in your application (Views will be drawn directly to a block of memory
24/// controlled by you).
25///
26/// When a View is rendered on the CPU, you can retrieve the backing Surface via View::surface().
27///
28/// @pre This is automatically managed for you when using App::Create(), if you want to override
29/// Surface or SurfaceFactory, you'll need to use Renderer::Create() instead.
30///
31/// ## Default Implementation
32///
33/// A default Surface implementation, BitmapSurface, is automatically provided by the library when
34/// you call Renderer::Create() without defining a custom SurfaceFactory.
35///
36/// You should cast the Surface to a BitmapSurface to access the underlying Bitmap.
37///
38/// ## Setting the Surface Implementation
39///
40/// To define your own implementation, you should inherit from this class, handle the virtual
41/// member functions, and then define a custom SurfaceFactory that creates/destroys an
42/// instance of your class.
43///
44/// After that, you should pass an instance of your custom SurfaceFactory class to
45/// Platform::set_surface_factory() before calling Renderer::Create().
46///
48 public:
49 virtual ~Surface();
50
51 ///
52 /// Width (in pixels).
53 ///
54 virtual uint32_t width() const = 0;
55
56 ///
57 /// Height (in pixels).
58 ///
59 virtual uint32_t height() const = 0;
60
61 ///
62 /// Number of bytes between rows (usually width * 4)
63 ///
64 virtual uint32_t row_bytes() const = 0;
65
66 ///
67 /// Size in bytes.
68 ///
69 virtual size_t size() const = 0;
70
71 ///
72 /// Lock the pixel buffer and get a pointer to the beginning of the data for reading/writing.
73 ///
74 /// @note Native pixel format is premultiplied BGRA 32-bit (8 bits per channel).
75 ///
76 virtual void* LockPixels() = 0;
77
78 ///
79 /// Unlock the pixel buffer.
80 ///
81 virtual void UnlockPixels() = 0;
82
83 ///
84 /// Resize the pixel buffer to a certain width and height (both in pixels).
85 ///
86 /// This should never be called while pixels are locked.
87 ///
88 virtual void Resize(uint32_t width, uint32_t height) = 0;
89
90 ///
91 /// Set the dirty bounds to a certain value.
92 ///
93 /// This is called after the Renderer paints to an area of the pixel buffer. (The new value will
94 /// be joined with the existing dirty_bounds())
95 ///
96 virtual void set_dirty_bounds(const IntRect& bounds);
97
98 ///
99 /// Get the dirty bounds.
100 ///
101 /// This value can be used to determine which portion of the pixel buffer has been updated since
102 /// the last call to ClearDirtyBounds().
103 ///
104 /// The general algorithm to determine if a Surface needs display is:
105 /// <pre>
106 /// if (!surface.dirty_bounds().IsEmpty()) {
107 /// // Surface pixels are dirty and needs display.
108 /// // Cast Surface to native Surface and use it here (pseudo code)
109 /// DisplaySurface(surface);
110 ///
111 /// // Once you're done, clear the dirty bounds:
112 /// surface.ClearDirtyBounds();
113 /// }
114 /// </pre>
115 ///
116 virtual IntRect dirty_bounds() const;
117
118 ///
119 /// Clear the dirty bounds.
120 ///
121 /// You should call this after you're done displaying the Surface.
122 ///
123 virtual void ClearDirtyBounds();
124
125 protected:
127
129};
130
131///
132/// User-defined factory to provide your own surface implementation.
133///
134/// The library uses this to create/destroy Surface instances when rendering Views on the CPU.
135///
136/// @pre This is automatically managed for you when using App::Create(), if you want to override
137/// Surface or SurfaceFactory, you'll need to use Renderer::Create() instead.
138///
139/// ## Setting the Surface Factory
140///
141/// The default factory creates/destroys a BitmapSurface but you can override this by providing your
142/// own factory to Platform::set_surface_factory().
143///
145 public:
147
148 ///
149 /// Create a native Surface with a certain width and height (in pixels).
150 ///
151 virtual Surface* CreateSurface(uint32_t width, uint32_t height) = 0;
152
153 ///
154 /// Destroy a native Surface previously created by CreateSurface().
155 ///
156 virtual void DestroySurface(Surface* surface) = 0;
157};
158
159///
160/// The default surface implementation, backed by a bitmap.
161///
162/// This is automatically provided by the library when you call Renderer::Create() without defining
163/// a custom SurfaceFactory.
164///
165/// This implementation uses a Bitmap to store pixel data (retrieve it via BitmapSurface::bitmap()).
166///
168 public:
169 virtual uint32_t width() const override;
170
171 virtual uint32_t height() const override;
172
173 virtual uint32_t row_bytes() const override;
174
175 virtual size_t size() const override;
176
177 virtual void* LockPixels() override;
178
179 virtual void UnlockPixels() override;
180
181 virtual void Resize(uint32_t width, uint32_t height) override;
182
183 ///
184 /// Get the underlying Bitmap.
185 ///
187
188 protected:
189 BitmapSurface(uint32_t width, uint32_t height);
190 virtual ~BitmapSurface();
191 BitmapSurface(const BitmapSurface&) = delete;
192 void operator=(const BitmapSurface&) = delete;
193 friend class BitmapSurfaceFactory;
194
195 void* impl_;
196};
197
198///
199/// Get the default Bitmap Surface Factory singleton. (Do not destroy this, this singleton is owned
200/// by the library).
201///
203
204} // namespace ultralight
#define UExport
Definition Exports.h:25
The default surface implementation, backed by a bitmap.
Definition Surface.h:167
virtual void * LockPixels() override
Lock the pixel buffer and get a pointer to the beginning of the data for reading/writing.
virtual uint32_t width() const override
Width (in pixels).
virtual uint32_t row_bytes() const override
Number of bytes between rows (usually width * 4)
BitmapSurface(uint32_t width, uint32_t height)
virtual void Resize(uint32_t width, uint32_t height) override
Resize the pixel buffer to a certain width and height (both in pixels).
virtual size_t size() const override
Size in bytes.
virtual uint32_t height() const override
Height (in pixels).
BitmapSurface(const BitmapSurface &)=delete
RefPtr< Bitmap > bitmap()
Get the underlying Bitmap.
void * impl_
Definition Surface.h:195
virtual void UnlockPixels() override
Unlock the pixel buffer.
void operator=(const BitmapSurface &)=delete
A nullable smart pointer.
Definition RefPtr.h:79
User-defined factory to provide your own surface implementation.
Definition Surface.h:144
virtual Surface * CreateSurface(uint32_t width, uint32_t height)=0
Create a native Surface with a certain width and height (in pixels).
virtual void DestroySurface(Surface *surface)=0
Destroy a native Surface previously created by CreateSurface().
User-defined pixel buffer surface.
Definition Surface.h:47
virtual void ClearDirtyBounds()
Clear the dirty bounds.
virtual uint32_t height() const =0
Height (in pixels).
virtual void Resize(uint32_t width, uint32_t height)=0
Resize the pixel buffer to a certain width and height (both in pixels).
virtual uint32_t row_bytes() const =0
Number of bytes between rows (usually width * 4)
virtual uint32_t width() const =0
Width (in pixels).
virtual void * LockPixels()=0
Lock the pixel buffer and get a pointer to the beginning of the data for reading/writing.
virtual void UnlockPixels()=0
Unlock the pixel buffer.
IntRect dirty_bounds_
Definition Surface.h:128
virtual size_t size() const =0
Size in bytes.
virtual void set_dirty_bounds(const IntRect &bounds)
Set the dirty bounds to a certain value.
virtual IntRect dirty_bounds() const
Get the dirty bounds.
Definition App.h:14
SurfaceFactory * GetBitmapSurfaceFactory()
Get the default Bitmap Surface Factory singleton.
Integer Rectangle Helper.
Definition Geometry.h:529