aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Allan MacKinnon <allanmac@google.com>2018-06-24 08:31:14 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-24 15:56:44 +0000
commitebf160f308b698c075c9c1cf8d65d40cb2486238 (patch)
tree5593af46661b4971275a606903b5a64cd7d694f7
parent5f0cc0e0665143d4d7b1a5ff06cf8df747068463 (diff)
Clean starting point for interop. VK will let us dodge this entirely.
Bug: skia: Change-Id: I4bc961e7e1b9ef30c5bfc096fb3f81af9191e750 Reviewed-on: https://skia-review.googlesource.com/136860 Commit-Queue: Allan MacKinnon <allanmac@google.com> Reviewed-by: Allan MacKinnon <allanmac@google.com>
-rw-r--r--src/compute/skc/context.c2
-rw-r--r--src/compute/skc/grid.c25
-rw-r--r--src/compute/skc/interop.h60
-rw-r--r--src/compute/skc/main.c234
-rw-r--r--src/compute/skc/platforms/cl_12/composition_cl_12.h2
-rw-r--r--src/compute/skc/platforms/cl_12/cq_pool_cl.c12
-rw-r--r--src/compute/skc/platforms/cl_12/gl/interop.c629
-rw-r--r--src/compute/skc/platforms/cl_12/gl/interop.h42
-rw-r--r--src/compute/skc/platforms/cl_12/interop/interop_glfw.c751
-rw-r--r--src/compute/skc/platforms/cl_12/kernels/devices/gen9/device_cl_12.c4
-rw-r--r--src/compute/skc/platforms/cl_12/runtime_cl_12.c74
-rw-r--r--src/compute/skc/platforms/cl_12/runtime_cl_12.h8
-rw-r--r--src/compute/skc/platforms/cl_12/skc_cl.h63
-rw-r--r--src/compute/skc/platforms/cl_12/styling_cl_12.c7
-rw-r--r--src/compute/skc/platforms/cl_12/surface_cl_12.c (renamed from src/compute/skc/platforms/cl_12/surface_cl_12_buffer.c)214
-rw-r--r--src/compute/skc/skc.h58
-rw-r--r--src/compute/skc/skc_create_cl.h70
-rw-r--r--src/compute/skc/skc_types.h37
-rw-r--r--src/compute/skc/surface.c54
-rw-r--r--src/compute/skc/surface.h32
20 files changed, 1230 insertions, 1148 deletions
diff --git a/src/compute/skc/context.c b/src/compute/skc/context.c
index 59c7956fd5..8066dc2b9b 100644
--- a/src/compute/skc/context.c
+++ b/src/compute/skc/context.c
@@ -28,7 +28,7 @@
//
skc_err
-skc_context_create_cl(skc_context_t * context,
+skc_context_create_cl(skc_context_t * context,
cl_context context_cl,
cl_device_id device_id_cl)
{
diff --git a/src/compute/skc/grid.c b/src/compute/skc/grid.c
index 934fa9f8bf..fb5a073a16 100644
--- a/src/compute/skc/grid.c
+++ b/src/compute/skc/grid.c
@@ -63,11 +63,11 @@
// For now and for simplicity, unify all grid ids in one set.
//
-typedef skc_uchar skc_grid_id_t; // 256 values
-#define SKC_GRID_ID_INVALID SKC_UCHAR_MAX // 255
+typedef skc_uchar skc_grid_id_t; // 256 values
+#define SKC_GRID_ID_INVALID SKC_UCHAR_MAX // 255
-#define SKC_GRID_SIZE_WORDS 8 // 256 bits
-#define SKC_GRID_SIZE_IDS ((32 * SKC_GRID_SIZE_WORDS) - 1) // 255 ids
+#define SKC_GRID_SIZE_IDS (SKC_GRID_ID_INVALID-1)
+#define SKC_GRID_SIZE_WORDS ((SKC_GRID_SIZE_IDS+31)/32)
//
//
@@ -315,8 +315,13 @@ skc_grid_deps_attach(skc_grid_deps_t const deps,
char const * const execute_name,
char const * const dispose_name)
{
+ //
// FIXME -- no more ids -- either fatal or flush & wait for grids to be released
- assert(deps->count < SKC_GRID_SIZE_IDS);
+ //
+ // assert(deps->count < SKC_GRID_SIZE_IDS);
+ //
+ while (deps->count == SKC_GRID_SIZE_IDS)
+ skc_scheduler_wait_one(deps->scheduler);
// otherwise, an id exists so decrement count
deps->count += 1;
@@ -404,7 +409,7 @@ void
skc_grid_detach(skc_grid_t const grid)
{
// for now make sure grid is complete
- // assert(*grid->state >= SKC_GRID_STATE_COMPLETE);
+ // assert(grid->state == SKC_GRID_STATE_COMPLETE);
// transition state
grid->state = SKC_GRID_STATE_DETACHED;
@@ -413,6 +418,7 @@ skc_grid_detach(skc_grid_t const grid)
// FIXME -- save profiling info
//
+ // cleanup
if (skc_grid_words_set(grid->deps->active,grid->id)) // 1:inactive
grid->deps->count -= 1;
}
@@ -445,7 +451,7 @@ skc_grid_deps_force(skc_grid_deps_t const deps,
{
skc_grid_id_t grid_id = handle_map[SKC_TYPED_HANDLE_TO_HANDLE(handles[ii])];
- if (grid_id != SKC_GRID_ID_INVALID)
+ if (grid_id < SKC_GRID_ID_INVALID)
{
skc_grid_t const grid = deps->grids + grid_id;
@@ -483,6 +489,7 @@ void
skc_grid_happens_after_grid(skc_grid_t const after,
skc_grid_t const before)
{
+ // declarations can't be made on non-ready grids
assert(after->state == SKC_GRID_STATE_READY);
if (before->state >= SKC_GRID_STATE_COMPLETE)
@@ -502,7 +509,7 @@ skc_grid_happens_after_handle(skc_grid_t const after, skc_handle_t const before)
skc_uint const id_before = after->deps->handle_map[before];
- if (id_before == SKC_GRID_ID_INVALID)
+ if (id_before >= SKC_GRID_ID_INVALID)
return;
if (skc_grid_words_set(after->before.words,id_before))
@@ -668,7 +675,7 @@ skc_grid_complete(skc_grid_t const grid)
if (idx == 32)
{
active = *after_words++;
- after += 1;
+ after += 32;
continue;
}
else // clear active
diff --git a/src/compute/skc/interop.h b/src/compute/skc/interop.h
new file mode 100644
index 0000000000..555f3c41c4
--- /dev/null
+++ b/src/compute/skc/interop.h
@@ -0,0 +1,60 @@
+/*
+ * 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.h"
+
+//
+//
+//
+
+struct skc_interop *
+skc_interop_create();
+
+void
+skc_interop_destroy(struct skc_interop * interop);
+
+cl_context_properties
+skc_interop_get_wgl_context();
+
+cl_context_properties
+skc_interop_get_wgl_dc();
+
+void
+skc_interop_set_cl_context(struct skc_interop * interop,
+ cl_context context_cl);
+
+bool
+skc_interop_poll(struct skc_interop * interop,
+ int * key);
+
+void
+skc_interop_transform(struct skc_interop * interop,
+ struct skc_transform_stack * ts);
+
+bool
+skc_interop_should_exit(struct skc_interop * interop);
+
+skc_framebuffer_t
+skc_interop_get_framebuffer();
+
+void
+skc_interop_blit(struct skc_interop * interop);
+
+void
+skc_interop_get_size(struct skc_interop * interop,
+ uint32_t * width,
+ uint32_t * height);
+//
+//
+//
diff --git a/src/compute/skc/main.c b/src/compute/skc/main.c
index e0d42b31e0..fe37324229 100644
--- a/src/compute/skc/main.c
+++ b/src/compute/skc/main.c
@@ -10,19 +10,10 @@
//
//
-#include <glad/glad.h>
-#include <GLFW/glfw3.h>
-
-//
-//
-//
-
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
-#include "skc_create_cl.h"
-
#include "common/cl/find_cl.h"
#include "common/cl/assert_cl.h"
@@ -34,35 +25,44 @@
//
//
-#include <CL/opencl.h>
-#include "platforms/cl_12/gl/interop.h"
+#include "platforms/cl_12/skc_cl.h"
+#include "interop.h"
//
//
//
-void
-skc_runtime_cl_12_debug(struct skc_context * const context);
+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,
- bool * quit)
+ skc_framebuffer_t fb,
+ void * data)
{
- *quit = true;
+ // 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);
//
//
@@ -83,8 +83,6 @@ main(int argc, char** argv)
//
// load test file
//
- // #include "test/lion.inl"
-
struct svg_doc * svg_doc = svg_doc_parse(argv[1],false);
fprintf(stderr,"p/r/l = %u / %u / %u\n",
@@ -95,9 +93,7 @@ main(int argc, char** argv)
//
// fire up GL
//
- GLFWwindow * window;
-
- skc_interop_init(&window);
+ struct skc_interop * interop = skc_interop_create();
//
// find platform and device by name
@@ -112,21 +108,19 @@ main(int argc, char** argv)
true));
//
- // get GL and device contexts
- //
- HGLRC hGLRC = wglGetCurrentContext();
- HDC hDC = wglGetCurrentDC();
-
- //
- // create the CL context
+ // 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, (cl_context_properties)hGLRC,
- CL_WGL_HDC_KHR, (cl_context_properties)hDC,
+ 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,
@@ -136,6 +130,11 @@ main(int argc, char** argv)
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;
@@ -145,11 +144,6 @@ main(int argc, char** argv)
device_id_cl);
//
- // associate
- //
- skc_interop_register(context);
-
- //
// create path builder
//
skc_path_builder_t path_builder;
@@ -199,76 +193,125 @@ main(int argc, char** argv)
//
// rasterize, render and reclaim svg until escape
//
- while (!glfwWindowShouldClose(window))
+ 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))
{
- // save stack
- uint32_t const ts_save = skc_transform_stack_save(ts);
+ // redefine the paths?
+ if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS)
+ {
+ // decode paths
+ paths = svg_doc_paths_decode(svg_doc,path_builder);
+ }
+
+ // rasterize the paths?
+ if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE)
+ {
+ // save stack
+ uint32_t const ts_save = skc_transform_stack_save(ts);
- // poll glfw
- skc_interop_poll(window,ts);
+ // update transform
+ skc_interop_transform(interop,ts);
- // decode paths
- skc_path_t * paths = svg_doc_paths_decode(svg_doc,path_builder);
+ // decode rasters
+ rasters = svg_doc_rasters_decode(svg_doc,ts,paths,raster_builder);
- // decode rasters
- skc_raster_t * rasters = svg_doc_rasters_decode(svg_doc,ts,paths,raster_builder);
+ // restore the transform stack
+ skc_transform_stack_restore(ts,ts_save);
+ }
- // restore the transform stack
- skc_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);
- // decode layers -- places rasters
- svg_doc_layers_decode(svg_doc,rasters,composition,styling,true/*is_srgb*/);
+ // unseal and reset the composition
+ skc_composition_unseal(composition,true);
- // seal the composition
- skc_composition_seal(composition);
+ // decode layers -- places rasters
+ svg_doc_layers_decode(svg_doc,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);
+ }
- bool quit = false;
uint32_t const clip[] = { 0, 0, 65535, 65535 }; // tile clip is <= 9 bits (512)
// render the styled composition to the surface
- skc_surface_render(surface,clip,styling,composition,
- is_render_complete,&quit,
- skc_interop_get_fb(window));
+ skc_surface_render(surface,
+ styling,
+ composition,
+ skc_interop_get_framebuffer(interop),
+ clip,
+ NULL,
+ NULL);
- // release the paths
- svg_doc_paths_release(svg_doc,paths,context);
+ //
+ // 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);
+
+ // 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
+ svg_doc_rewind(svg_doc);
+
+ if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_DEFINE_PATHS)
+ {
+ // release the paths
+ svg_doc_paths_release(svg_doc,paths,context);
+ }
+
+ if (pipeline_start_at_loop <= SKC_PIPELINE_START_AT_RASTERIZE)
+ {
+ // release the rasters
+ svg_doc_rasters_release(svg_doc,rasters,context);
+ }
+ }
+
+#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.
+ //
- // rasters have been released
- svg_doc_rasters_release(svg_doc,rasters,context);
+ //
+ // explicitly spin until framebuffer is rendered
+ //
+ bool quit = false;
- // spin until framebuffer is rendered
while (!quit) {
// fprintf(stderr,"WAITING ON: !quit\n");
skc_context_wait(context);
}
-
- // blit and swap
- skc_interop_blit(window);
-
- // print out some useful debug info
- skc_runtime_cl_12_debug(context);
-
- // rewind the doc
- svg_doc_rewind(svg_doc);
-
- //
- // I don't like this being here
- //
- float const rgba[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
- uint32_t rect[4] = { 0 };
-
- skc_interop_get_dim(rect+2);
-
- skc_surface_clear(surface,rgba,rect,
- skc_interop_get_fb(window));
-
- // exit(EXIT_SUCCESS);
-
- // reset styling
- skc_styling_reset(styling);
-
- // unseal the composition
- skc_composition_unseal(composition,true);
+#endif
}
//
@@ -287,10 +330,9 @@ main(int argc, char** argv)
err = skc_context_release(context);
//
- // GLFW CLEANUP
+ // dispose of GL interop
//
- glfwDestroyWindow(window);
- glfwTerminate();
+ skc_interop_destroy(interop);
//
//
diff --git a/src/compute/skc/platforms/cl_12/composition_cl_12.h b/src/compute/skc/platforms/cl_12/composition_cl_12.h
index 4f52090658..81a544fdee 100644
--- a/src/compute/skc/platforms/cl_12/composition_cl_12.h
+++ b/src/compute/skc/platforms/cl_12/composition_cl_12.h
@@ -47,8 +47,8 @@ struct skc_composition_impl
skc_int lock_count; // wip renders
struct {
- skc_grid_t sort;
skc_grid_t place;
+ skc_grid_t sort;
} grids;
cl_command_queue cq;
diff --git a/src/compute/skc/platforms/cl_12/cq_pool_cl.c b/src/compute/skc/platforms/cl_12/cq_pool_cl.c
index 8d1537dc40..2e37937b69 100644
--- a/src/compute/skc/platforms/cl_12/cq_pool_cl.c
+++ b/src/compute/skc/platforms/cl_12/cq_pool_cl.c
@@ -46,7 +46,7 @@ static
cl_command_queue
skc_runtime_cl_12_create_cq(struct skc_runtime * const runtime,
struct skc_cq_pool * const pool)
-
+
{
cl_command_queue cq;
@@ -59,7 +59,7 @@ skc_runtime_cl_12_create_cq(struct skc_runtime * const runtime,
cq = clCreateCommandQueue(runtime->cl.context,
runtime->cl.device_id,
pool->cq_props,
- &cl_err); cl_ok(cl_err);
+ &cl_err); cl_ok(cl_err);
#else
if (runtime_cl->version.major < 2)
{
@@ -71,7 +71,7 @@ skc_runtime_cl_12_create_cq(struct skc_runtime * const runtime,
cq = clCreateCommandQueue(runtime_cl->context,
runtime_cl->device_id,
(cl_command_queue_properties)type,
- &cl_err); cl_ok(cl_err);
+ &cl_err); cl_ok(cl_err);
}
else
{
@@ -135,7 +135,7 @@ skc_cq_pool_dispose(struct skc_runtime * const runtime,
//
//
-static
+static
void
skc_cq_pool_write(struct skc_cq_pool * const pool,
cl_command_queue cq)
@@ -174,7 +174,7 @@ skc_cq_pool_expand(struct skc_runtime * const runtime,
//
//
-static
+static
cl_command_queue
skc_cq_pool_read(struct skc_runtime * const runtime,
struct skc_cq_pool * const pool)
@@ -199,7 +199,7 @@ skc_runtime_acquire_cq_in_order(struct skc_runtime * const runtime)
}
void
-skc_runtime_release_cq_in_order(struct skc_runtime * const runtime,
+skc_runtime_release_cq_in_order(struct skc_runtime * const runtime,
cl_command_queue cq)
{
skc_cq_pool_write(&runtime->cq_pool,cq);
diff --git a/src/compute/skc/platforms/cl_12/gl/interop.c b/src/compute/skc/platforms/cl_12/gl/interop.c
deleted file mode 100644
index 6697bb7e83..0000000000
--- a/src/compute/skc/platforms/cl_12/gl/interop.c
+++ /dev/null
@@ -1,629 +0,0 @@
-/*
- * 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 <glad/glad.h>
-#include <glfw/glfw3.h>
-
-//
-//
-//
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <math.h>
-
-//
-//
-//
-
-#include "common/cl/assert_cl.h"
-#include "types.h"
-
-//
-//
-//
-
-#include "interop.h"
-#include "context.h"
-#include "runtime_cl_12.h"
-
-//
-//
-//
-
-#include "svg2skc/transform_stack.h"
-
-//
-//
-//
-
-#if 1
-#define SKC_IMAGE_FORMAT GL_RGBA8
-#else
-#define SKC_IMAGE_FORMAT GL_RGBA16F
-#endif
-
-//
-//
-//
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-//
-//
-//
-
-struct skc_interop_fb
-{
- cl_context context;
-
- GLuint fbo;
- GLuint rbo;
-
- cl_mem mem;
-
- int width;
- int height;
-
- bool is_srgb;
- bool is_vsync_on;
- bool is_fullscreen;
- bool is_iconified;
- bool is_resized;
- bool is_spinning;
- bool is_info;
-
- skc_float scale;
- skc_float2 translate;
- float rotate_theta;
-};
-
-static struct skc_interop_fb fb =
- {
- .mem = NULL,
-
- .is_srgb = true,
- .is_vsync_on = false,
- .is_fullscreen = false,
- .is_iconified = false,
- .is_resized = true,
- .is_spinning = false,
- .is_info = false,
-
- .scale = 1.0f,
- .translate = { 0.0f, 0.0f },
- .rotate_theta = 0.0f
- };
-
-//
-// FPS COUNTER FROM HERE:
-//
-// http://antongerdelan.net/opengl/glcontext2.html
-//
-
-static
-void
-skc_interop_fps(GLFWwindow * window)
-{
- if (fb.is_fullscreen)
- return;
-
- // static fps counters
- static double stamp_prev = 0.0;
- static int frame_count = 0;
-
- // locals
- double const stamp_curr = glfwGetTime();
- double const elapsed = stamp_curr - stamp_prev;
-
- if (elapsed >= 0.5)
- {
- stamp_prev = stamp_curr;
-
- double const fps = (double)frame_count / elapsed;
-
- char tmp[64];
-
- sprintf_s(tmp,64,"(%d x %d) - VSync %s - sRGB %s - FPS: %.2f",
- fb.width,fb.height,
- fb.is_vsync_on ? "ON" : "OFF",
- fb.is_srgb ? "ENABLED" : "DISABLED",
- fps);
-
- glfwSetWindowTitle(window,tmp);
-
- frame_count = 0;
- }
-
- frame_count++;
-}
-
-//
-// INITIALIZE GLFW/GLAD
-//
-
-static
-void
-skc_interop_error_callback(int error, char const * description)
-{
- fputs(description,stderr);
-}
-
-//
-//
-//
-
-static
-void
-skc_interop_iconify_callback(GLFWwindow * window, int iconified)
-{
- fb.is_iconified = iconified;
-}
-
-//
-//
-//
-
-static
-void
-skc_interop_key_callback(GLFWwindow * window, int key, int scancode, int action, int mods)
-{
- if (action == GLFW_RELEASE)
- return;
-
- switch (key)
- {
- case GLFW_KEY_EQUAL:
- fb.rotate_theta = 0.0f;
- break;
-
- case GLFW_KEY_I:
- fb.is_info = true;
- break;
-
- case GLFW_KEY_R:
- fb.is_spinning ^= true;
- break;
-
- case GLFW_KEY_S:
- fb.is_srgb ^= true;
- if (fb.is_srgb)
- glEnable(GL_FRAMEBUFFER_SRGB);
- else
- glDisable(GL_FRAMEBUFFER_SRGB);
- break;
-
- case GLFW_KEY_V:
- fb.is_vsync_on ^= true;
- glfwSwapInterval(fb.is_vsync_on ? 1 : 0);
- break;
-
- case GLFW_KEY_W:
- glfwSetWindowSize(window,1024,1024);
- break;
-
- case GLFW_KEY_ESCAPE:
- glfwSetWindowShouldClose(window,GL_TRUE);
- break;
- }
-}
-
-static
-void
-skc_interop_window_size_callback(GLFWwindow * window, int width, int height)
-{
- fb.width = width;
- fb.height = height;
- fb.is_resized = true;
-
-#if 0
- skc_render_kernel_set_clip(0,0,width,height);
-#endif
-}
-
-static
-void
-skc_interop_scale(double const scale_offset)
-{
-#define SKC_SCALE_FACTOR 1.05
-
- static double scale_exp = 0.0;
-
- scale_exp += scale_offset;
- fb.scale = (float)pow(SKC_SCALE_FACTOR,scale_exp);
-}
-
-static
-void
-skc_interop_scroll_callback(GLFWwindow * window, double xoffset, double yoffset)
-{
- bool const ctrl =
- (glfwGetKey(window,GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) ||
- (glfwGetKey(window,GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS);
-
- if (!ctrl)
- return;
-
- skc_interop_scale(yoffset);
-}
-
-static
-void
-skc_interop_translate(float const dx, float const dy)
-{
- float const dx_scaled = dx / fb.scale;
- float const dy_scaled = dy / fb.scale;
-
- float const cos_theta = cosf(fb.rotate_theta); // replace with cospi if available
- float const sin_theta = sinf(fb.rotate_theta); // replace with sinpi if available
-
- fb.translate.x += dx_scaled*cos_theta + dy_scaled*sin_theta;
- fb.translate.y += dy_scaled*cos_theta - dx_scaled*sin_theta;
-}
-
-static
-void
-skc_interop_cursor_position_callback(GLFWwindow * window, double x, double y)
-{
- int const state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT);
-
- static bool is_mouse_dragging = false;
- static float x_prev=0.0, y_prev=0.0;
-
- float const mx = (float)x;
- float const my = (float)y;
-
- if (state == GLFW_PRESS)
- {
- if (is_mouse_dragging)
- {
- const bool ctrl =
- (glfwGetKey(window,GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) ||
- (glfwGetKey(window,GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS);
-
- if (ctrl)
- {
- float const cx = 0.5f * fb.width;
- float const cy = 0.5f * fb.height;
-
- // find angle between mouse and center
- float const vx = x_prev - cx;
- float const vy = y_prev - cy;
-
- float const wx = mx - cx;
- float const wy = my - cy;
-
- float const len = sqrtf((vx*vx + vy*vy) * (wx*wx + wy*wy));
-
- if (len > 0.0f)
- {
- float const dot = vx*wx + vy*wy;
- float const da = acosf(dot / len);
-
- if (vx*wy - vy*wx >= 0.0f)
- fb.rotate_theta += da;
- else
- fb.rotate_theta -= da;
-
- fb.rotate_theta = fmodf(fb.rotate_theta,(float)(M_PI*2.0));
- }
- }
- else
- {
- skc_interop_translate(mx - x_prev,
- my - y_prev);
- }
- }
- else
- {
- is_mouse_dragging = true;
- }
-
- x_prev = mx;
- y_prev = my;
- }
- else
- {
- is_mouse_dragging = false;
- }
-}
-
-//
-//
-//
-
-static
-void
-skc_interop_resize()
-{
- fb.is_resized = false;
-
- // release the image2d
- if (fb.mem != NULL)
- cl(ReleaseMemObject(fb.mem));
-
- // resize rbo
- glNamedRenderbufferStorage(fb.rbo,
- SKC_IMAGE_FORMAT,
- fb.width,
- fb.height);
-
- // attach rbo to fbo
- glNamedFramebufferRenderbuffer(fb.fbo,
- GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER,
- fb.rbo);
- //
- //
- //
- cl_int cl_err;
-
- fb.mem = clCreateFromGLRenderbuffer(fb.context,
- CL_MEM_WRITE_ONLY,
- fb.rbo,
- &cl_err); cl_ok(cl_err);
- //
- // for debugging porpoises!
- //
- cl_image_format format;
-
- cl(GetImageInfo(fb.mem,
- CL_IMAGE_FORMAT,
- sizeof(format),
- &format,
- NULL));
-}
-
-//
-//
-//
-
-static
-void
-skc_interop_acquire()
-{
- // frame buffer object
- glCreateFramebuffers(1,&fb.fbo);
-
- // render buffer object w/a color buffer
- glCreateRenderbuffers(1,&fb.rbo);
-
- // size rbo
- glNamedRenderbufferStorage(fb.rbo,
- SKC_IMAGE_FORMAT,
- fb.width,
- fb.height);
-
- // attach rbo to fbo
- glNamedFramebufferRenderbuffer(fb.fbo,
- GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER,
- fb.rbo);
-}
-
-void
-skc_interop_register(skc_context_t context)
-{
- fb.context = context->runtime->cl.context;
-}
-
-//
-//
-//
-
-void
-skc_interop_init(GLFWwindow * * window)
-{
- //
- // INITIALIZE GLFW/GLAD
- //
- glfwSetErrorCallback(skc_interop_error_callback);
-
- if (!glfwInit())
- exit(EXIT_FAILURE);
-
- GLFWmonitor * const primary = glfwGetPrimaryMonitor();
- GLFWvidmode const * const mode = glfwGetVideoMode(primary);
-
- if (fb.is_fullscreen)
- {
- fb.width = mode->width;
- fb.height = mode->height;
- }
- else
- {
- fb.width = 1600;
- fb.height = 1024;
- }
-
- glfwWindowHint(GLFW_ALPHA_BITS, 0);
- glfwWindowHint(GLFW_DEPTH_BITS, 0);
- glfwWindowHint(GLFW_STENCIL_BITS, 0);
-
- glfwWindowHint(GLFW_SRGB_CAPABLE, GL_TRUE);
-
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
-
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-
- *window = glfwCreateWindow(fb.width,fb.height,
- "Skia Compute",
- fb.is_fullscreen ? primary : NULL,
- NULL);
-
- if (*window == NULL)
- {
- glfwTerminate();
- exit(EXIT_FAILURE);
- }
-
- glfwMakeContextCurrent(*window);
-
- // set up GLAD
- gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
-
- // ignore vsync for now
- glfwSwapInterval(fb.is_vsync_on ? 1 : 0);
-
- // only copy r/g/b
- glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
-
- // enable SRGB, disable scissor
- glEnable(GL_FRAMEBUFFER_SRGB);
- glDisable(GL_SCISSOR_TEST);
-
- //
- // SET USER POINTER AND CALLBACKS
- //
- glfwSetKeyCallback (*window,skc_interop_key_callback);
- glfwSetFramebufferSizeCallback(*window,skc_interop_window_size_callback);
- glfwSetScrollCallback (*window,skc_interop_scroll_callback);
- glfwSetCursorPosCallback (*window,skc_interop_cursor_position_callback);
- glfwSetWindowIconifyCallback (*window,skc_interop_iconify_callback);
-
- //
- //
- //
- fprintf(stderr,
- "GL_VENDOR : %s\n"
- "GL_RENDERER : %s\n",
- glGetString(GL_VENDOR),
- glGetString(GL_RENDERER));
-
- //
- // acquire an FBO/RBO
- //
- skc_interop_acquire();
-}
-
-//
-//
-//
-
-#define SKC_ROTATE_STEP ((float)(M_PI / 180.0))
-
-static
-void
-skc_interop_transform(struct skc_transform_stack * ts)
-{
- // OpenGL'ism
- skc_transform_stack_push_affine(ts,
- 1.0f, 0.0f,0.0f,
- 0.0f,-1.0f,(float)fb.height);
- // multiply
- skc_transform_stack_concat(ts);
-
- // spinner...
- if (fb.is_spinning)
- fb.rotate_theta = fmodf(fb.rotate_theta + SKC_ROTATE_STEP,(float)(M_PI*2.0));
-
- // always rotate and scale around surface center point
- skc_transform_stack_push_rotate_scale_xy(ts,
- fb.rotate_theta,
- fb.scale,fb.scale,
- 0.5f*fb.width,0.5f*fb.height);
- skc_transform_stack_concat(ts);
-
- // where did the mouse take us?
- skc_transform_stack_push_translate(ts,
- fb.translate.x,fb.translate.y);
- skc_transform_stack_concat(ts);
-}
-
-
-void
-skc_interop_poll(GLFWwindow * window,
- struct skc_transform_stack * ts)
-{
- // wait until uniconified
- while (fb.is_iconified)
- {
- glfwWaitEvents();
- continue;
- }
-
- // what's happended?
- glfwPollEvents();
-
- // resize?
- if (fb.is_resized)
- skc_interop_resize();
-
- // monitor fps
- skc_interop_fps(window);
-
- skc_interop_transform(ts);
-}
-
-//
-//
-//
-
-void
-skc_interop_blit(GLFWwindow * window)
-{
- // blit skc rbo
- glBlitNamedFramebuffer(fb.fbo,0,
- 0,0,fb.width,fb.height,
- 0,0,fb.width,fb.height,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
-#if 0
- //
- // FIXME -- this clear does nothing!
- //
- // As a hack we're clearing the interop'd RBO with a
- // clEnqueueFillImage().
- //
- float const rgba[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
- // GLenum const attachments[] = { GL_COLOR_ATTACHMENT0 };
- // glInvalidateNamedFramebufferData(fb.fbo,1,attachments);
- glClearNamedFramebufferfv(fb.fbo,GL_COLOR,0,rgba);
-#endif
-
- // swap buffers
- glfwSwapBuffers(window);
-}
-
-//
-//
-//
-
-void *
-skc_interop_get_fb(GLFWwindow * window)
-{
- glFlush();
-
- return fb.mem;
-}
-
-//
-//
-//
-
-void
-skc_interop_get_dim(uint32_t dim[2])
-{
- dim[0] = fb.width;
- dim[1] = fb.height;
-}
-
-//
-//
-//
-
-
diff --git a/src/compute/skc/platforms/cl_12/gl/interop.h b/src/compute/skc/platforms/cl_12/gl/interop.h
deleted file mode 100644
index 112d365764..0000000000
--- a/src/compute/skc/platforms/cl_12/gl/interop.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.h"
-
-//
-//
-//
-
-void
-skc_interop_init(GLFWwindow * * window);
-
-void
-skc_interop_register(skc_context_t context);
-
-void
-skc_interop_poll(GLFWwindow * window,
- struct skc_transform_stack * ts);
-
-void *
-skc_interop_get_fb(GLFWwindow * window);
-
-void
-skc_interop_get_dim(uint32_t dim[2]);
-
-void
-skc_interop_blit(GLFWwindow * window);
-
-//
-//
-//
diff --git a/src/compute/skc/platforms/cl_12/interop/interop_glfw.c b/src/compute/skc/platforms/cl_12/interop/interop_glfw.c
new file mode 100644
index 0000000000..a5c0bfcb57
--- /dev/null
+++ b/src/compute/skc/platforms/cl_12/interop/interop_glfw.c
@@ -0,0 +1,751 @@
+/*
+ * 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 <glad/glad.h>
+#include <glfw/glfw3.h>
+
+//
+//
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <math.h>
+
+//
+//
+//
+
+#include "common/cl/assert_cl.h"
+
+//
+//
+//
+
+#include "interop.h"
+
+//
+//
+//
+
+#include "skc_cl.h"
+#include "runtime_cl_12.h"
+
+//
+//
+//
+
+#include "svg2skc/transform_stack.h"
+
+//
+//
+//
+
+#if 1
+#define SKC_IMAGE_FORMAT GL_RGBA8
+#else
+#define SKC_IMAGE_FORMAT GL_RGBA16F
+#endif
+
+//
+//
+//
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+//
+//
+//
+
+struct skc_interop
+{
+ GLFWwindow * window;
+
+ cl_context context_cl;
+
+ GLuint fbo;
+ GLuint rbo;
+
+ struct skc_framebuffer_cl fb;
+
+ int width;
+ int height;
+
+ bool is_msecs;
+ bool is_srgb;
+ bool is_vsync_on;
+ bool is_fullscreen;
+ bool is_iconified;
+ bool is_resized;
+ bool is_spinning;
+ bool is_transform;
+
+ skc_float scale;
+ skc_float2 translate;
+ float rotate_theta;
+
+ int key;
+};
+
+//
+// INITIALIZE GLFW/GLAD
+//
+
+static
+void
+skc_interop_error_callback(int error, char const * description)
+{
+ fputs(description,stderr);
+}
+
+//
+//
+//
+
+static
+void
+skc_interop_iconify_callback(GLFWwindow * window, int iconified)
+{
+ struct skc_interop * interop = glfwGetWindowUserPointer(window);
+
+ interop->is_iconified = iconified;
+}
+
+//
+//
+//
+
+static
+void
+skc_interop_key_callback(GLFWwindow * window, int key, int scancode, int action, int mods)
+{
+ struct skc_interop * interop = glfwGetWindowUserPointer(window);
+
+ if (action == GLFW_RELEASE)
+ return;
+
+ switch (key)
+ {
+ case GLFW_KEY_EQUAL:
+ interop->rotate_theta = 0.0f;
+ interop->is_transform = true;
+ break;
+
+ case GLFW_KEY_M:
+ interop->is_msecs ^= true;
+ break;
+
+ case GLFW_KEY_R:
+ interop->is_spinning ^= true;
+ break;
+
+ case GLFW_KEY_S:
+ interop->is_srgb ^= true;
+ if (interop->is_srgb)
+ glEnable(GL_FRAMEBUFFER_SRGB);
+ else
+ glDisable(GL_FRAMEBUFFER_SRGB);
+ break;
+
+ case GLFW_KEY_V:
+ interop->is_vsync_on ^= true;
+ glfwSwapInterval(interop->is_vsync_on ? 1 : 0);
+ break;
+
+ case GLFW_KEY_W:
+ glfwSetWindowSize(window,1024,1024);
+ break;
+
+ case GLFW_KEY_ESCAPE:
+ glfwSetWindowShouldClose(window,GL_TRUE);
+ break;
+
+ default:
+ interop->key = key;
+ }
+}
+
+static
+void
+skc_interop_window_size_callback(GLFWwindow * window, int width, int height)
+{
+ struct skc_interop * interop = glfwGetWindowUserPointer(window);
+
+ interop->width = width;
+ interop->height = height;
+ interop->is_resized = true;
+ interop->is_transform = true;
+
+#if 0
+ skc_render_kernel_set_clip(0,0,width,height);
+#endif
+}
+
+static
+void
+skc_interop_scale(struct skc_interop * interop, double const scale_offset)
+{
+#define SKC_SCALE_FACTOR 1.05
+
+ static double scale_exp = 0.0;
+
+ scale_exp += scale_offset;
+
+ interop->scale = (float)pow(SKC_SCALE_FACTOR,scale_exp);
+}
+
+static
+void
+skc_interop_scroll_callback(GLFWwindow * window, double xoffset, double yoffset)
+{
+ bool const ctrl =
+ (glfwGetKey(window,GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) ||
+ (glfwGetKey(window,GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS);
+
+ if (!ctrl)
+ return;
+
+ struct skc_interop * interop = glfwGetWindowUserPointer(window);
+
+ skc_interop_scale(interop,yoffset);
+
+ interop->is_transform = true;
+}
+
+static
+void
+skc_interop_translate(struct skc_interop * interop, float const dx, float const dy)
+{
+ float const dx_scaled = dx / interop->scale;
+ float const dy_scaled = dy / interop->scale;
+
+ float const cos_theta = cosf(interop->rotate_theta); // replace with cospi if available
+ float const sin_theta = sinf(interop->rotate_theta); // replace with sinpi if available
+
+ interop->translate.x += dx_scaled*cos_theta + dy_scaled*sin_theta;
+ interop->translate.y += dy_scaled*cos_theta - dx_scaled*sin_theta;
+}
+
+static
+void
+skc_interop_cursor_position_callback(GLFWwindow * window, double x, double y)
+{
+
+ int const state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT);
+
+ static bool is_mouse_dragging = false;
+ static float x_prev=0.0, y_prev=0.0;
+
+ float const mx = (float)x;
+ float const my = (float)y;
+
+ if (state == GLFW_PRESS)
+ {
+ struct skc_interop * interop = glfwGetWindowUserPointer(window);
+
+ if (is_mouse_dragging)
+ {
+ const bool ctrl =
+ (glfwGetKey(window,GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) ||
+ (glfwGetKey(window,GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS);
+
+ if (ctrl)
+ {
+ float const cx = 0.5f * interop->width;
+ float const cy = 0.5f * interop->height;
+
+ // find angle between mouse and center
+ float const vx = x_prev - cx;
+ float const vy = y_prev - cy;
+
+ float const wx = mx - cx;
+ float const wy = my - cy;
+
+ float const len = sqrtf((vx*vx + vy*vy) * (wx*wx + wy*wy));
+
+ if (len > 0.0f)
+ {
+ float const dot = vx*wx + vy*wy;
+ float const da = acosf(dot / len);
+
+ if (vx*wy - vy*wx >= 0.0f)
+ interop->rotate_theta += da;
+ else
+ interop->rotate_theta -= da;
+
+ interop->rotate_theta = fmodf(interop->rotate_theta,(float)(M_PI*2.0));
+ }
+ }
+ else
+ {
+ skc_interop_translate(interop,
+ mx - x_prev,
+ my - y_prev);
+ }
+
+ interop->is_transform = true;
+ }
+ else
+ {
+ is_mouse_dragging = true;
+ }
+
+ x_prev = mx;
+ y_prev = my;
+ }
+ else
+ {
+ is_mouse_dragging = false;
+ }
+}
+
+//
+//
+//
+
+static
+void
+skc_interop_acquire(struct skc_interop * interop)
+{
+ // frame buffer object
+ glCreateFramebuffers(1,&interop->fbo);
+
+ // render buffer object w/a color buffer
+ glCreateRenderbuffers(1,&interop->rbo);
+
+ // size rbo
+ glNamedRenderbufferStorage(interop->rbo,
+ SKC_IMAGE_FORMAT,
+ interop->width,
+ interop->height);
+
+ // attach rbo to fbo
+ glNamedFramebufferRenderbuffer(interop->fbo,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ interop->rbo);
+}
+
+//
+//
+//
+
+struct skc_interop *
+skc_interop_create()
+{
+ struct skc_interop * interop = malloc(sizeof(*interop));
+
+ *interop = (struct skc_interop)
+ {
+ .fb = { .type = SKC_FRAMEBUFFER_CL_GL_RENDERBUFFER,
+ .mem = NULL,
+ .interop = interop,
+ .post_render = skc_interop_blit },
+
+ .is_msecs = true,
+ .is_srgb = true,
+ .is_vsync_on = false,
+ .is_fullscreen = false,
+ .is_iconified = false,
+ .is_resized = true,
+ .is_spinning = false,
+ .is_transform = true,
+
+ .scale = 1.0f,
+ .translate = { 0.0f, 0.0f },
+ .rotate_theta = 0.0f,
+
+ .key = 0
+ };
+
+ //
+ // INITIALIZE GLFW/GLAD
+ //
+ glfwSetErrorCallback(skc_interop_error_callback);
+
+ if (!glfwInit())
+ exit(EXIT_FAILURE);
+
+ GLFWmonitor * const primary = glfwGetPrimaryMonitor();
+ GLFWvidmode const * const mode = glfwGetVideoMode(primary);
+
+ if (interop->is_fullscreen)
+ {
+ interop->width = mode->width;
+ interop->height = mode->height;
+ }
+ else
+ {
+ interop->width = 1600;
+ interop->height = 1600;
+ }
+
+ glfwWindowHint(GLFW_ALPHA_BITS, 0);
+ glfwWindowHint(GLFW_DEPTH_BITS, 0);
+ glfwWindowHint(GLFW_STENCIL_BITS, 0);
+
+ glfwWindowHint(GLFW_SRGB_CAPABLE, GL_TRUE);
+
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
+
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+
+ interop->window = glfwCreateWindow(interop->width,
+ interop->height,
+ "Skia Compute",
+ interop->is_fullscreen ? primary : NULL,
+ NULL);
+
+ if (interop->window == NULL)
+ {
+ glfwTerminate();
+ exit(EXIT_FAILURE);
+ }
+
+ // save back pointer
+ glfwSetWindowUserPointer(interop->window,interop);
+
+ glfwMakeContextCurrent(interop->window);
+
+ // set up GLAD
+ gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
+
+ // ignore vsync for now
+ glfwSwapInterval(interop->is_vsync_on ? 1 : 0);
+
+ // only copy r/g/b
+ glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
+
+ // enable SRGB, disable scissor
+ glEnable(GL_FRAMEBUFFER_SRGB);
+ glDisable(GL_SCISSOR_TEST);
+
+ //
+ // SET USER POINTER AND CALLBACKS
+ //
+ glfwSetKeyCallback (interop->window,skc_interop_key_callback);
+ glfwSetFramebufferSizeCallback(interop->window,skc_interop_window_size_callback);
+ glfwSetScrollCallback (interop->window,skc_interop_scroll_callback);
+ glfwSetCursorPosCallback (interop->window,skc_interop_cursor_position_callback);
+ glfwSetWindowIconifyCallback (interop->window,skc_interop_iconify_callback);
+
+ //
+ //
+ //
+ fprintf(stderr,
+ "GL_VENDOR : %s\n"
+ "GL_RENDERER : %s\n",
+ glGetString(GL_VENDOR),
+ glGetString(GL_RENDERER));
+
+ //
+ // acquire an FBO/RBO
+ //
+ skc_interop_acquire(interop);
+
+ return interop;
+}
+
+//
+//
+//
+
+void
+skc_interop_destroy(struct skc_interop * interop)
+{
+ glfwDestroyWindow(interop->window);
+ glfwTerminate();
+
+ free(interop);
+}
+
+//
+//
+//
+
+void
+skc_interop_set_cl_context(struct skc_interop * interop,
+ cl_context context_cl)
+{
+ interop->context_cl = context_cl;
+}
+
+//
+//
+//
+
+cl_context_properties
+skc_interop_get_wgl_context()
+{
+ return (cl_context_properties)wglGetCurrentContext();
+}
+
+cl_context_properties
+skc_interop_get_wgl_dc()
+{
+ return (cl_context_properties)wglGetCurrentDC();
+}
+
+//
+//
+//
+
+#define SKC_ROTATE_STEP ((float)(M_PI / 180.0))
+
+void
+skc_interop_transform(struct skc_interop * interop,
+ struct skc_transform_stack * ts)
+{
+ // OpenGL'ism
+ skc_transform_stack_push_affine(ts,
+ 1.0f, 0.0f,0.0f,
+ 0.0f,-1.0f,(float)interop->height);
+ // multiply
+ skc_transform_stack_concat(ts);
+
+ // spinner...
+ if (interop->is_spinning)
+ interop->rotate_theta = fmodf(interop->rotate_theta + SKC_ROTATE_STEP,(float)(M_PI*2.0));
+
+ // always rotate and scale around surface center point
+ skc_transform_stack_push_rotate_scale_xy(ts,
+ interop->rotate_theta,
+ interop->scale,
+ interop->scale,
+ 0.5f*interop->width,
+ 0.5f*interop->height);
+ skc_transform_stack_concat(ts);
+
+ // where did the mouse take us?
+ skc_transform_stack_push_translate(ts,
+ interop->translate.x,
+ interop->translate.y);
+ skc_transform_stack_concat(ts);
+}
+
+//
+//
+//
+
+static
+void
+skc_interop_resize(struct skc_interop * interop)
+{
+ interop->is_resized = false;
+
+ // release the image2d
+ if (interop->fb.mem != NULL)
+ cl(ReleaseMemObject(interop->fb.mem));
+
+ // resize rbo
+ glNamedRenderbufferStorage(interop->rbo,
+ SKC_IMAGE_FORMAT,
+ interop->width,
+ interop->height);
+
+ // attach rbo to fbo
+ glNamedFramebufferRenderbuffer(interop->fbo,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ interop->rbo);
+ //
+ //
+ //
+ cl_int cl_err;
+
+ interop->fb.mem = clCreateFromGLRenderbuffer(interop->context_cl,
+ CL_MEM_WRITE_ONLY,
+ interop->rbo,
+ &cl_err); cl_ok(cl_err);
+ //
+ // for debugging porpoises!
+ //
+#if 0
+ cl_image_format format;
+
+ cl(GetImageInfo(interop->fb.mem,
+ CL_IMAGE_FORMAT,
+ sizeof(format),
+ &format,
+ NULL));
+#endif
+}
+
+//
+// FPS COUNTER FROM HERE:
+//
+// http://antongerdelan.net/opengl/glcontext2.html
+//
+
+static
+void
+skc_interop_fps(struct skc_interop * interop)
+{
+ if (interop->is_fullscreen)
+ return;
+
+ // static fps counters
+ static double stamp_prev = 0.0;
+ static int frame_count = 0;
+
+ // locals
+ double const stamp_curr = glfwGetTime();
+ double const elapsed = stamp_curr - stamp_prev;
+
+ if (elapsed >= 0.5)
+ {
+ stamp_prev = stamp_curr;
+
+ char tmp[64];
+
+ if (interop->is_msecs)
+ {
+ double const msecs = min(elapsed * 1000 / frame_count,9999.9);
+
+ sprintf_s(tmp,64,"%5.1f MSECS - (%d x %d) - VSync %s - sRGB %s",
+ msecs,
+ interop->width,interop->height,
+ interop->is_vsync_on ? "ON" : "OFF",
+ interop->is_srgb ? "ENABLED" : "DISABLED");
+ }
+ else
+ {
+ double const fps = min((double)frame_count / elapsed,9999.9);
+
+ sprintf_s(tmp,64,"%5.1f FPS - (%d x %d) - VSync %s - sRGB %s",
+ fps,
+ interop->width,interop->height,
+ interop->is_vsync_on ? "ON" : "OFF",
+ interop->is_srgb ? "ENABLED" : "DISABLED");
+ }
+
+ glfwSetWindowTitle(interop->window,tmp);
+
+ frame_count = 0;
+ }
+
+ frame_count++;
+}
+
+//
+//
+//
+
+bool
+skc_interop_poll(struct skc_interop * interop, int * key)
+{
+ // wait until uniconified
+ while (interop->is_iconified)
+ {
+ glfwWaitEvents();
+ continue;
+ }
+
+ // what's happended?
+ glfwPollEvents();
+
+ // resize?
+ if (interop->is_resized)
+ skc_interop_resize(interop);
+
+ // monitor fps
+ skc_interop_fps(interop);
+
+ if (key != NULL)
+ {
+ *key = interop->key;
+ interop->key = 0;
+ }
+
+ bool const is_transform = interop->is_transform || interop->is_spinning;
+
+ interop->is_transform = false;
+
+ return is_transform;
+}
+
+//
+//
+//
+
+void
+skc_interop_blit(struct skc_interop * interop)
+{
+ // blit skc rbo
+ glBlitNamedFramebuffer(interop->fbo,0,
+ 0,0,interop->width,interop->height,
+ 0,0,interop->width,interop->height,
+ GL_COLOR_BUFFER_BIT,
+ GL_NEAREST);
+
+ // swap buffers
+ glfwSwapBuffers(interop->window);
+
+#if 0
+ //
+ // FIXME -- this clear does nothing!
+ //
+ // As a hack we're clearing the interop'd RBO with a
+ // clEnqueueFillImage().
+ //
+ GLenum const attachments[] = { GL_COLOR_ATTACHMENT0 };
+ glInvalidateNamedFramebufferData(interop->fbo,1,attachments);
+ float const rgba[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ glClearNamedFramebufferfv(interop->fbo,GL_COLOR,0,rgba);
+#endif
+}
+
+//
+//
+//
+
+skc_framebuffer_t
+skc_interop_get_framebuffer(struct skc_interop * interop)
+{
+ // glFlush();
+ glFinish();
+
+ return &interop->fb;
+}
+
+//
+//
+//
+
+bool
+skc_interop_should_exit(struct skc_interop * interop)
+{
+ return glfwWindowShouldClose(interop->window);
+}
+
+//
+//
+//
+
+void
+skc_interop_get_size(struct skc_interop * interop,
+ uint32_t * width,
+ uint32_t * height)
+{
+ *width = interop->width;
+ *height = interop->height;
+}
+
+//
+//
+//
+
+
diff --git a/src/compute/skc/platforms/cl_12/kernels/devices/gen9/device_cl_12.c b/src/compute/skc/platforms/cl_12/kernels/devices/gen9/device_cl_12.c
index f7e06a1062..d7f10e38bf 100644
--- a/src/compute/skc/platforms/cl_12/kernels/devices/gen9/device_cl_12.c
+++ b/src/compute/skc/platforms/cl_12/kernels/devices/gen9/device_cl_12.c
@@ -87,6 +87,8 @@
//
// FIXME -- THE CONFIG INITIALIZATION IS ONLY HERE TEMPORARILY
//
+// FIXME -- move these to log2 values where appropriate
+//
static
struct skc_config const config =
@@ -103,7 +105,7 @@ struct skc_config const config =
},
.scheduler = {
- .size = 4096 // 128 // fixme -- this is just for testing -- too big
+ .size = 4096 // 128 // FIXME -- this is just for testing -- way too big -- schedulees should bring their own state
},
.subblock = {
diff --git a/src/compute/skc/platforms/cl_12/runtime_cl_12.c b/src/compute/skc/platforms/cl_12/runtime_cl_12.c
index a4a578fa29..81e1e8569e 100644
--- a/src/compute/skc/platforms/cl_12/runtime_cl_12.c
+++ b/src/compute/skc/platforms/cl_12/runtime_cl_12.c
@@ -31,7 +31,7 @@
//
//
-static
+static
void
skc_block_pool_create(struct skc_runtime * const runtime, cl_command_queue cq)
{
@@ -41,7 +41,7 @@ skc_block_pool_create(struct skc_runtime * const runtime, cl_command_queue cq)
// create block extent
skc_extent_pdrw_alloc(runtime,
&runtime->block_pool.blocks,
- runtime->block_pool.size->pool_size *
+ runtime->block_pool.size->pool_size *
runtime->config->block.bytes);
// allocate block pool ids
@@ -84,7 +84,7 @@ skc_block_pool_create(struct skc_runtime * const runtime, cl_command_queue cq)
cl(ReleaseKernel(k1));
}
-static
+static
void
skc_block_pool_dispose(struct skc_runtime * const runtime)
{
@@ -105,7 +105,7 @@ skc_runtime_yield(struct skc_runtime * const runtime)
}
static
-void
+void
skc_runtime_wait(struct skc_runtime * const runtime)
{
skc_scheduler_wait(runtime->scheduler);
@@ -122,7 +122,7 @@ skc_runtime_cl_12_create(struct skc_context * const context,
{
// allocate the runtime
struct skc_runtime * const runtime = malloc(sizeof(*runtime));
-
+
// save off CL objects
runtime->cl.context = context_cl;
runtime->cl.device_id = device_id_cl;
@@ -135,7 +135,7 @@ skc_runtime_cl_12_create(struct skc_context * const context,
sizeof(align_bits),
&align_bits,
NULL));
-
+
runtime->cl.align_bytes = align_bits / 8;
// create device
@@ -183,7 +183,7 @@ skc_runtime_cl_12_create(struct skc_context * const context,
context->yield = skc_runtime_yield;
context->wait = skc_runtime_wait;
-
+
context->path_builder = skc_path_builder_cl_12_create;
context->path_retain = skc_runtime_path_host_retain;
context->path_release = skc_runtime_path_host_release;
@@ -196,7 +196,7 @@ skc_runtime_cl_12_create(struct skc_context * const context,
context->composition = skc_composition_cl_12_create;
context->styling = skc_styling_cl_12_create;
-
+
context->surface = skc_surface_cl_12_create;
// block on pool creation
@@ -234,48 +234,19 @@ skc_runtime_cl_12_dispose(struct skc_context * const context)
skc_block_pool_dispose(context->runtime);
// skc_handle_pool_dispose(context->runtime);
-
+
return SKC_ERR_SUCCESS;
}
//
-// TEMPORARY BENCHMARK
+// REPORT BLOCK POOL ALLOCATION
//
-#if 1
-
-#include <windows.h>
-
-#define SKC_FRAMES_MASK 0x7F
-#define SKC_FRAMES (SKC_FRAMES_MASK + 1)
-
void
skc_runtime_cl_12_debug(struct skc_context * const context)
{
-#ifdef NDEBUG
- static skc_uint frames=0;
- static LARGE_INTEGER StartingTime={0}, EndingTime;
-
- if ((frames++ & SKC_FRAMES_MASK) != SKC_FRAMES_MASK)
- return;
-
- QueryPerformanceCounter(&EndingTime);
-
- LARGE_INTEGER ElapsedMicroseconds, Frequency;
-
- ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
-
- QueryPerformanceFrequency(&Frequency);
-
- double const msecs_total = 1000.0 * ElapsedMicroseconds.QuadPart / Frequency.QuadPart;
- double const msecs_frame = msecs_total / SKC_FRAMES;
-
- printf("Frames / Total / Per : %u / %.3f / %.3f\n",
- SKC_FRAMES,msecs_total,msecs_frame);
-#endif
-
struct skc_runtime * const runtime = context->runtime;
-
+
// acquire out-of-order cq
cl_command_queue cq = skc_runtime_acquire_cq_in_order(runtime);
@@ -293,28 +264,17 @@ skc_runtime_cl_12_debug(struct skc_context * const context)
skc_uint const available = bp_atomic->writes - bp_atomic->reads;
skc_uint const inuse = runtime->config->block_pool.pool_size - available;
- fprintf(stderr,"w/r/f/a: %9u - %9u = %9u : %6.2f MB\n",
+ fprintf(stderr,
+ "writes/reads/avail/alloc: %9u / %9u / %9u = %6.2f MB / %9u = %6.2f MB\n",
bp_atomic->writes,
bp_atomic->reads,
available,
- (inuse * runtime->config->block.bytes) / (1024.0*1024.0));
-
- if (available >= (1<<27))
- {
- fprintf(stderr,"block pool corrupted!\n");
- exit(-1);
- }
-
- //
- //
- //
-#ifdef NDEBUG
- QueryPerformanceCounter(&StartingTime);
-#endif
+ (available * runtime->config->block.bytes) / (1024.0*1024.0),
+ inuse,
+ (inuse * runtime->config->block.bytes) / (1024.0*1024.0));
}
-#endif
-
//
//
//
+
diff --git a/src/compute/skc/platforms/cl_12/runtime_cl_12.h b/src/compute/skc/platforms/cl_12/runtime_cl_12.h
index ff820e6872..beb924f3ca 100644
--- a/src/compute/skc/platforms/cl_12/runtime_cl_12.h
+++ b/src/compute/skc/platforms/cl_12/runtime_cl_12.h
@@ -178,3 +178,11 @@ skc_runtime_device_temp_free(struct skc_runtime * const runtime,
//
//
//
+
+void
+skc_runtime_cl_12_debug(struct skc_context * const context);
+
+//
+//
+//
+
diff --git a/src/compute/skc/platforms/cl_12/skc_cl.h b/src/compute/skc/platforms/cl_12/skc_cl.h
new file mode 100644
index 0000000000..41ca40280a
--- /dev/null
+++ b/src/compute/skc/platforms/cl_12/skc_cl.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can
+ * be found in the LICENSE file.
+ *
+ */
+
+#ifndef SKC_ONCE_SKC_CREATE_CL
+#define SKC_ONCE_SKC_CREATE_CL
+
+//
+//
+//
+
+#ifdef __APPLE__
+#include "OpenCL/opencl.h"
+#else
+#include "CL/opencl.h"
+#endif
+
+//
+//
+//
+
+#include "skc.h"
+
+//
+// CONTEXT CREATION
+//
+
+skc_err
+skc_context_create_cl(skc_context_t * context,
+ cl_context context_cl,
+ cl_device_id device_id_cl);
+
+//
+// SURFACE RENDER FRAMEBUFFER TYPES
+//
+
+typedef enum skc_framebuffer_cl_mem_type {
+ SKC_FRAMEBUFFER_CL_IMAGE2D,
+ SKC_FRAMEBUFFER_CL_GL_RENDERBUFFER,
+ SKC_FRAMEBUFFER_CL_GL_TEXTURE
+} skc_framebuffer_cl_mem_type;
+
+struct skc_framebuffer_cl
+{
+ skc_framebuffer_cl_mem_type type;
+ cl_mem mem;
+ struct skc_interop * interop;
+ void (* post_render)(struct skc_interop * interop);
+};
+
+//
+//
+//
+
+#endif
+
+//
+//
+//
diff --git a/src/compute/skc/platforms/cl_12/styling_cl_12.c b/src/compute/skc/platforms/cl_12/styling_cl_12.c
index 6c84fe6f70..8d8d90525d 100644
--- a/src/compute/skc/platforms/cl_12/styling_cl_12.c
+++ b/src/compute/skc/platforms/cl_12/styling_cl_12.c
@@ -212,7 +212,12 @@ skc_styling_pfn_release(struct skc_styling_impl * const impl)
return;
//
- // otherwise, unmap all resources by sealing and delete
+ // otherwise, unmap all resources
+ //
+
+ //
+ // FIXME -- is it pointless unmap before freeing? The seal
+ // accomplishes the unmapping.
//
skc_styling_pfn_seal(impl);
diff --git a/src/compute/skc/platforms/cl_12/surface_cl_12_buffer.c b/src/compute/skc/platforms/cl_12/surface_cl_12.c
index cc7cba5225..24a0c45f3c 100644
--- a/src/compute/skc/platforms/cl_12/surface_cl_12_buffer.c
+++ b/src/compute/skc/platforms/cl_12/surface_cl_12.c
@@ -12,6 +12,8 @@
#include "common/cl/assert_cl.h"
+#include "skc_cl.h"
+#include "interop.h"
#include "extent_cl_12.h"
#include "runtime_cl_12.h"
#include "styling_cl_12.h"
@@ -32,32 +34,23 @@
struct skc_surface_impl
{
- struct skc_surface * surface;
- struct skc_runtime * runtime;
+ struct skc_surface * surface;
+ struct skc_runtime * runtime;
// framebuffer
// struct skc_extent_pdrw fb;
// struct skc_extent_phrN_pdwN fb;
// for now, a single in-order command queue
- cl_command_queue cq;
+ cl_command_queue cq;
struct {
- cl_kernel render;
+ cl_kernel render;
} kernels;
};
//
-// we might want concurrent access to the same surface as long as
-// the clips don't overlap.
//
-// this would require acquiring a cq on demand when it is determined
-// that the clipped render won't overlap
-//
-// { tile clip , cq } pair
-//
-// skc_uint4 clip;
-// cl_command_queue cq
//
struct skc_surface_render
@@ -68,10 +61,10 @@ struct skc_surface_render
struct skc_styling * styling;
struct skc_composition * composition;
- skc_surface_render_pfn_notify notify;
- void * data;
+ struct skc_framebuffer_cl * fb;
- cl_mem fb;
+ skc_surface_render_notify notify;
+ void * data;
skc_grid_t grid;
@@ -79,21 +72,22 @@ struct skc_surface_render
};
//
-//
+// FIXME -- we only need this because (I think) RBO<>CL interop
+// results in glClear() on the FBO not working...
//
static
void
-skc_surface_pfn_clear(struct skc_surface_impl * const impl,
- float const rgba[4],
- skc_uint const rect[4],
- void * fb)
+skc_surface_debug_clear(struct skc_surface_impl * const impl,
+ skc_framebuffer_t fb,
+ float const rgba[4],
+ uint32_t const rect[4])
{
size_t const origin[3] = { rect[0], rect[1], 0 };
size_t const region[3] = { rect[2], rect[3], 1 };
cl(EnqueueFillImage(impl->cq,
- (cl_mem)fb,
+ ((struct skc_framebuffer_cl *)fb)->mem,
rgba,
origin,
region,
@@ -104,27 +98,7 @@ skc_surface_pfn_clear(struct skc_surface_impl * const impl,
//
//
-static
-void
-skc_surface_pfn_blit(struct skc_surface_impl * const impl,
- skc_uint const rect[4],
- skc_int const txty[2])
-{
- ;
-}
-
-//
-//
-//
-
#if 0 // #ifndef NDEBUG
-#define SKC_SURFACE_DEBUG
-#endif
-
-#ifdef SKC_SURFACE_DEBUG
-
-#define SKC_SURFACE_WIDTH 4096
-#define SKC_SURFACE_HEIGHT 4096
static
void
@@ -166,6 +140,42 @@ skc_surface_debug(struct skc_surface_impl * const impl)
//
//
+static
+void
+skc_surface_pfn_release(struct skc_surface_impl * const impl)
+{
+ if (--impl->surface->ref_count != 0)
+ return;
+
+ //
+ // otherwise, release all resources
+ //
+
+ // drain the command queue
+ cl(Finish(impl->cq));
+
+ struct skc_runtime * const runtime = impl->runtime;
+
+ // release the kernel
+ cl(ReleaseKernel(impl->kernels.render));
+
+ // free surface host
+ skc_runtime_host_perm_free(runtime,impl->surface);
+
+ // release the cq
+ skc_runtime_release_cq_in_order(runtime,impl->cq);
+
+ // release fb
+ // skc_extent_phrN_pdwN_free(runtime,&impl->fb);
+
+ // free surface impl
+ skc_runtime_host_perm_free(runtime,impl);
+}
+
+//
+//
+//
+
void
skc_surface_render_complete(struct skc_surface_render * const render)
{
@@ -179,6 +189,7 @@ skc_surface_render_complete(struct skc_surface_render * const render)
render->notify(render->impl->surface,
render->styling,
render->composition,
+ render->fb,
render->data);
}
@@ -188,6 +199,15 @@ skc_surface_render_complete(struct skc_surface_render * const render)
// grid is now complete
skc_grid_complete(render->grid);
+
+ struct skc_surface_impl * const impl = render->impl;
+ struct skc_runtime * const runtime = impl->runtime;
+
+ // release the surface
+ skc_surface_pfn_release(impl);
+
+ // free the render object
+ skc_runtime_host_temp_free(runtime,render,render->id);
}
static
@@ -220,8 +240,9 @@ skc_surface_grid_pfn_execute(skc_grid_t const grid)
if (atomics->offsets > 0)
{
- // acquire the rbo
- cl(EnqueueAcquireGLObjects(impl->cq,1,&render->fb,0,NULL,NULL));
+ // acquire the rbo/tex
+ if (render->fb->type != SKC_FRAMEBUFFER_CL_IMAGE2D)
+ cl(EnqueueAcquireGLObjects(impl->cq,1,&render->fb->mem,0,NULL,NULL));
// get the styling args
struct skc_styling_impl * const si = render->styling->impl;
@@ -239,7 +260,7 @@ skc_surface_grid_pfn_execute(skc_grid_t const grid)
cl(SetKernelArg(impl->kernels.render,7,SKC_CL_ARG(impl->runtime->block_pool.blocks.drw)));
// surface
- cl(SetKernelArg(impl->kernels.render,8,SKC_CL_ARG(render->fb)));
+ cl(SetKernelArg(impl->kernels.render,8,SKC_CL_ARG(render->fb->mem)));
#if 1
// tile clip
@@ -264,7 +285,25 @@ skc_surface_grid_pfn_execute(skc_grid_t const grid)
cl_event complete;
// give the rbo back
- cl(EnqueueReleaseGLObjects(impl->cq,1,&render->fb,0,NULL,&complete));
+ if (render->fb->type != SKC_FRAMEBUFFER_CL_IMAGE2D)
+ {
+ cl(EnqueueReleaseGLObjects(impl->cq,1,&render->fb->mem,0,NULL,&complete));
+
+ //
+ // blit the rbo to fbo0
+ //
+ render->fb->post_render(render->fb->interop);
+
+ //
+ // clear the rbo -- FIXME -- we shouldn't have to do this here
+ //
+ float const rgba[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ uint32_t rect[4] = { 0 };
+
+ skc_interop_get_size(render->fb->interop,rect+2,rect+3);
+
+ skc_surface_debug_clear(impl,render->fb,rgba,rect);
+ }
// notify anyone listening...
cl(SetEventCallback(complete,CL_COMPLETE,skc_surface_render_cb,render));
@@ -285,68 +324,13 @@ skc_surface_grid_pfn_execute(skc_grid_t const grid)
static
void
-skc_surface_pfn_release(struct skc_surface_impl * const impl)
-{
- if (--impl->surface->ref_count != 0)
- return;
-
- //
- // otherwise, release all resources
- //
-
- // drain the command queue
- cl(Finish(impl->cq));
-
- struct skc_runtime * const runtime = impl->runtime;
-
- // release the kernel
- cl(ReleaseKernel(impl->kernels.render));
-
- // free surface host
- skc_runtime_host_perm_free(runtime,impl->surface);
-
- // release the cq
- skc_runtime_release_cq_in_order(runtime,impl->cq);
-
- // release fb
- // skc_extent_phrN_pdwN_free(runtime,&impl->fb);
-
- // free surface impl
- skc_runtime_host_perm_free(runtime,impl);
-}
-
-//
-//
-//
-
-static
-void
-skc_surface_grid_pfn_dispose(skc_grid_t const grid)
-{
- struct skc_surface_render * const render = skc_grid_get_data(grid);
- struct skc_surface_impl * const impl = render->impl;
- struct skc_runtime * const runtime = impl->runtime;
-
- // free the render object
- skc_runtime_host_temp_free(runtime,render,render->id);
-
- // release the surface
- skc_surface_pfn_release(impl);
-}
-
-//
-//
-//
-
-static
-void
skc_surface_pfn_render(struct skc_surface_impl * const impl,
- uint32_t const clip[4],
skc_styling_t styling,
skc_composition_t composition,
- skc_surface_render_pfn_notify notify,
- void * data,
- void * fb)
+ skc_framebuffer_t fb,
+ uint32_t const clip[4],
+ skc_surface_render_notify notify,
+ void * data)
{
// retain surface
skc_surface_retain(impl->surface);
@@ -387,15 +371,21 @@ skc_surface_pfn_render(struct skc_surface_impl * const impl,
render->grid = SKC_GRID_DEPS_ATTACH(impl->runtime->deps,
NULL, // invalidation not necessary
render,
- NULL, // no waiting
+ NULL, // no waiting
skc_surface_grid_pfn_execute,
- skc_surface_grid_pfn_dispose);
-
+ NULL); // no disposal
+ //
// declare happens-after relationships
- skc_grid_happens_after_grid(render->grid,styling->impl->grid);
- skc_grid_happens_after_grid(render->grid,composition->impl->grids.sort);
+ //
+ if (styling->impl->state != SKC_STYLING_STATE_SEALED)
+ skc_grid_happens_after_grid(render->grid,styling->impl->grid);
- // wait for styling and composition
+ if (composition->impl->state != SKC_COMPOSITION_STATE_SEALED)
+ skc_grid_happens_after_grid(render->grid,composition->impl->grids.sort);
+
+ //
+ // start render but possibly wait for styling and composition
+ //
skc_grid_start(render->grid);
}
@@ -423,8 +413,6 @@ skc_surface_cl_12_create(struct skc_context * const context,
(*surface)->ref_count = 1;
(*surface)->release = skc_surface_pfn_release;
- (*surface)->clear = skc_surface_pfn_clear;
- (*surface)->blit = skc_surface_pfn_blit;
(*surface)->render = skc_surface_pfn_render;
// intialize impl
diff --git a/src/compute/skc/skc.h b/src/compute/skc/skc.h
index a81a5346b7..a5e81fb2ff 100644
--- a/src/compute/skc/skc.h
+++ b/src/compute/skc/skc.h
@@ -248,7 +248,7 @@ skc_err
skc_styling_group_leave(skc_styling_t styling,
skc_group_id group_id,
uint32_t n,
- skc_styling_cmd_t const * cmds);
+ skc_styling_cmd_t const * cmds);
skc_err
skc_styling_group_parents(skc_styling_t styling,
@@ -271,7 +271,7 @@ skc_styling_group_layer(skc_styling_t styling,
skc_group_id group_id,
skc_layer_id layer_id,
uint32_t n,
- skc_styling_cmd_t const * cmds);
+ skc_styling_cmd_t const * cmds);
//
// STYLING ENCODERS -- FIXME -- WILL EVENTUALLY BE OPAQUE
@@ -298,13 +298,6 @@ skc_styling_layer_fill_gradient_encoder(skc_styling_cmd_t * cmds,
// SURFACE
//
-//
-// FIXME - surface create needs to be able to specify different
-// surface targets here that are a function of the surface type and
-// rendering model: CL/global, GL/buffer, simple SRCOVER model,
-// complex group-based PDF rendering model, etc.
-//
-
skc_err
skc_surface_create(skc_context_t context, skc_surface_t * surface);
@@ -314,44 +307,24 @@ skc_surface_retain(skc_surface_t surface);
skc_err
skc_surface_release(skc_surface_t surface);
-// skc_interop_surface_t
-// skc_surface_interop_surface_get(skc_surface_t surface);
-
-//
-// NO NO NO -- SKC will always be a client of some other platform so
-// handle things like blits and clears there unless it's something
-// unique like an SKC tile-based clear/blit.
-//
-// (temporarily implement these for testing porpoises)
-//
-
-skc_err
-skc_surface_clear(skc_surface_t surface,
- float const rgba[4],
- uint32_t const rect[4],
- void * fb);
-
-skc_err
-skc_surface_blit(skc_surface_t surface,
- uint32_t const rect[4],
- int32_t const txty[2]);
-
//
// SURFACE RENDER
//
-typedef void (*skc_surface_render_pfn_notify)(skc_surface_t surface,
- skc_styling_t styling,
- skc_composition_t composition,
- void * data);
+typedef void (*skc_surface_render_notify)(skc_surface_t surface,
+ skc_styling_t styling,
+ skc_composition_t composition,
+ skc_framebuffer_t fb,
+ void * data);
+
skc_err
-skc_surface_render(skc_surface_t surface,
- uint32_t const clip[4],
- skc_styling_t styling,
- skc_composition_t composition,
- skc_surface_render_pfn_notify notify,
- void * data,
- void * fb); // FIXME FIXME
+skc_surface_render(skc_surface_t surface,
+ skc_styling_t styling,
+ skc_composition_t composition,
+ skc_framebuffer_t fb,
+ uint32_t const clip[4],
+ skc_surface_render_notify notify,
+ void * data);
//
// COORDINATED EXTERNAL OPERATIONS
@@ -387,4 +360,3 @@ skc_context_wait(skc_context_t context);
//
//
//
-
diff --git a/src/compute/skc/skc_create_cl.h b/src/compute/skc/skc_create_cl.h
deleted file mode 100644
index 0ab0fe0cb9..0000000000
--- a/src/compute/skc/skc_create_cl.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can
- * be found in the LICENSE file.
- *
- */
-
-#ifndef SKC_ONCE_SKC_CREATE_CL
-#define SKC_ONCE_SKC_CREATE_CL
-
-//
-//
-//
-
-#ifdef __APPLE__
-#include "OpenCL/opencl.h"
-#else
-#include "CL/opencl.h"
-#endif
-
-//
-//
-//
-
-#include "skc.h"
-
-//
-// CONTEXT CREATION
-//
-
-skc_err
-skc_context_create_cl(skc_context_t * context,
- cl_context context_cl,
- cl_device_id device_id_cl);
-
-//
-// FIXME -- SPECIALIZE SURFACE RENDER
-//
-
-#if 0
-
-//
-// SURFACE RENDER
-//
-
-typedef void (*skc_surface_render_pfn_notify)(skc_surface_t surface,
- skc_styling_t styling,
- skc_composition_t composition,
- void * data);
-skc_err
-skc_surface_render(skc_surface_t surface,
- uint32_t const clip[4],
- skc_styling_t styling,
- skc_composition_t composition,
- skc_surface_render_pfn_notify notify,
- void * data,
- void * fb); // FIXME FIXME
-
-#endif
-
-//
-//
-//
-
-#endif
-
-//
-//
-//
diff --git a/src/compute/skc/skc_types.h b/src/compute/skc/skc_types.h
index 0dbcf182bf..c0b1dc97e1 100644
--- a/src/compute/skc/skc_types.h
+++ b/src/compute/skc/skc_types.h
@@ -20,31 +20,28 @@
//
//
-typedef struct skc_context * skc_context_t;
-typedef struct skc_path_builder * skc_path_builder_t;
-typedef struct skc_raster_builder * skc_raster_builder_t;
+typedef struct skc_context * skc_context_t;
+typedef struct skc_path_builder * skc_path_builder_t;
+typedef struct skc_raster_builder * skc_raster_builder_t;
-typedef struct skc_composition * skc_composition_t;
-typedef struct skc_styling * skc_styling_t;
+typedef struct skc_composition * skc_composition_t;
+typedef struct skc_styling * skc_styling_t;
-typedef struct skc_surface * skc_surface_t;
+typedef struct skc_surface * skc_surface_t;
-typedef uint32_t skc_path_t;
-typedef uint32_t skc_raster_t;
+typedef uint32_t skc_path_t;
+typedef uint32_t skc_raster_t;
-typedef uint32_t skc_layer_id;
-typedef uint32_t skc_group_id;
+typedef uint32_t skc_layer_id;
+typedef uint32_t skc_group_id;
-typedef uint32_t skc_styling_cmd_t;
+typedef uint32_t skc_styling_cmd_t;
-typedef uint64_t skc_weakref_t;
-typedef skc_weakref_t skc_transform_weakref_t;
-typedef skc_weakref_t skc_raster_clip_weakref_t;
+typedef uint64_t skc_weakref_t;
+typedef skc_weakref_t skc_transform_weakref_t;
+typedef skc_weakref_t skc_raster_clip_weakref_t;
-#if 0
-typedef struct skc_interop * skc_interop_t;
-typedef uint32_t skc_interop_surface_t;
-#endif
+typedef void * skc_framebuffer_t;
//
//
@@ -62,10 +59,6 @@ typedef uint32_t skc_interop_surface_t;
// RASTER CLIP LAYOUT: { x0, y0, x1, y1 }
//
-//
-//
-//
-
#endif
//
diff --git a/src/compute/skc/surface.c b/src/compute/skc/surface.c
index 61bfac3ee6..3d96bb65ac 100644
--- a/src/compute/skc/surface.c
+++ b/src/compute/skc/surface.c
@@ -34,39 +34,18 @@ skc_surface_release(skc_surface_t surface)
return SKC_ERR_SUCCESS;
}
-skc_err
-skc_surface_clear(skc_surface_t surface,
- float const rgba[4],
- uint32_t const rect[4],
- void * fb)
-{
- surface->clear(surface->impl,rgba,rect,fb);
-
- return SKC_ERR_SUCCESS;
-}
-
-skc_err
-skc_surface_blit(skc_surface_t surface,
- uint32_t const rect[4],
- int32_t const txty[2])
-{
- surface->blit(surface->impl,rect,txty);
-
- return SKC_ERR_SUCCESS;
-}
-
//
//
//
skc_err
-skc_surface_render(skc_surface_t surface,
- uint32_t const clip[4],
- skc_styling_t styling,
- skc_composition_t composition,
- skc_surface_render_pfn_notify notify,
- void * data,
- void * fb)
+skc_surface_render(skc_surface_t surface,
+ skc_styling_t styling,
+ skc_composition_t composition,
+ skc_framebuffer_t fb,
+ uint32_t const clip[4],
+ skc_surface_render_notify notify,
+ void * data)
{
skc_err err;
@@ -74,17 +53,24 @@ skc_surface_render(skc_surface_t surface,
if ((err = skc_styling_seal(styling)) != SKC_ERR_SUCCESS)
return err;
- // seal composition -- force started
+ // seal composition -- force starts any dependent paths or rasters
if ((err = skc_composition_seal(composition)) != SKC_ERR_SUCCESS)
return err;
//
- // FIXME -- at some point, we will want non-overlapping clips to be
- // rendered simultaneously. There is plenty of compute for nominal
- // size render tasks so it might not make much a performance
- // improvement.
+ // NOTE: there is purposefully no guard against any of the following
+ // use cases:
+ //
+ // - Simultaneous renders to different frambuffers.
+ //
+ // - Simultaneous renders with potentially overlapping clips to
+ // the same framebuffer.
+ //
+ // NOTE: we may want to support concurrent rendering of
+ // non-overlapping clips. This is fairly easy but at this point
+ // doesn't seem like a common use case.
//
- surface->render(surface->impl,clip,styling,composition,notify,data,fb);
+ surface->render(surface->impl,styling,composition,fb,clip,notify,data);
return SKC_ERR_SUCCESS;
}
diff --git a/src/compute/skc/surface.h b/src/compute/skc/surface.h
index 7f9dda85c4..94f9128841 100644
--- a/src/compute/skc/surface.h
+++ b/src/compute/skc/surface.h
@@ -26,29 +26,15 @@ struct skc_surface
skc_int ref_count;
- //
- // FIXME -- this list of pfn's isn't complete
- //
- void (* release)(struct skc_surface_impl * const impl);
- void (* render )(struct skc_surface_impl * const impl,
- uint32_t const clip[4],
- skc_styling_t styling,
- skc_composition_t composition,
- skc_surface_render_pfn_notify notify,
- void * data,
- void * fb);
- //
- // FIXME -- these will probably be removed
- //
- void (* clear )(struct skc_surface_impl * const impl,
- float const rgba[4],
- skc_uint const rect[4],
- void * fb);
-
- void (* blit )(struct skc_surface_impl * const impl,
- skc_uint const rect[4],
- skc_int const txty[2]);
-
+ void (* release)(struct skc_surface_impl * const impl);
+
+ void (* render )(struct skc_surface_impl * const impl,
+ skc_styling_t styling,
+ skc_composition_t composition,
+ skc_framebuffer_t fb,
+ uint32_t const clip[4],
+ skc_surface_render_notify notify,
+ void * data);
};
//