diff options
author | Allan MacKinnon <allanmac@google.com> | 2018-06-24 08:31:14 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-24 15:56:44 +0000 |
commit | ebf160f308b698c075c9c1cf8d65d40cb2486238 (patch) | |
tree | 5593af46661b4971275a606903b5a64cd7d694f7 | |
parent | 5f0cc0e0665143d4d7b1a5ff06cf8df747068463 (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>
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); }; // |