1 | /*! |
2 | * \file colorstop_atlas.hpp |
3 | * \brief file colorstop_atlas.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 | |
20 | #ifndef FASTUIDRAW_COLORSTOP_ATLAS_HPP |
21 | #define FASTUIDRAW_COLORSTOP_ATLAS_HPP |
22 | |
23 | #include <fastuidraw/util/reference_counted.hpp> |
24 | #include <fastuidraw/colorstop.hpp> |
25 | |
26 | namespace fastuidraw |
27 | { |
28 | /*!\addtogroup PainterBackend |
29 | * @{ |
30 | */ |
31 | |
32 | /*! |
33 | * \brief |
34 | * Represents the interface for the backing store for the texels |
35 | * of a sequence of color stops. The expectation is that linear |
36 | * filtering acting on the underlying backing store is all that |
37 | * is needed for correct color interpolation from a gradient |
38 | * interpolate. For example in GL, this can be GL_TEXTURE_1D_ARRAY |
39 | * with both minification and magnification filters set as GL_LINEAR. |
40 | * An implementation of the class does NOT need to be thread safe |
41 | * because the user of the backing store (ColorStopAtlas) performs |
42 | * calls to the backing store behind its own mutex. |
43 | */ |
44 | class ColorStopBackingStore: |
45 | public reference_counted<ColorStopBackingStore>::concurrent |
46 | { |
47 | public: |
48 | virtual |
49 | ~ColorStopBackingStore(); |
50 | |
51 | /*! |
52 | * To be implemented by a derived class to set color data into the |
53 | * backing store. |
54 | * \param x horizontal position |
55 | * \param l length of data |
56 | * \param w width of data |
57 | * \param data RGBA8 values |
58 | */ |
59 | virtual |
60 | void |
61 | set_data(int x, int l, int w, |
62 | c_array<const u8vec4> data)=0; |
63 | |
64 | /*! |
65 | * To be implemented by a derived class to flush set_data() to |
66 | * the backing store. |
67 | */ |
68 | virtual |
69 | void |
70 | flush(void) |
71 | {} |
72 | |
73 | /*! |
74 | * Returns the dimensions of the backing store (as passed in the |
75 | * ctor). |
76 | */ |
77 | ivec2 |
78 | dimensions(void) const; |
79 | |
80 | /*! |
81 | * Returns the product of dimensions().x() |
82 | * against dimensions().y() |
83 | */ |
84 | int |
85 | width_times_height(void) const; |
86 | |
87 | /*! |
88 | * Resize the object by increasing the number of layers. |
89 | */ |
90 | void |
91 | resize(int new_num_layers); |
92 | |
93 | protected: |
94 | /*! |
95 | * Ctor. |
96 | * \param wl provides the dimensions of the ColorStopBackingStore |
97 | */ |
98 | explicit |
99 | ColorStopBackingStore(ivec2 wl); |
100 | |
101 | /*! |
102 | * Ctor |
103 | * \param w width of backing store |
104 | * \param num_layers number of layers of backing store |
105 | */ |
106 | ColorStopBackingStore(int w, int num_layers); |
107 | |
108 | /*! |
109 | * To be implemented by a derived class to resize the |
110 | * object. The resize changes ONLY the number of layers |
111 | * of the object and only increases the value as well. |
112 | * When called, the return value of dimensions() is |
113 | * the size before the resize completes. |
114 | * \param new_num_layers new number of layers to which |
115 | * to resize the underlying store. |
116 | */ |
117 | virtual |
118 | void |
119 | resize_implement(int new_num_layers) = 0; |
120 | |
121 | private: |
122 | void *m_d; |
123 | }; |
124 | |
125 | /*! |
126 | * \brief |
127 | * A ColorStopAtlas is a common location to all color stop data of an |
128 | * application. Ideally, all color stop sequences are placed into a single |
129 | * ColorStopAtlas (changes of ColorStopAtlas force draw-call breaks). |
130 | */ |
131 | class ColorStopAtlas: |
132 | public reference_counted<ColorStopAtlas>::concurrent |
133 | { |
134 | public: |
135 | /*! |
136 | * Ctor. |
137 | * \param pbacking_store handle to the ColorStopBackingStore |
138 | * object to which the atlas will store color stops |
139 | */ |
140 | explicit |
141 | ColorStopAtlas(reference_counted_ptr<ColorStopBackingStore> pbacking_store); |
142 | |
143 | virtual |
144 | ~ColorStopAtlas(); |
145 | |
146 | /*! |
147 | * Create a \ref ColorStopSequence onto this \ref ColorStopAtlas. |
148 | * \param color_stops source color stops to use |
149 | * \param pwidth specifies number of texels to occupy on the ColorStopAtlas. |
150 | * The discretization of the color stop values is specified by |
151 | * the width. Additionally, the width is clamped to \ref |
152 | * max_width(). |
153 | */ |
154 | reference_counted_ptr<ColorStopSequence> |
155 | create(const ColorStopArray &color_stops, unsigned int pwidth); |
156 | |
157 | /*! |
158 | * Returns the width of the ColorStopBackingStore |
159 | * of the atlas. |
160 | */ |
161 | unsigned int |
162 | max_width(void) const; |
163 | |
164 | /*! |
165 | * Returns a handle to the backing store of the atlas. |
166 | */ |
167 | reference_counted_ptr<const ColorStopBackingStore> |
168 | backing_store(void) const; |
169 | |
170 | /*! |
171 | * Increments an internal counter. If this internal |
172 | * counter is greater than zero, then the reurning |
173 | * of interval to the free store for later use is |
174 | * -delayed- until the counter reaches zero again |
175 | * (see unlock_resources()). The use case is |
176 | * for buffered painting where the GPU calls are delayed |
177 | * for later (to batch commands) and an Image may go |
178 | * out of scope before the GPU commands are sent to |
179 | * the GPU. By delaying the return of intervals to the |
180 | * freestore, the color stop data is valid still for |
181 | * rendering even if the owning ColorStopSequence |
182 | * has been deleted. |
183 | */ |
184 | void |
185 | lock_resources(void); |
186 | |
187 | /*! |
188 | * Decrements an internal counter. If this internal |
189 | * counter reaches zero, those intervals from those |
190 | * ColorStopSequence objects that were deleted |
191 | * while the counter was non-zero, are then returned |
192 | * to the interval free store. See lock_resources() |
193 | * for more details. |
194 | */ |
195 | void |
196 | unlock_resources(void); |
197 | |
198 | /*! |
199 | * Calls ColorStopBackingStore::flush() on |
200 | * the backing store (see backing_store()). |
201 | */ |
202 | void |
203 | flush(void) const; |
204 | |
205 | private: |
206 | friend class ColorStopSequence; |
207 | |
208 | /*! |
209 | * Allocate and set on the atlas a sequence of color values |
210 | * to be stored continuously in a common layer. Returns |
211 | * the offset into the layer in ivec2::x() and the which |
212 | * layer in ivec2::y(). |
213 | * \param data data to place on atlas |
214 | */ |
215 | ivec2 |
216 | allocate(c_array<const u8vec4> data); |
217 | |
218 | /*! |
219 | * Mark a region to be free on the atlas |
220 | * \param location .x() gives the offset into the layer to |
221 | * mark as free and .y() gives the layer |
222 | * \param width number of elements to mark as free |
223 | */ |
224 | void |
225 | deallocate(ivec2 location, int width); |
226 | |
227 | /*! |
228 | * Returns the total number of color stops that are available |
229 | * in the atlas without resizing the ColorStopBackingStore |
230 | * of the ColorStopAtlas. |
231 | */ |
232 | int |
233 | total_available(void) const; |
234 | |
235 | void *m_d; |
236 | }; |
237 | |
238 | /*! @} */ |
239 | } |
240 | |
241 | #endif |
242 | |