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 <allanmac@google.com>
Commit-Queue: Allan MacKinnon <allanmac@google.com>
Auto-Submit: Allan MacKinnon <allanmac@google.com>
This commit is contained in:
Allan MacKinnon 2018-10-01 09:16:33 -07:00 committed by Skia Commit-Bot
parent 3b8b11e1f9
commit 6ddc9598ef
7 changed files with 432 additions and 19 deletions

View File

@ -17,9 +17,32 @@
#include "common/cl/find_cl.h" #include "common/cl/find_cl.h"
#include "common/cl/assert_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 "svg/svg_doc.h"
#include "svg2skc/svg2skc.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 // load test file
// //
#ifdef SKC_TEST_SVG
struct svg_doc * svg_doc = svg_doc_parse(argv[1],false); struct svg_doc * svg_doc = svg_doc_parse(argv[1],false);
fprintf(stderr,"p/r/l = %u / %u / %u\n", fprintf(stderr,"p/r/l = %u / %u / %u\n",
svg_doc_path_count(svg_doc), svg_doc_path_count(svg_doc),
svg_doc_raster_count(svg_doc), svg_doc_raster_count(svg_doc),
svg_doc_layer_count(svg_doc)); svg_doc_layer_count(svg_doc));
#endif
// //
// fire up GL // fire up GL
@ -171,7 +196,7 @@ main(int argc, char const * argv[])
err = skc_styling_create(context, err = skc_styling_create(context,
&styling, &styling,
svg_doc_layer_count(svg_doc), SKC_TEST(layer_count),
1000, 1000,
2 * 1024 * 1024); 2 * 1024 * 1024);
@ -204,7 +229,7 @@ main(int argc, char const * argv[])
if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS) if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS)
{ {
// decode paths // decode paths
paths = svg_doc_paths_decode(svg_doc,path_builder); paths = SKC_TEST(paths_decode,path_builder);
} }
// rasterize the paths? // rasterize the paths?
@ -217,7 +242,7 @@ main(int argc, char const * argv[])
skc_interop_transform(interop,ts); skc_interop_transform(interop,ts);
// decode rasters // 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 // restore the transform stack
ts_transform_stack_restore(ts,ts_save); ts_transform_stack_restore(ts,ts_save);
@ -233,7 +258,7 @@ main(int argc, char const * argv[])
skc_composition_unseal(composition,true); skc_composition_unseal(composition,true);
// decode layers -- places rasters // 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 // seal the styling -- render will seal if not called
skc_styling_seal(styling); skc_styling_seal(styling);
@ -267,6 +292,8 @@ main(int argc, char const * argv[])
// how many blocks are in use? // how many blocks are in use?
if (key == 'I') if (key == 'I')
skc_runtime_cl_12_debug(context); skc_runtime_cl_12_debug(context);
else if (key == 'T')
SKC_TEST(toggle);
// do we only want to run part of the pipeline? // do we only want to run part of the pipeline?
if ((key >= SKC_PIPELINE_START_AT_DEFINE_PATHS) && (key <= SKC_PIPELINE_START_AT_RENDER)) 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) if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_COMPOSITION)
{ {
// rewind the svg doc // rewind the svg doc
svg_doc_rewind(svg_doc); SKC_TEST(rewind);
if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS) if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS)
{ {
// release the 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) if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE)
{ {
// release the rasters // release the rasters
svg_doc_rasters_release(svg_doc,rasters,context); SKC_TEST(rasters_release,context,rasters);
} }
} }

View File

@ -1794,7 +1794,7 @@ skc_kernel_render(__global union skc_layer_node const * SKC_RESTRICT const
group.range.lo = 0; group.range.lo = 0;
group.range.hi = SKC_UINT_MAX; group.range.hi = SKC_UINT_MAX;
group.depth = 0; group.depth = SKC_UINT_MAX;
group.id = 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; cmd_next = layer_node_new.cmds;
// if this is final then configure so groups get unwound, otherwise we're done // 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)) 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; cmd_next = groups[group.id].cmds.leave;
// decrement group depth // decrement group depth
if (--group.depth == 0) if (--group.depth == SKC_UINT_MAX)
{ {
flags |= SKC_TILE_FLAGS_FLUSH_COMPLETE; flags |= SKC_TILE_FLAGS_FLUSH_COMPLETE;
} }

View File

@ -250,10 +250,22 @@ skc_styling_group_leave(skc_styling_t styling,
uint32_t n, uint32_t n,
skc_styling_cmd_t const * cmds); 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_err
skc_styling_group_parents(skc_styling_t styling, skc_styling_group_parents(skc_styling_t styling,
skc_group_id group_id, skc_group_id group_id,
uint32_t depth, uint32_t n,
skc_group_id const * parents); skc_group_id const * parents);
skc_err skc_err

View File

@ -132,20 +132,19 @@ skc_styling_group_leave(skc_styling_t styling,
skc_err skc_err
skc_styling_group_parents(skc_styling_t styling, skc_styling_group_parents(skc_styling_t styling,
skc_group_id group_id, skc_group_id group_id,
uint32_t depth, uint32_t n,
skc_group_id const * parents) skc_group_id const * parents)
{ {
styling->unseal(styling->impl,true); styling->unseal(styling->impl,true);
styling->groups.extent[group_id].parents = (union skc_group_parents) styling->groups.extent[group_id].parents = (union skc_group_parents)
{ {
.depth = depth, .depth = n, // starts at 0
.base = styling->extras.count .base = styling->extras.count
}; };
memcpy(styling->extras.extent + styling->extras.count,parents,depth * sizeof(*parents)); while (n-- > 0)
styling->extras.extent[styling->extras.count++].parent = parents[n];
styling->extras.count += depth;
return SKC_ERR_SUCCESS; return SKC_ERR_SUCCESS;
} }

View File

@ -79,8 +79,8 @@ union skc_group_parents
skc_uint2 u32v2; skc_uint2 u32v2;
struct { struct {
skc_uint depth; // zero-based depth of this group skc_uint depth;
skc_uint base; // index to sequence of group ids leading back to root skc_uint base;
}; };
}; };

View File

@ -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 <stdio.h>
#include <stdlib.h>
#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<<ii*8,1.0f);
skc_styling_cmd_t cmds[1 + 1 + 3 + 1];
cmds[0] = SKC_STYLING_OPCODE_COVER_NONZERO;
cmds[1] = SKC_STYLING_OPCODE_COVER_MASK;
skc_styling_layer_fill_rgba_encoder(cmds+2,rgba);
cmds[_countof(cmds)-1] = SKC_STYLING_OPCODE_BLEND_OVER | SKC_STYLING_OPCODE_IS_FINAL;
skc_styling_group_layer(styling,
group_ids[1],
ii*2+1,
_countof(cmds),cmds);
}
}
//
// for all rasters...
//
for (uint32_t ii=0; ii<6; ii++)
{
skc_composition_place(composition,
rasters+ii,
&ii,
NULL, // &cmd->place.tx,
NULL, // &cmd->place.ty,
1);
}
}
//
//
//

View File

@ -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 <skc/skc.h>
//
//
//
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);
//
//
//