Skia Compute core files

Bug: skia:
Change-Id: I4bba49cf20eff013e581800a3f114c85acd8498c
Reviewed-on: https://skia-review.googlesource.com/135782
Reviewed-by: Mike Klein <mtklein@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/src/compute/skc/raster_builder.c b/src/compute/skc/raster_builder.c
new file mode 100644
index 0000000..6da8071
--- /dev/null
+++ b/src/compute/skc/raster_builder.c
@@ -0,0 +1,321 @@
+/*
+ * 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 <stdlib.h>
+#include <memory.h>
+#include <float.h>
+
+#include "raster_builder.h"
+
+#include "context.h"
+#include "weakref.h"
+
+#include "scheduler.h"
+#include "handle.h"
+
+#include "common.h"
+
+//
+//
+//
+
+#ifndef NDEBUG
+
+#include <stdio.h>
+
+#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;
+}
+
+//
+//
+//