/*
* 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 "ts/transform_stack.h"
//
//
//
// #define SKC_TEST_SVG
#ifdef SKC_TEST_SVG
//
// SVG
//
#include "svg/svg_doc.h"
#include "svg2skc/svg2skc.h"
#define SKC_TEST(f,...) svg_doc_##f(svg_doc,__VA_ARGS__)
void
svg_doc_toggle(struct svg_doc * sd) { ; };
#else
#include "tests/groups/groups.h"
#define SKC_TEST(f,...) groups_##f(__VA_ARGS__)
#endif
//
//
//
#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
//
#ifdef SKC_TEST_SVG
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));
#endif
//
// 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,
SKC_TEST(layer_count),
1000,
2 * 1024 * 1024);
//
// create a surface
//
skc_surface_t surface;
err = skc_surface_create(context,&surface);
//
// create a transform stack
//
struct ts_transform_stack * ts = ts_transform_stack_create(32);
// prime the transform stack with subpixel scale
ts_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 = SKC_TEST(paths_decode,path_builder);
}
// rasterize the paths?
if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE)
{
// save stack
uint32_t const ts_save = ts_transform_stack_save(ts);
// update transform
skc_interop_transform(interop,ts);
// decode rasters
rasters = SKC_TEST(rasters_decode,ts,paths,raster_builder);
// restore the transform stack
ts_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
SKC_TEST(layers_decode,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);
else if (key == 'T')
SKC_TEST(toggle);
// 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
SKC_TEST(rewind);
if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS)
{
// release the paths
SKC_TEST(paths_release,context,paths);
}
if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE)
{
// release the rasters
SKC_TEST(rasters_release,context,rasters);
}
}
#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
//
ts_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;
}
//
//
//