1 /*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can
5 * be found in the LICENSE file.
6 *
7 */
8
9 //
10 //
11 //
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <conio.h>
16
17 #include "common/cl/find_cl.h"
18 #include "common/cl/assert_cl.h"
19
20 #include "ts/transform_stack.h"
21
22 //
23 //
24 //
25
26 // #define SKC_TEST_SVG
27 #ifdef SKC_TEST_SVG
28 //
29 // SVG
30 //
31 #include "svg/svg_doc.h"
32 #include "svg2skc/svg2skc.h"
33
34 #define SKC_TEST(f,...) svg_doc_##f(svg_doc,__VA_ARGS__)
35
36 void
svg_doc_toggle(struct svg_doc * sd)37 svg_doc_toggle(struct svg_doc * sd) { ; };
38
39 #else
40
41 #include "tests/groups/groups.h"
42
43 #define SKC_TEST(f,...) groups_##f(__VA_ARGS__)
44
45 #endif
46
47 //
48 //
49 //
50
51 #include "platforms/cl_12/skc_cl.h"
52 #include "interop.h"
53
54 //
55 //
56 //
57
58 typedef enum skc_pipeline_start_at_e {
59 SKC_PIPELINE_START_AT_DEFINE_PATHS = '1',
60 SKC_PIPELINE_START_AT_RASTERIZE = '2',
61 SKC_PIPELINE_START_AT_COMPOSITION = '3',
62 SKC_PIPELINE_START_AT_RENDER = '4'
63 } skc_pipeline_start_at_e;
64
65 //
66 // Callback for explicitly waiting for render completion
67 //
68
69 #if 0
70 static
71 void
72 is_render_complete(skc_surface_t surface,
73 skc_styling_t styling,
74 skc_composition_t composition,
75 skc_framebuffer_t fb,
76 void * data)
77 {
78 // exit while loop
79 *(bool*)data = true;
80 }
81 #endif
82
83 //
84 // FIXME - for debugging purposes declare this internal prototype
85 //
86
87 void
88 skc_runtime_cl_12_debug(struct skc_context * const context);
89
90 //
91 //
92 //
93
94 int
main(int argc,char const * argv[])95 main(int argc, char const * argv[])
96 {
97 //
98 //
99 //
100 if (argc <= 1)
101 {
102 fprintf(stderr,"-- missing filename\n");
103 return EXIT_FAILURE; // no filename
104 }
105
106 //
107 // load test file
108 //
109 #ifdef SKC_TEST_SVG
110 struct svg_doc * svg_doc = svg_doc_parse(argv[1],false);
111
112 fprintf(stderr,"p/r/l = %u / %u / %u\n",
113 svg_doc_path_count(svg_doc),
114 svg_doc_raster_count(svg_doc),
115 svg_doc_layer_count(svg_doc));
116 #endif
117
118 //
119 // fire up GL
120 //
121 struct skc_interop * interop = skc_interop_create();
122
123 //
124 // find platform and device by name
125 //
126 cl_platform_id platform_id_cl;
127 cl_device_id device_id_cl;
128
129 cl(FindIdsByName("Intel","Graphics",
130 &platform_id_cl,
131 &device_id_cl,
132 0,NULL,NULL,
133 true));
134
135 //
136 // create the CL context with GL interop
137 //
138 #ifdef _WIN32
139 cl_context_properties context_properties_cl[] =
140 {
141 CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id_cl,
142 CL_GL_CONTEXT_KHR, skc_interop_get_wgl_context(),
143 CL_WGL_HDC_KHR, skc_interop_get_wgl_dc(),
144 0
145 };
146 #else
147 #error "Missing a system-compatible context!"
148 #endif
149
150 cl_int cl_err;
151 cl_context context_cl = clCreateContext(context_properties_cl,
152 1,
153 &device_id_cl,
154 NULL,
155 NULL,
156 &cl_err); cl_ok(cl_err);
157 //
158 // register cl_context with GL interop
159 //
160 skc_interop_set_cl_context(interop,context_cl);
161
162 //
163 // create SKC context
164 //
165 skc_context_t context;
166
167 skc_err err = skc_context_create_cl(&context,
168 context_cl,
169 device_id_cl);
170
171 //
172 // create path builder
173 //
174 skc_path_builder_t path_builder;
175
176 err = skc_path_builder_create(context,&path_builder);
177
178 //
179 // create raster builder
180 //
181 skc_raster_builder_t raster_builder;
182
183 err = skc_raster_builder_create(context,&raster_builder);
184
185 //
186 // create a composition
187 //
188 skc_composition_t composition;
189
190 err = skc_composition_create(context,&composition);
191
192 //
193 // create a styling instance
194 //
195 skc_styling_t styling;
196
197 err = skc_styling_create(context,
198 &styling,
199 SKC_TEST(layer_count),
200 1000,
201 2 * 1024 * 1024);
202
203 //
204 // create a surface
205 //
206 skc_surface_t surface;
207
208 err = skc_surface_create(context,&surface);
209
210 //
211 // create a transform stack
212 //
213 struct ts_transform_stack * ts = ts_transform_stack_create(32);
214
215 // prime the transform stack with subpixel scale
216 ts_transform_stack_push_scale(ts,32.0,32.0);
217
218 //
219 // rasterize, render and reclaim svg until escape
220 //
221 skc_pipeline_start_at_e pipeline_start_at_base = SKC_PIPELINE_START_AT_DEFINE_PATHS;
222 skc_pipeline_start_at_e pipeline_start_at_loop = SKC_PIPELINE_START_AT_DEFINE_PATHS;
223 skc_path_t * paths;
224 skc_raster_t * rasters;
225
226 while (!skc_interop_should_exit(interop))
227 {
228 // redefine the paths?
229 if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS)
230 {
231 // decode paths
232 paths = SKC_TEST(paths_decode,path_builder);
233 }
234
235 // rasterize the paths?
236 if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE)
237 {
238 // save stack
239 uint32_t const ts_save = ts_transform_stack_save(ts);
240
241 // update transform
242 skc_interop_transform(interop,ts);
243
244 // decode rasters
245 rasters = SKC_TEST(rasters_decode,ts,paths,raster_builder);
246
247 // restore the transform stack
248 ts_transform_stack_restore(ts,ts_save);
249 }
250
251 // decode the styling and composition?
252 if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_COMPOSITION)
253 {
254 // reset styling
255 skc_styling_reset(styling);
256
257 // unseal and reset the composition
258 skc_composition_unseal(composition,true);
259
260 // decode layers -- places rasters
261 SKC_TEST(layers_decode,rasters,composition,styling,true/*is_srgb*/);
262
263 // seal the styling -- render will seal if not called
264 skc_styling_seal(styling);
265
266 // seal the composition -- render will seal if not called
267 skc_composition_seal(composition);
268 }
269
270 uint32_t const clip[] = { 0, 0, 65535, 65535 };
271 int32_t const txty[] = { 0, 0 };
272
273 // render the styled composition to the surface
274 skc_surface_render(surface,
275 styling,
276 composition,
277 skc_interop_get_framebuffer(interop),
278 clip,
279 txty,
280 NULL,
281 NULL);
282
283 //
284 // poll for events and maybe start from a different point in the
285 // pipeline
286 //
287 int key;
288
289 // poll for window events
290 bool const transform_changed = skc_interop_poll(interop,&key);
291
292 // how many blocks are in use?
293 if (key == 'I')
294 skc_runtime_cl_12_debug(context);
295 else if (key == 'T')
296 SKC_TEST(toggle);
297
298 // do we only want to run part of the pipeline?
299 if ((key >= SKC_PIPELINE_START_AT_DEFINE_PATHS) && (key <= SKC_PIPELINE_START_AT_RENDER))
300 pipeline_start_at_base = key;
301
302 // valid for a loop
303 pipeline_start_at_loop = pipeline_start_at_base;
304
305 // if the transform changed then we must start at rasterize or before
306 if (transform_changed)
307 pipeline_start_at_loop = min(pipeline_start_at_loop,SKC_PIPELINE_START_AT_RASTERIZE);
308
309 if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_COMPOSITION)
310 {
311 // rewind the svg doc
312 SKC_TEST(rewind);
313
314 if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS)
315 {
316 // release the paths
317 SKC_TEST(paths_release,context,paths);
318 }
319
320 if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE)
321 {
322 // release the rasters
323 SKC_TEST(rasters_release,context,rasters);
324 }
325 }
326
327 #if 0
328 //
329 // Note that we don't need to explicitly wait for the render()
330 // to complete since SKC is fully concurrent and the styling and
331 // compsition unseal() operations will "clock" the render loop.
332 //
333
334 //
335 // explicitly spin until framebuffer is rendered
336 //
337 bool quit = false;
338
339 while (!quit) {
340 // fprintf(stderr,"WAITING ON: !quit\n");
341 skc_context_wait(context);
342 }
343 #endif
344 }
345
346 //
347 // dispose of mundane resources
348 //
349 ts_transform_stack_release(ts);
350
351 //
352 // dispose of all SKC resources
353 //
354 err = skc_surface_release(surface);
355 err = skc_styling_release(styling);
356 err = skc_composition_release(composition);
357 err = skc_raster_builder_release(raster_builder);
358 err = skc_path_builder_release(path_builder);
359 err = skc_context_release(context);
360
361 //
362 // dispose of GL interop
363 //
364 skc_interop_destroy(interop);
365
366 //
367 //
368 //
369 return EXIT_SUCCESS;
370 }
371
372 //
373 //
374 //
375