aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/compute/skc/main.c
blob: 2af8ebb6fc5ddba9324d951023f01b8909421063 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can
 * be found in the LICENSE file.
 *
 */

//
//
//

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#include "common/cl/find_cl.h"
#include "common/cl/assert_cl.h"

#include "svg/svg_doc.h"
#include "svg2skc/svg2skc.h"
#include "svg2skc/transform_stack.h"

//
//
//

#include "platforms/cl_12/skc_cl.h"
#include "interop.h"

//
//
//

typedef enum skc_pipeline_start_at_e {
  SKC_PIPELINE_START_AT_DEFINE_PATHS = '1',
  SKC_PIPELINE_START_AT_RASTERIZE    = '2',
  SKC_PIPELINE_START_AT_COMPOSITION  = '3',
  SKC_PIPELINE_START_AT_RENDER       = '4'
} skc_pipeline_start_at_e;

//
// Callback for explicitly waiting for render completion
//

#if 0
static
void
is_render_complete(skc_surface_t     surface,
                   skc_styling_t     styling,
                   skc_composition_t composition,
                   skc_framebuffer_t fb,
                   void            * data)
{
  // exit while loop
  *(bool*)data = true;
}
#endif

//
// FIXME - for debugging purposes declare this internal prototype
//

void
skc_runtime_cl_12_debug(struct skc_context * const context);

//
//
//

