1#include <iostream>
2#include <sstream>
3#include <fstream>
4#include <bitset>
5
6#include <fastuidraw/util/util.hpp>
7#include <fastuidraw/painter/painter.hpp>
8#include <fastuidraw/painter/backend/painter_header.hpp>
9#include <fastuidraw/painter/backend/painter_item_matrix.hpp>
10#include <fastuidraw/painter/backend/painter_clip_equations.hpp>
11#include <fastuidraw/painter/attribute_data/stroked_point.hpp>
12#include <fastuidraw/painter/attribute_data/arc_stroked_point.hpp>
13
14#include "sdl_painter_demo.hpp"
15
16using namespace fastuidraw;
17
18typedef std::bitset<32> bitset;
19
20c_string
21shader_extension(GLenum shader_type)
22{
23 switch (shader_type)
24 {
25 case GL_FRAGMENT_SHADER: return "frag";
26 case GL_VERTEX_SHADER: return "vert";
27 case GL_GEOMETRY_SHADER: return "geom";
28 case GL_TESS_CONTROL_SHADER: return "tesc";
29 case GL_TESS_EVALUATION_SHADER: return "tese";
30 case GL_COMPUTE_SHADER: return "comp";
31 default: return "unknown";
32 }
33}
34
35c_string
36label_sampler_type(GLenum type)
37{
38#define EASY(X) case X: return #X
39
40#ifndef FASTUIDRAW_GL_USE_GLES
41#define SUFFIX_1D(X) \
42 EASY(X##1D_ARRAY); \
43 EASY(X##1D); \
44 EASY(X##2D_RECT);
45#else
46#define SUFFIX_1D(X) ;
47#endif
48
49#define SUFFIX_MS(X) \
50 EASY(X##2D_MULTISAMPLE); \
51 EASY(X##2D_MULTISAMPLE_ARRAY);
52
53#define SUFFIX(X) \
54 SUFFIX_1D(X); \
55 EASY(X##2D); \
56 EASY(X##3D); \
57 EASY(X##CUBE); \
58 EASY(X##2D_ARRAY); \
59 EASY(X##BUFFER);
60
61#define PREFIX(X) \
62 SUFFIX(GL_##X##_); \
63 SUFFIX(GL_INT_##X##_); \
64 SUFFIX(GL_UNSIGNED_INT_##X##_); \
65
66#define PREFIX_MS(X) \
67 SUFFIX_MS(GL_##X##_); \
68 SUFFIX_MS(GL_INT_##X##_); \
69 SUFFIX_MS(GL_UNSIGNED_INT_##X##_); \
70
71 switch(type)
72 {
73 PREFIX(SAMPLER);
74 PREFIX_MS(SAMPLER);
75 PREFIX(IMAGE);
76#ifndef FASTUIDRAW_GL_USE_GLES
77 PREFIX_MS(IMAGE);
78#endif
79 }
80
81 return nullptr;
82
83#undef PREFIX_MS
84#undef SUFFIX_MS
85#undef PREFIX
86#undef SUFFIX
87#undef SUFFIX_1D
88#undef EASY
89}
90
91class painter_test:public sdl_painter_demo
92{
93public:
94 painter_test(void):
95 sdl_painter_demo("", true)
96 {}
97
98protected:
99
100 void
101 log_helper(const reference_counted_ptr<gl::Program> &pr,
102 c_string prefix_1, c_string prefix_2, GLenum shader_type)
103 {
104 unsigned int cnt;
105 c_string label;
106
107 cnt = pr->num_shaders(shader_type);
108 if (cnt == 0)
109 {
110 return;
111 }
112
113 label = gl::Shader::gl_shader_type_label(shader_type);
114 std::cout << label << "'s written to:\n";
115
116 for(unsigned int i = 0; i < cnt; ++i)
117 {
118 std::ostringstream name, name_glsl, name_log;
119
120 name << "painter." << prefix_1 << ".";
121 if (prefix_2)
122 {
123 name << prefix_2 << ".";
124 }
125 name << i << "." << shader_extension(shader_type);
126 name_glsl << name.str() << ".glsl";
127 name_log << name.str() << ".log";
128
129 std::ofstream file(name_glsl.str().c_str());
130 file << pr->shader_src_code(shader_type, i);
131 std::cout << "\tSource #" << i << ":" << name.str() << "\n";
132
133 std::ofstream file_log(name_log.str().c_str());
134 file_log << pr->shader_compile_log(shader_type, i);
135 std::cout << "\tCompile Log #" << i << ":" << name_log.str() << "\n";
136 }
137 }
138
139 void
140 log_program(const reference_counted_ptr<gl::Program> &pr,
141 c_string prefix_1, c_string prefix_2)
142 {
143 if (!pr)
144 {
145 return;
146 }
147 else
148 {
149 std::ostringstream name;
150
151 name << "painter." << prefix_1;
152 if (prefix_2)
153 {
154 name << "." << prefix_2;
155 }
156 name << ".program.log";
157
158 std::ofstream file(name.str().c_str());
159
160 file << pr->log();
161
162 /* query the program for the values of all texture types */
163 if (pr->link_success())
164 {
165 pr->use_program();
166 gl::Program::block_info default_block(pr->default_uniform_block());
167 for (unsigned int v = 0, endv = default_block.number_variables(); v < endv; ++v)
168 {
169 gl::Program::shader_variable_info sh(default_block.variable(v));
170 const char *sampler_type;
171
172 sampler_type = label_sampler_type(sh.glsl_type());
173 if (sampler_type)
174 {
175 file << sh.name() << " of type " << sampler_type << "\n";
176 for (unsigned c = 0, endc = sh.count(); c < endc; ++c)
177 {
178 GLint value;
179 fastuidraw_glGetUniformiv(pr->name(), sh.location(c), &value);
180 file << "\t[" << c << "] bound at " << value << " binding point\n";
181 }
182 }
183 }
184 }
185
186 std::cout << "\n\nProgram Log and contents written to "
187 << name.str() << "\n";
188 }
189
190 log_helper(pr, prefix_1, prefix_2, GL_VERTEX_SHADER);
191 log_helper(pr, prefix_1, prefix_2, GL_FRAGMENT_SHADER);
192 log_helper(pr, prefix_1, prefix_2, GL_GEOMETRY_SHADER);
193 log_helper(pr, prefix_1, prefix_2, GL_TESS_EVALUATION_SHADER);
194 log_helper(pr, prefix_1, prefix_2, GL_TESS_CONTROL_SHADER);
195
196 if (pr->link_success())
197 {
198 std::cout << "Link success\n";
199 pr->use_program();
200 }
201 else
202 {
203 std::cout << "Link Failed\n";
204 }
205 }
206
207 void
208 derived_init(int, int)
209 {
210 fastuidraw::c_string program_labels[gl::PainterEngineGL::number_program_types] =
211 {
212 [gl::PainterEngineGL::program_all] = "program_all",
213 [gl::PainterEngineGL::program_without_discard] = "program_without_discard",
214 [gl::PainterEngineGL::program_with_discard] = "program_with_discard",
215 };
216
217 fastuidraw::c_string blend_labels[PainterBlendShader::number_types] =
218 {
219 [PainterBlendShader::single_src] = "single_src",
220 [PainterBlendShader::dual_src] = "dual_src",
221 [PainterBlendShader::framebuffer_fetch] = "framebuffer_fetch",
222 };
223
224 for (int pr = 0; pr < gl::PainterEngineGL::number_program_types; ++pr)
225 {
226 for (int b = 0; b < PainterBlendShader::number_types; ++b)
227 {
228 reference_counted_ptr<gl::Program> program;
229 program = m_backend->program(static_cast<enum gl::PainterEngineGL::program_type_t>(pr),
230 static_cast<enum PainterBlendShader::shader_type>(b));
231 log_program(program, program_labels[pr], blend_labels[b]);
232 }
233 }
234 log_program(m_backend->program_deferred_coverage_buffer(), "deferred_coverage_buffer", nullptr);
235
236 std::cout << "\nUseful command to see shader after pre-processor:\n"
237 << "\tsed 's/#version/@version/g' file.glsl | sed 's/#extension/@extension/g'"
238 << " | cpp | grep -v \"#\" | sed '/^\\s*$/d'"
239 << " | sed 's/@version/#version/g' | sed 's/@extension/#extension/g'\n";
240 }
241
242 void
243 draw_frame(void)
244 {
245 end_demo(0);
246 }
247
248 void
249 handle_event(const SDL_Event &ev)
250 {
251 switch(ev.type)
252 {
253 case SDL_QUIT:
254 end_demo(0);
255 break;
256
257 case SDL_KEYUP:
258 switch(ev.key.keysym.sym)
259 {
260 case SDLK_ESCAPE:
261 end_demo(0);
262 break;
263 }
264 break;
265 };
266 }
267
268private:
269
270};
271
272int
273main(int argc, char **argv)
274{
275 FASTUIDRAWassert(StrokedPoint::number_offset_types < FASTUIDRAW_MAX_VALUE_FROM_NUM_BITS(StrokedPoint::offset_type_num_bits));
276 std::cout << std::setw(45) << "header_size = " << PainterHeader::header_size << "\n"
277 << std::setw(45) << "clip_equations_data_size = " << PainterClipEquations::clip_data_size << "\n"
278 << std::setw(45) << "item_matrix_data_size = " << PainterItemMatrix::matrix_data_size << "\n"
279 << std::setw(45) << "brush image_data_size = " << PainterImageBrushShaderData::shader_data_size << "\n"
280 << std::setw(45) << "brush repeat_window_data_size = " << PainterBrush::repeat_window_data_size << "\n"
281 << std::setw(45) << "brush transformation_matrix_data_size = " << PainterBrush::transformation_matrix_data_size << "\n"
282 << std::setw(45) << "brush transformation_translation_data_size = " << PainterBrush::transformation_translation_data_size << "\n"
283 << "\n"
284
285 << std::setw(45) << "brush image_mask = " << bitset(PainterBrush::image_mask) << "\n"
286 << std::setw(45) << "brush image_mipmap_mask = " << bitset(PainterImageBrushShader::mipmap_mask << PainterBrush::image_bit0) << "\n"
287 << std::setw(45) << "brush gradient_mask = " << bitset(PainterBrush::gradient_mask) << "\n"
288 << std::setw(45) << "brush repeat_window_mask = " << bitset(PainterBrush::repeat_window_mask) << "\n"
289 << std::setw(45) << "brush repeat_window_x_spread_type_mask = " << bitset(PainterBrush::repeat_window_x_spread_type_mask) << "\n"
290 << std::setw(45) << "brush repeat_window_y_spread_type_mask = " << bitset(PainterBrush::repeat_window_y_spread_type_mask) << "\n"
291 << std::setw(45) << "brush transformation_translation_mask = " << bitset(PainterBrush::transformation_translation_mask) << "\n"
292 << std::setw(45) << "brush transformation_matrix_mask = " << bitset(PainterBrush::transformation_matrix_mask) << "\n"
293 << std::setw(45) << "brush image_type_mask = " << bitset(PainterImageBrushShader::type_mask << PainterBrush::image_bit0) << "\n"
294 << std::setw(45) << "brush image_format_mask = " << bitset(PainterImageBrushShader::format_mask << PainterBrush::image_bit0) << "\n"
295 << std::setw(45) << "brush number_feature_bits = " << PainterBrush::number_feature_bits << "\n"
296
297 << std::setw(45) << "stroked_number_offset_types = " << StrokedPoint::number_offset_types << "\n"
298 << std::setw(45) << "stroked_offset_type_bit0 = " << StrokedPoint::offset_type_bit0 << "\n"
299 << std::setw(45) << "stroked_offset_type_num_bits = " << StrokedPoint::offset_type_num_bits << "\n"
300 << std::setw(45) << "stroked_boundary_bit = " << StrokedPoint::boundary_bit << "\n"
301 << std::setw(45) << "stroked_depth_bit0 = " << StrokedPoint::depth_bit0 << "\n"
302 << std::setw(45) << "stroked_depth_num_bits = " << StrokedPoint::depth_num_bits << "\n"
303 << std::setw(45) << "stroked_join_bit = " << StrokedPoint::join_bit << "\n"
304 << std::setw(45) << "stroked_number_common_bits = " << StrokedPoint::number_common_bits << "\n"
305 << std::setw(45) << "stroked_normal0_y_sign_bit = " << StrokedPoint::normal0_y_sign_bit << "\n"
306 << std::setw(45) << "stroked_normal1_y_sign_bit = " << StrokedPoint::normal1_y_sign_bit << "\n"
307 << std::setw(45) << "stroked_sin_sign_bit = " << StrokedPoint::sin_sign_bit << "\n"
308 << std::setw(45) << "stroked_adjustable_cap_ending_bit = " << StrokedPoint::adjustable_cap_ending_bit << "\n"
309 << std::setw(45) << "stroked_bevel_edge_bit = " << StrokedPoint::bevel_edge_bit << "\n";
310
311 painter_test P;
312 return P.main(argc, argv);
313
314}
315