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
27namespace fastuidraw
28{
29
30///@cond
31class ImageSourceBase;
32class 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