int
main(int argc, char const * argv[])
{
  //
  //
  //
  if (argc <= 1)
    {
      fprintf(stderr,"-- missing filename\n");
      return EXIT_FAILURE; // no filename
    }

  //
  // load test file
  //
  struct svg_doc * svg_doc = svg_doc_parse(argv[1],false);

  fprintf(stderr,"p/r/l = %u / %u / %u\n",
          svg_doc_path_count(svg_doc),
          svg_doc_raster_count(svg_doc),
          svg_doc_layer_count(svg_doc));

  //
  // fire up GL
  //
  struct skc_interop * interop = skc_interop_create();

  //
  // find platform and device by name
  //
  cl_platform_id platform_id_cl;
  cl_device_id   device_id_cl;

  cl(FindIdsByName("Intel","Graphics",
                   &platform_id_cl,
                   &device_id_cl,
                   0,NULL,NULL,
                   true));

  //
  // create the CL context with GL interop
  //
#ifdef _WIN32
  cl_context_properties context_properties_cl[] =
    {
      CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id_cl,
      CL_GL_CONTEXT_KHR,   skc_interop_get_wgl_context(),
      CL_WGL_HDC_KHR,      skc_interop_get_wgl_dc(),
      0
    };
#else
#error "Missing a system-compatible context!"
#endif

  cl_int     cl_err;
  cl_context context_cl = clCreateContext(context_properties_cl,
                                          1,
                                          &device_id_cl,
                                          NULL,
                                          NULL,
                                          &cl_err); cl_ok(cl_err);
  //
  // register cl_context with GL interop
  //
  skc_interop_set_cl_context(interop,context_cl);

  //
  // create SKC context
  //
  skc_context_t context;

  skc_err err = skc_context_create_cl(&context,
                                      context_cl,
                                      device_id_cl);

  //
  // create path builder
  //
  skc_path_builder_t path_builder;

  err = skc_path_builder_create(context,&path_builder);

  //
  // create raster builder
  //
  skc_raster_builder_t raster_builder;

  err = skc_raster_builder_create(context,&raster_builder);

  //
  // create a composition
  //
  skc_composition_t composition;

  err = skc_composition_create(context,&composition);

  //
  // create a styling instance
  //
  skc_styling_t styling;

  err = skc_styling_create(context,
                           &styling,
                           svg_doc_layer_count(svg_doc),
                           1000,
                           2 * 1024 * 1024);

  //
  // create a surface
  //
  skc_surface_t surface;

  err = skc_surface_create(context,&surface);

  //
  // create a transform stack
  //
  struct skc_transform_stack * ts = skc_transform_stack_create(32);

  // prime the transform stack with subpixel scale
  skc_transform_stack_push_scale(ts,32.0,32.0);

  //
  // rasterize, render and reclaim svg until escape
  //
  skc_pipeline_start_at_e pipeline_start_at_base = SKC_PIPELINE_START_AT_DEFINE_PATHS;
  skc_pipeline_start_at_e pipeline_start_at_loop = SKC_PIPELINE_START_AT_DEFINE_PATHS;
  skc_path_t            * paths;
  skc_raster_t          * rasters;

  while (!skc_interop_should_exit(interop))
    {
      // redefine the paths?
      if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS)
        {
          // decode paths
          paths = svg_doc_paths_decode(svg_doc,path_builder);
        }

      // rasterize the paths?
      if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE)
        {
          // save stack
          uint32_t const ts_save = skc_transform_stack_save(ts);

          // update transform
          skc_interop_transform(interop,ts);

          // decode rasters
          rasters = svg_doc_rasters_decode(svg_doc,ts,paths,raster_builder);

          // restore the transform stack
          skc_transform_stack_restore(ts,ts_save);
        }

      // decode the styling and composition?
      if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_COMPOSITION)
        {
          // reset styling
          skc_styling_reset(styling);

          // unseal and reset the composition
          skc_composition_unseal(composition,true);

          // decode layers -- places rasters
          svg_doc_layers_decode(svg_doc,rasters,composition,styling,true/*is_srgb*/);

          // seal the styling -- render will seal if not called
          skc_styling_seal(styling);

          // seal the composition -- render will seal if not called
          skc_composition_seal(composition);
        }

      uint32_t const clip[] = { 0, 0, 65535, 65535 };
      int32_t  const txty[] = { 0, 0 };

      // render the styled composition to the surface
      skc_surface_render(surface,
                         styling,
                         composition,
                         skc_interop_get_framebuffer(interop),
                         clip,
                         txty,
                         NULL,
                         NULL);

      //
      // poll for events and maybe start from a different point in the
      // pipeline
      //
      int key;

      // poll for window events
      bool const transform_changed = skc_interop_poll(interop,&key);

      // how many blocks are in use?
      if (key == 'I')
        skc_runtime_cl_12_debug(context);

      // do we only want to run part of the pipeline?
      if ((key >= SKC_PIPELINE_START_AT_DEFINE_PATHS) && (key <= SKC_PIPELINE_START_AT_RENDER))
        pipeline_start_at_base = key;

      // valid for a loop
      pipeline_start_at_loop = pipeline_start_at_base;

      // if the transform changed then we must start at rasterize or before
      if (transform_changed)
        pipeline_start_at_loop = min(pipeline_start_at_loop,SKC_PIPELINE_START_AT_RASTERIZE);

      if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_COMPOSITION)
        {
          // rewind the svg doc
          svg_doc_rewind(svg_doc);

          if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS)
            {
              // release the paths
              svg_doc_paths_release(svg_doc,paths,context);
            }

          if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE)
            {
              // release the rasters
              svg_doc_rasters_release(svg_doc,rasters,context);
            }
        }

#if 0
      //
      // Note that we don't need to explicitly wait for the render()
      // to complete since SKC is fully concurrent and the styling and
      // compsition unseal() operations will "clock" the render loop.
      //

      //
      // explicitly spin until framebuffer is rendered
      //
      bool quit = false;

      while (!quit) {
        // fprintf(stderr,"WAITING ON: !quit\n");
        skc_context_wait(context);
      }
#endif
    }

  //
  // dispose of mundane resources
  //
  skc_transform_stack_release(ts);

  //
  // dispose of all SKC resources
  //
  err = skc_surface_release(surface);
  err = skc_styling_release(styling);
  err = skc_composition_release(composition);
  err = skc_raster_builder_release(raster_builder);
  err = skc_path_builder_release(path_builder);
  err = skc_context_release(context);

  //
  // dispose of GL interop
  //
  skc_interop_destroy(interop);

  //
  //
  //
  return EXIT_SUCCESS;
}

//
//
//