1 | /*! |
2 | * \file image.hpp |
3 | * \brief file image.hpp |
4 | * |
5 | * Copyright 2016 by Intel. |
6 | * |
7 | * Contact: kevin.rogovin@gmail.com |
8 | * |
9 | * This Source Code Form is subject to the |
10 | * terms of the Mozilla Public License, v. 2.0. |
11 | * If a copy of the MPL was not distributed with |
12 | * this file, You can obtain one at |
13 | * http://mozilla.org/MPL/2.0/. |
14 | * |
15 | * \author Kevin Rogovin <kevin.rogovin@gmail.com> |
16 | * |
17 | */ |
18 | |
19 | #ifndef FASTUIDRAW_IMAGE_HPP |
20 | #define FASTUIDRAW_IMAGE_HPP |
21 | |
22 | #include <fastuidraw/util/reference_counted.hpp> |
23 | #include <fastuidraw/util/util.hpp> |
24 | #include <fastuidraw/util/vecN.hpp> |
25 | #include <fastuidraw/util/c_array.hpp> |
26 | |
27 | namespace fastuidraw |
28 | { |
29 | |
30 | ///@cond |
31 | class ImageSourceBase; |
32 | class ImageAtlas; |
33 | ///@endcond |
34 | |
35 | /*!\addtogroup Imaging |
36 | * @{ |
37 | */ |
38 | |
39 | /*! |
40 | * \brief |
41 | * An Image represents an image comprising of RGBA8 values. |
42 | * The texel values themselves are stored in a ImageAtlas. |
43 | */ |
44 | class Image:public resource_base |
45 | { |
46 | public: |
47 | /*! |
48 | * Enumeration to describe the format of an image |
49 | */ |
50 | enum format_t |
51 | { |
52 | /*! |
53 | * Image is non-premultiplied RGBA format (each |
54 | * color channel of each pixel taking 8-bits). |
55 | */ |
56 | rgba_format, |
57 | |
58 | /*! |
59 | * Image is RGBA format (each color channel of |
60 | * each pixel taking 8-bits) with the RGB channels |
61 | * pre-multiplied by the alpha channel. |
62 | */ |
63 | premultipied_rgba_format, |
64 | }; |
65 | |
66 | /*! |
67 | * Gives the image-type of an Image |
68 | */ |
69 | enum type_t |
70 | { |
71 | /*! |
72 | * Indicates that the Image is on an ImageAtlas. |
73 | * Such images will not introcude draw-breaks, but |
74 | * are more complicated to sample from. |
75 | */ |
76 | on_atlas, |
77 | |
78 | /*! |
79 | * Indicates that the Image is backed by a gfx API |
80 | * texture via a bindless interface. Such images |
81 | * do not introduce draw-breaks and are simple |
82 | * from. The only draw back, is that not all 3D |
83 | * API implementations support bindless texruing |
84 | * (for example the GL/GLES backends require that |
85 | * the GL/GLES implementation support an extension. |
86 | */ |
87 | bindless_texture2d, |
88 | |
89 | /*! |
90 | * Indicates to source the Image data from a currently |
91 | * bound texture of the 3D API context. These image are |
92 | * simple to sample from but introduce draw breaks. Using |
93 | * images of these types should be avoided at all costs |
94 | * since whenever one uses Image objects of these types |
95 | * the 3D API state needs to change which induces a stage |
96 | * change and draw break, harming performance. |
97 | */ |
98 | context_texture2d, |
99 | }; |
100 | |
101 | /*! |
102 | * Class representing an action to execute when a bindless |
103 | * image is deleted. The action is guaranteed to be executed |
104 | * AFTER the 3D API is no longer using the resources that |
105 | * back the image. |
106 | */ |
107 | class ResourceReleaseAction: |
108 | public reference_counted<ResourceReleaseAction>::concurrent |
109 | { |
110 | public: |
111 | virtual |
112 | ~ResourceReleaseAction() |
113 | {} |
114 | |
115 | /*! |
116 | * To be implemented by a derived class to perform resource |
117 | * release actions. |
118 | */ |
119 | virtual |
120 | void |
121 | action(void) = 0; |
122 | }; |
123 | |
124 | virtual |
125 | ~Image(); |
126 | |
127 | /*! |
128 | * Returns the number of index look-ups to get to the image data. |
129 | * |
130 | * Only applies when type() returns \ref on_atlas. |
131 | */ |
132 | unsigned int |
133 | number_index_lookups(void) const; |
134 | |
135 | /*! |
136 | * Returns the dimensions of the image, i.e the width and height. |
137 | */ |
138 | ivec2 |
139 | dimensions(void) const; |
140 | |
141 | /*! |
142 | * Returns the number of mipmap levels the image supports. |
143 | */ |
144 | unsigned int |
145 | number_mipmap_levels(void) const; |
146 | |
147 | /*! |
148 | * Returns the "head" index tile as returned by |
149 | * ImageAtlas::add_index_tile() or |
150 | * ImageAtlas::add_index_tile_index_data(). |
151 | * |
152 | * Only applies when type() returns \ref on_atlas. |
153 | */ |
154 | ivec3 |
155 | master_index_tile(void) const; |
156 | |
157 | /*! |
158 | * If number_index_lookups() > 0, returns the number of texels in |
159 | * each dimension of the master index tile this Image lies. |
160 | * If number_index_lookups() is 0, the returns the same value |
161 | * as dimensions(). |
162 | * |
163 | * Only applies when type() returns \ref on_atlas. |
164 | */ |
165 | vec2 |
166 | master_index_tile_dims(void) const; |
167 | |
168 | /*! |
169 | * Returns the quotient of dimensions() divided |
170 | * by master_index_tile_dims(). |
171 | * |
172 | * Only applies when type() returns \ref on_atlas. |
173 | */ |
174 | float |
175 | dimensions_index_divisor(void) const; |
176 | |
177 | /*! |
178 | * Returns the bindless handle for the Image. |
179 | * |
180 | * Only applies when type() does NOT return \ref on_atlas. |
181 | */ |
182 | uint64_t |
183 | bindless_handle(void) const; |
184 | |
185 | /*! |
186 | * Returns the image type. |
187 | */ |
188 | type_t |
189 | type(void) const; |
190 | |
191 | /*! |
192 | * Returns the format of the image. |
193 | */ |
194 | enum format_t |
195 | format(void) const; |
196 | |
197 | protected: |
198 | /*! |
199 | * Protected ctor for creating an Image backed by a bindless texture; |
200 | * Backends should use this ctor for Image deried classes that do |
201 | * cleanup (for example releasing the handle and/or deleting the texture). |
202 | * \param atlas ImageAtlas atlas onto which to place the image. |
203 | * \param w width of underlying texture |
204 | * \param h height of underlying texture |
205 | * \param m number of mipmap levels of the image |
206 | * \param type the type of the bindless texture, must NOT have value |
207 | * \ref on_atlas. |
208 | * \param fmt the format of the image |
209 | * \param handle the bindless handle value used by the Gfx API in |
210 | * shaders to reference the texture. |
211 | * \param action action to call to release backing resources of |
212 | * the created Image. |
213 | */ |
214 | Image(ImageAtlas &atlas, int w, int h, unsigned int m, |
215 | enum type_t type, uint64_t handle, enum format_t fmt, |
216 | const reference_counted_ptr<ResourceReleaseAction> &action = |
217 | reference_counted_ptr<ResourceReleaseAction>()); |
218 | |
219 | private: |
220 | friend class ImageAtlas; |
221 | |
222 | Image(ImageAtlas &atlas, int w, int h, |
223 | const ImageSourceBase &image_data); |
224 | |
225 | void *m_d; |
226 | }; |
227 | |
228 | /*! |
229 | * \brief |
230 | * ImageSourceBase defines the inteface for copying texel data |
231 | * from a source (CPU memory, a file, etc) to an |
232 | * AtlasColorBackingStoreBase derived object. |
233 | */ |
234 | class ImageSourceBase |
235 | { |
236 | public: |
237 | virtual |
238 | ~ImageSourceBase() |
239 | {} |
240 | |
241 | /*! |
242 | * To be implemented by a derived class to return true |
243 | * if a region (across all mipmap levels) has a constant |
244 | * color. |
245 | * \param location location at LOD 0 |
246 | * \param square_size width and height of region to check |
247 | * \param dst if all have texels of the region have the same |
248 | * color, write that color value to dst. |
249 | */ |
250 | virtual |
251 | bool |
252 | all_same_color(ivec2 location, int square_size, u8vec4 *dst) const = 0; |
253 | |
254 | /*! |
255 | * To be implemented by a derived class to return the number of |
256 | * levels (including the base-image) of image source has, i.e. |
257 | * if the image is to have no mipmapping, return 1. |
258 | */ |
259 | virtual |
260 | unsigned int |
261 | number_levels(void) const = 0; |
262 | |
263 | /*! |
264 | * To be implemented by a derived class to write to |
265 | * a \ref c_array of \ref u8vec4 data a rectangle of |
266 | * texels of a particular mipmap level. NOTE: if pixels |
267 | * are requested to be fetched from outside the sources |
268 | * natural dimensions, those pixels outside are to be |
269 | * duplicates of the boundary values. |
270 | * |
271 | * \param level LOD of data where 0 represents the highest |
272 | * level of detail and each successive level |
273 | * is half the resolution in each dimension; |
274 | * it is gauranteed by the called that |
275 | * 0 <= level() < number_levels() |
276 | * \param location (x, y) location of data from which to copy |
277 | * \param w width of data from which to copy |
278 | * \param h height of data from which to copy |
279 | * \param dst location to which to write data, data is to be packed |
280 | * dst[x + w * y] holds the texel data |
281 | * (x + location.x(), y + location.y()) with |
282 | * 0 <= x < w and 0 <= y < h |
283 | */ |
284 | virtual |
285 | void |
286 | fetch_texels(unsigned int level, ivec2 location, |
287 | unsigned int w, unsigned int h, |
288 | c_array<u8vec4> dst) const = 0; |
289 | |
290 | /*! |
291 | * To be implemented by a derived class to return |
292 | * the format of the image data. |
293 | */ |
294 | virtual |
295 | enum Image::format_t |
296 | format(void) const = 0; |
297 | }; |
298 | |
299 | /*! |
300 | * \brief |
301 | * An implementation of \ref ImageSourceBase where the data is backed |
302 | * by a c_array<const u8vec4> data. |
303 | */ |
304 | class ImageSourceCArray:public ImageSourceBase |
305 | { |
306 | public: |
307 | /*! |
308 | * Ctor. |
309 | * \param dimensions width and height of the LOD level 0 mipmap; |
310 | * the LOD level n is then assumed to be size |
311 | * (dimensions.x() >> n, dimensions.y() >> n) |
312 | * \param pdata the texel data, the data is NOT copied, thus the |
313 | * contents backing the texel data must not be freed |
314 | * until the ImageSourceCArray goes out of scope. |
315 | * \param fmt the format of the image data |
316 | */ |
317 | ImageSourceCArray(uvec2 dimensions, |
318 | c_array<const c_array<const u8vec4> > pdata, |
319 | enum Image::format_t fmt); |
320 | virtual |
321 | bool |
322 | all_same_color(ivec2 location, int square_size, u8vec4 *dst) const; |
323 | |
324 | virtual |
325 | unsigned int |
326 | number_levels(void) const; |
327 | |
328 | virtual |
329 | void |
330 | fetch_texels(unsigned int mimpap_level, ivec2 location, |
331 | unsigned int w, unsigned int h, |
332 | c_array<u8vec4> dst) const; |
333 | |
334 | virtual |
335 | enum Image::format_t |
336 | format(void) const; |
337 | |
338 | private: |
339 | uvec2 m_dimensions; |
340 | c_array<const c_array<const u8vec4> > m_data; |
341 | enum Image::format_t m_format; |
342 | }; |
343 | |
344 | /*! @} */ |
345 | |
346 | } //namespace |
347 | |
348 | #endif |
349 | |