/* * 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 #include #include #include "raster_builder.h" #include "context.h" #include "weakref.h" #include "scheduler.h" #include "handle.h" #include "common.h" // // // #ifndef NDEBUG #include #define SKC_CONTEXT_WAIT_DEBUG(p) \ fprintf(stderr,"WAITING ON: " p "\n") #else #define SKC_CONTEXT_WAIT_DEBUG(p) #endif // // // #define SKC_CONTEXT_WAIT_WHILE(c,p) \ while (p) { \ SKC_CONTEXT_WAIT_DEBUG(#p); \ skc_context_wait(c); \ } // // // #if 0 // // IDENTITY TRANSFORM // static float const skc_transform_identity[8] = { 1.0f, 0.0f, 0.0f, // sx shx tx 0.0f, 1.0f, 0.0f, // shy sy ty 0.0f, 0.0f // w0 w1 1 <-- always 1 }; // float const * const skc_transform_identity_ptr = skc_transform_identity; // // DEFAULT RASTER CLIP // static float const skc_raster_clip_default[4] = { -FLT_MAX, -FLT_MAX, // lower left corner of bounding box +FLT_MAX, +FLT_MAX // upper right corner of bounding box }; // float const * const skc_raster_clip_default_ptr = skc_raster_clip_default; #endif // // // skc_err skc_raster_builder_retain(skc_raster_builder_t raster_builder) { raster_builder->refcount += 1; return SKC_ERR_SUCCESS; } //xbli // // skc_err skc_raster_builder_release(skc_raster_builder_t raster_builder) { SKC_ASSERT_STATE_ASSERT(SKC_RASTER_BUILDER_STATE_READY,raster_builder); raster_builder->release(raster_builder->impl); return SKC_ERR_SUCCESS; } // // // static skc_bool skc_raster_builder_path_ids_append(struct skc_raster_builder * const raster_builder, union skc_cmd_fill * const cmd, skc_path_t const path) { SKC_CONTEXT_WAIT_WHILE(raster_builder->context,skc_extent_ring_is_full(&raster_builder->path_ids.ring)); cmd->path = path; raster_builder->path_ids.extent[skc_extent_ring_wip_index_inc(&raster_builder->path_ids.ring)] = path; return skc_extent_ring_wip_is_full(&raster_builder->path_ids.ring); } static skc_bool skc_raster_builder_transforms_append(struct skc_raster_builder * const raster_builder, union skc_cmd_fill * const cmd, skc_transform_weakref_t * const transform_weakref, skc_float const * const transform) { // // FIXME -- check weakref // SKC_CONTEXT_WAIT_WHILE(raster_builder->context,skc_extent_ring_is_full(&raster_builder->transforms.ring)); cmd->transform = skc_extent_ring_wip_count(&raster_builder->transforms.ring); skc_uint const base = skc_extent_ring_wip_index_inc(&raster_builder->transforms.ring); memcpy(raster_builder->transforms.extent[base].f32a8,transform,sizeof(skc_float8)); return skc_extent_ring_wip_is_full(&raster_builder->transforms.ring); } static skc_bool skc_raster_builder_clips_append(struct skc_raster_builder * const raster_builder, union skc_cmd_fill * const cmd, skc_raster_clip_weakref_t * const raster_clip_weakref, skc_float const * const raster_clip) { // // FIXME -- check weakref // SKC_CONTEXT_WAIT_WHILE(raster_builder->context,skc_extent_ring_is_full(&raster_builder->clips.ring)); cmd->clip = skc_extent_ring_wip_count(&raster_builder->clips.ring); skc_uint const base = skc_extent_ring_wip_index_inc(&raster_builder->clips.ring); memcpy(raster_builder->clips.extent[base].f32a4,raster_clip,sizeof(skc_float4)); return skc_extent_ring_wip_is_full(&raster_builder->clips.ring); } static skc_bool skc_raster_builder_cmds_append(struct skc_raster_builder * const raster_builder, union skc_cmd_fill * const cmd) { SKC_CONTEXT_WAIT_WHILE(raster_builder->context,skc_extent_ring_is_full(&raster_builder->fill_cmds.ring)); cmd->cohort = skc_extent_ring_wip_count(&raster_builder->raster_ids.ring); skc_uint const base = skc_extent_ring_wip_index_inc(&raster_builder->fill_cmds.ring); raster_builder->fill_cmds.extent[base] = *cmd; #if 0 fprintf(stderr,"[ %4u, %4u, %4u, %4u ]\n", cmd->path, cmd->transform, cmd->clip, cmd->cohort); #endif return skc_extent_ring_wip_is_full(&raster_builder->fill_cmds.ring); } // // // static skc_bool skc_raster_builder_raster_ids_append(struct skc_raster_builder * const raster_builder, skc_raster_t const raster) { SKC_CONTEXT_WAIT_WHILE(raster_builder->context,skc_extent_ring_is_full(&raster_builder->raster_ids.ring)); raster_builder->raster_ids.extent[skc_extent_ring_wip_index_inc(&raster_builder->raster_ids.ring)] = raster; return skc_extent_ring_wip_is_full(&raster_builder->raster_ids.ring); } // // // static void skc_raster_builder_checkpoint(struct skc_raster_builder * const raster_builder) { skc_extent_ring_checkpoint(&raster_builder->path_ids .ring); skc_extent_ring_checkpoint(&raster_builder->transforms.ring); skc_extent_ring_checkpoint(&raster_builder->clips .ring); skc_extent_ring_checkpoint(&raster_builder->fill_cmds .ring); skc_extent_ring_checkpoint(&raster_builder->raster_ids.ring); } // // RASTER OPS // skc_err skc_raster_begin(skc_raster_builder_t raster_builder) { SKC_ASSERT_STATE_TRANSITION(SKC_RASTER_BUILDER_STATE_READY, SKC_RASTER_BUILDER_STATE_BUILDING, raster_builder); return SKC_ERR_SUCCESS; } skc_err skc_raster_end(skc_raster_builder_t raster_builder, skc_raster_t * raster) { SKC_ASSERT_STATE_TRANSITION(SKC_RASTER_BUILDER_STATE_BUILDING, SKC_RASTER_BUILDER_STATE_READY, raster_builder); // get a raster id raster_builder->end(raster_builder->impl,raster); // if cohort is full then launch skc_bool const snap = skc_raster_builder_raster_ids_append(raster_builder,*raster); // checkpoint the current ring range skc_raster_builder_checkpoint(raster_builder); // snapshot and force start because the cohort is full -- no need to wait if (snap) raster_builder->force(raster_builder->impl); // add guard bit *raster |= SKC_TYPED_HANDLE_TYPE_IS_RASTER; // FIXME -- the guard bit can be buried return SKC_ERR_SUCCESS; } // // PATH-TO-RASTER OPS // skc_err skc_raster_add_filled(skc_raster_builder_t raster_builder, skc_path_t path, skc_transform_weakref_t * transform_weakref, float const * transform, skc_raster_clip_weakref_t * raster_clip_weakref, float const * raster_clip) { SKC_ASSERT_STATE_ASSERT(SKC_RASTER_BUILDER_STATE_BUILDING,raster_builder); // // validate and retain the path handle before proceeding // skc_err err = raster_builder->add(raster_builder->impl,&path,1); if (err) return err; // mask off the guard bits path = SKC_TYPED_HANDLE_TO_HANDLE(path); // // build the command... // union skc_cmd_fill cmd; // append path to ring skc_bool snap = skc_raster_builder_path_ids_append(raster_builder,&cmd,path); // append transform snap = skc_raster_builder_transforms_append(raster_builder,&cmd,transform_weakref,transform) || snap; // append raster clip snap = skc_raster_builder_clips_append(raster_builder,&cmd,raster_clip_weakref,raster_clip) || snap; // append fill command snap = skc_raster_builder_cmds_append(raster_builder,&cmd) || snap; // snapshot and lazily start if (snap) raster_builder->start(raster_builder->impl); return SKC_ERR_SUCCESS; } // // //