From 6ddc9598ef2a75c600407e3007a8fece03b62560 Mon Sep 17 00:00:00 2001 From: Allan MacKinnon Date: Mon, 1 Oct 2018 09:16:33 -0700 Subject: [PATCH] SKC group improvements NOTREECHECKS=true NOTRY=true NOPRESUBMIT=true Bug: skia: Change-Id: Ia1a3762b8b7537f4e672896aea7b4988410a71ef Reviewed-on: https://skia-review.googlesource.com/158320 Reviewed-by: Allan MacKinnon Commit-Queue: Allan MacKinnon Auto-Submit: Allan MacKinnon --- src/compute/skc/main.c | 43 ++- .../skc/platforms/cl_12/kernels/render.cl | 8 +- src/compute/skc/skc.h | 14 +- src/compute/skc/styling.c | 9 +- src/compute/skc/styling_types.h | 4 +- src/compute/tests/groups/groups.c | 300 ++++++++++++++++++ src/compute/tests/groups/groups.h | 73 +++++ 7 files changed, 432 insertions(+), 19 deletions(-) create mode 100644 src/compute/tests/groups/groups.c create mode 100644 src/compute/tests/groups/groups.h diff --git a/src/compute/skc/main.c b/src/compute/skc/main.c index 0a3f340001..bae9532edf 100644 --- a/src/compute/skc/main.c +++ b/src/compute/skc/main.c @@ -17,9 +17,32 @@ #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" -#include "ts/transform_stack.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 // // @@ -83,12 +106,14 @@ main(int argc, char const * argv[]) // // 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 @@ -171,7 +196,7 @@ main(int argc, char const * argv[]) err = skc_styling_create(context, &styling, - svg_doc_layer_count(svg_doc), + SKC_TEST(layer_count), 1000, 2 * 1024 * 1024); @@ -204,7 +229,7 @@ main(int argc, char const * argv[]) if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS) { // decode paths - paths = svg_doc_paths_decode(svg_doc,path_builder); + paths = SKC_TEST(paths_decode,path_builder); } // rasterize the paths? @@ -217,7 +242,7 @@ main(int argc, char const * argv[]) skc_interop_transform(interop,ts); // decode rasters - rasters = svg_doc_rasters_decode(svg_doc,ts,paths,raster_builder); + rasters = SKC_TEST(rasters_decode,ts,paths,raster_builder); // restore the transform stack ts_transform_stack_restore(ts,ts_save); @@ -233,7 +258,7 @@ main(int argc, char const * argv[]) skc_composition_unseal(composition,true); // decode layers -- places rasters - svg_doc_layers_decode(svg_doc,rasters,composition,styling,true/*is_srgb*/); + SKC_TEST(layers_decode,rasters,composition,styling,true/*is_srgb*/); // seal the styling -- render will seal if not called skc_styling_seal(styling); @@ -267,6 +292,8 @@ main(int argc, char const * argv[]) // 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)) @@ -282,18 +309,18 @@ main(int argc, char const * argv[]) if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_COMPOSITION) { // rewind the svg doc - svg_doc_rewind(svg_doc); + SKC_TEST(rewind); if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS) { // release the paths - svg_doc_paths_release(svg_doc,paths,context); + SKC_TEST(paths_release,context,paths); } if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE) { // release the rasters - svg_doc_rasters_release(svg_doc,rasters,context); + SKC_TEST(rasters_release,context,rasters); } } diff --git a/src/compute/skc/platforms/cl_12/kernels/render.cl b/src/compute/skc/platforms/cl_12/kernels/render.cl index 9f9530d55a..9f54315225 100644 --- a/src/compute/skc/platforms/cl_12/kernels/render.cl +++ b/src/compute/skc/platforms/cl_12/kernels/render.cl @@ -1794,7 +1794,7 @@ skc_kernel_render(__global union skc_layer_node const * SKC_RESTRICT const group.range.lo = 0; group.range.hi = SKC_UINT_MAX; - group.depth = 0; + group.depth = SKC_UINT_MAX; group.id = SKC_UINT_MAX; // @@ -1968,7 +1968,9 @@ skc_kernel_render(__global union skc_layer_node const * SKC_RESTRICT const cmd_next = layer_node_new.cmds; // if this is final then configure so groups get unwound, otherwise we're done - flags |= ((flags & SKC_TILE_FLAGS_FLUSH_FINALIZE) ? SKC_TILE_FLAGS_FLUSH_UNWIND : SKC_TILE_FLAGS_FLUSH_COMPLETE); + flags |= ((flags & SKC_TILE_FLAGS_FLUSH_FINALIZE) + ? SKC_TILE_FLAGS_FLUSH_UNWIND + : SKC_TILE_FLAGS_FLUSH_COMPLETE); } else if (!unwind && (layer_id_new >= group.range.lo && layer_id_new <= group.range.hi)) { @@ -1995,7 +1997,7 @@ skc_kernel_render(__global union skc_layer_node const * SKC_RESTRICT const cmd_next = groups[group.id].cmds.leave; // decrement group depth - if (--group.depth == 0) + if (--group.depth == SKC_UINT_MAX) { flags |= SKC_TILE_FLAGS_FLUSH_COMPLETE; } diff --git a/src/compute/skc/skc.h b/src/compute/skc/skc.h index 53d5f273af..6a50ee785d 100644 --- a/src/compute/skc/skc.h +++ b/src/compute/skc/skc.h @@ -250,10 +250,22 @@ skc_styling_group_leave(skc_styling_t styling, uint32_t n, skc_styling_cmd_t const * cmds); +// +// n: +// +// The number of parent groups above this group. The top of the +// hierarchy must start with a single enclosing group which has 0 +// parents. +// +// parents: +// +// The sequence of parent group ids leading from the top of +// hierarchy to the parent of 'group_id'. +// skc_err skc_styling_group_parents(skc_styling_t styling, skc_group_id group_id, - uint32_t depth, + uint32_t n, skc_group_id const * parents); skc_err diff --git a/src/compute/skc/styling.c b/src/compute/skc/styling.c index 5653e203a7..c917ebc0d0 100644 --- a/src/compute/skc/styling.c +++ b/src/compute/skc/styling.c @@ -132,20 +132,19 @@ skc_styling_group_leave(skc_styling_t styling, skc_err skc_styling_group_parents(skc_styling_t styling, skc_group_id group_id, - uint32_t depth, + uint32_t n, skc_group_id const * parents) { styling->unseal(styling->impl,true); styling->groups.extent[group_id].parents = (union skc_group_parents) { - .depth = depth, + .depth = n, // starts at 0 .base = styling->extras.count }; - memcpy(styling->extras.extent + styling->extras.count,parents,depth * sizeof(*parents)); - - styling->extras.count += depth; + while (n-- > 0) + styling->extras.extent[styling->extras.count++].parent = parents[n]; return SKC_ERR_SUCCESS; } diff --git a/src/compute/skc/styling_types.h b/src/compute/skc/styling_types.h index 10442e8f05..e4a520d30a 100644 --- a/src/compute/skc/styling_types.h +++ b/src/compute/skc/styling_types.h @@ -79,8 +79,8 @@ union skc_group_parents skc_uint2 u32v2; struct { - skc_uint depth; // zero-based depth of this group - skc_uint base; // index to sequence of group ids leading back to root + skc_uint depth; + skc_uint base; }; }; diff --git a/src/compute/tests/groups/groups.c b/src/compute/tests/groups/groups.c new file mode 100644 index 0000000000..901b2ce60d --- /dev/null +++ b/src/compute/tests/groups/groups.c @@ -0,0 +1,300 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can + * be found in the LICENSE file. + * + */ + +// +// +// + +#include +#include + +#include "color/color.h" +#include "ts/transform_stack.h" + +#include "groups.h" + +/* +Group { + children: [ + Layer { + rasters: [ + SkcRaster { + private: 2147745810 + } + ], + cmds: [ + CoverNonzero, + CoverWipMoveToMask + ] + }, + Layer { + rasters: [ + SkcRaster { + private: 2147745805 + } + ], + cmds: [ + CoverNonzero, + CoverMask, + FillColor( + [ + 1.0, + 1.0, + 1.0, + 1.0 + ] + ), + BlendOver + ] + } + ], + enter_cmds: [ + CoverMaskZero + ], + leave_cmds: [] +} +*/ + +static bool is_mask_invertible = false; + +void +groups_toggle() +{ + is_mask_invertible = !is_mask_invertible; +} + +// +// +// + +skc_path_t * +groups_paths_decode(skc_path_builder_t pb) +{ + skc_path_t * paths = malloc(sizeof(*paths) * 6); + + for (uint32_t ii=0; ii<3; ii++) + { + float const xy = (float)ii * 2.0f + 2.0f; + + skc_path_begin(pb); + skc_path_ellipse(pb,xy,xy,0.5f,1.5f); + skc_path_end(pb,paths+ii*2); + + skc_path_begin(pb); + skc_path_ellipse(pb,xy,xy,1.0f,1.0f); + skc_path_end(pb,paths+ii*2+1); + } + + return paths; +} + +void +groups_paths_release(skc_context_t context, + skc_path_t * const paths) +{ + skc_path_release(context,paths,6); + + free(paths); +} + +// +// +// + +skc_raster_t * +groups_rasters_decode(struct ts_transform_stack * const ts, + skc_path_t const * const paths, + skc_raster_builder_t rb) +{ + static float const raster_clip[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + skc_raster_t * rasters = malloc(sizeof(*rasters) * 6); + + uint32_t const ts_restore = ts_transform_stack_save(ts); + + ts_transform_stack_push_translate(ts,800,800); + ts_transform_stack_concat(ts); + + for (uint32_t ii=0; ii<6; ii++) + { + skc_raster_begin(rb); + skc_raster_add_filled(rb, + paths[ii], + ts_transform_stack_top_weakref(ts), + ts_transform_stack_top_transform(ts), + NULL, + raster_clip); + skc_raster_end(rb,rasters+ii); + } + + // restore stack depth + ts_transform_stack_restore(ts,ts_restore); + + return rasters; +} + +void +groups_rasters_release(skc_context_t context, + skc_raster_t * const rasters) +{ + skc_raster_release(context,rasters,6); + + free(rasters); +} + +// +// +// + +void +groups_rewind() +{ + ; +} + +// +// +// + +uint32_t +groups_layer_count() +{ + return 6; +} + +void +groups_layers_decode(skc_raster_t const * const rasters, + skc_composition_t composition, + skc_styling_t styling, + bool const is_srgb) +{ + skc_group_id group_ids[2]; + + { + skc_styling_group_alloc(styling,group_ids+0); + + // this is the root group + skc_styling_group_parents(styling,group_ids[0],0,NULL); + + // the range of the root group is maximal + skc_styling_group_range_lo(styling,group_ids[0],0); + skc_styling_group_range_hi(styling,group_ids[0],5); + + skc_styling_group_enter(styling, + group_ids[0], + 1, + (skc_styling_cmd_t[]) + { SKC_STYLING_OPCODE_COLOR_ACC_ZERO | + SKC_STYLING_OPCODE_IS_FINAL }); + + skc_styling_cmd_t cmds[3 + 1]; + + float background[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + + skc_styling_background_over_encoder(cmds,background); + + cmds[3] = SKC_STYLING_OPCODE_SURFACE_COMPOSITE | SKC_STYLING_OPCODE_IS_FINAL; + + skc_styling_group_leave(styling, + group_ids[0], + SKC_STYLING_CMDS(cmds)); + } + + // + // for all layers... + // + for (uint32_t ii=0; ii<3; ii++) + { + skc_styling_group_alloc(styling,group_ids+1); + + // this is the root group + skc_styling_group_parents(styling,group_ids[1],1,group_ids); + + // the range of the root group is maximal + skc_styling_group_range_lo(styling,group_ids[1],ii*2); + skc_styling_group_range_hi(styling,group_ids[1],ii*2+1); + + skc_styling_group_enter(styling, + group_ids[1], + 1, + (skc_styling_cmd_t[]) + { is_mask_invertible + ? (SKC_STYLING_OPCODE_COVER_MASK_ONE | SKC_STYLING_OPCODE_IS_FINAL) + : (SKC_STYLING_OPCODE_COVER_MASK_ZERO | SKC_STYLING_OPCODE_IS_FINAL) }); + + skc_styling_group_leave(styling, + group_ids[1], + 1, + (skc_styling_cmd_t[]) + { SKC_STYLING_OPCODE_NOOP | + SKC_STYLING_OPCODE_IS_FINAL }); + + // + // + // + + { + float const rgba[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + + skc_styling_cmd_t cmds[1 + 1 + 1]; + + cmds[0] = SKC_STYLING_OPCODE_COVER_NONZERO; + + if (is_mask_invertible) + { + cmds[1] = SKC_STYLING_OPCODE_COVER_WIP_MOVE_TO_MASK; + cmds[2] = SKC_STYLING_OPCODE_COVER_MASK_INVERT | SKC_STYLING_OPCODE_IS_FINAL; + } + else + { + cmds[1] = SKC_STYLING_OPCODE_COVER_WIP_MOVE_TO_MASK | SKC_STYLING_OPCODE_IS_FINAL; + } + + skc_styling_group_layer(styling, + group_ids[1], + ii*2, + _countof(cmds),cmds); + } + { + float rgba[4]; + + color_rgb32_to_rgba_f32(rgba,0xFF<place.tx, + NULL, // &cmd->place.ty, + 1); + } +} + +// +// +// diff --git a/src/compute/tests/groups/groups.h b/src/compute/tests/groups/groups.h new file mode 100644 index 0000000000..d82fda3664 --- /dev/null +++ b/src/compute/tests/groups/groups.h @@ -0,0 +1,73 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can + * be found in the LICENSE file. + * + */ + +// +// +// + +#pragma once + +// +// +// + +#include + +// +// +// + +void +groups_toggle(); + +// +// +// + +skc_path_t * +groups_paths_decode(skc_path_builder_t pb); + +void +groups_paths_release(skc_context_t context, + skc_path_t * const paths); + +// +// +// + +skc_raster_t * +groups_rasters_decode(struct ts_transform_stack * const ts, + skc_path_t const * const paths, + skc_raster_builder_t rb); + +void +groups_rasters_release(skc_context_t context, + skc_raster_t * const rasters); +// +// +// + +void +groups_rewind(); + +// +// +// + +uint32_t +groups_layer_count(); + +void +groups_layers_decode(skc_raster_t const * const rasters, + skc_composition_t composition, + skc_styling_t styling, + bool const is_srgb); + +// +// +//