[waffle] [PATCH v2 3/8] nacl: add implementation for waffle_config_choose
Patch fills attributes table suitable for Pepper API from wcore_config_attrs passed by the application. v2: throw error on unsupported context type (Chad Versace) code cleanup, comment for max attribs (Emil Velikov) Signed-off-by: Tapani Pälli --- src/waffle/nacl/nacl_config.c | 37 + src/waffle/nacl/nacl_config.h | 1 + 2 files changed, 38 insertions(+) diff --git a/src/waffle/nacl/nacl_config.c b/src/waffle/nacl/nacl_config.c index 27a75e1..7478493 100644 --- a/src/waffle/nacl/nacl_config.c +++ b/src/waffle/nacl/nacl_config.c @@ -23,7 +23,9 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "ppapi/c/pp_graphics_3d.h" #include "nacl_config.h" +#include "wcore_error.h" bool nacl_config_destroy(struct wcore_config *wc_self) @@ -50,6 +52,41 @@ nacl_config_choose(struct wcore_platform *wc_plat, if (self == NULL) return NULL; +// Currently only OpenGL ES 2.0 is supported. +if (attrs->context_api != WAFFLE_CONTEXT_OPENGL_ES2) { +wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, + "NaCl does no support context type %s.", + wcore_enum_to_string(attrs->context_api)); +return NULL; +} + +unsigned attr = 0; + +// Max amount of attribs is hardcoded in nacl_config.h (64) +#define PUSH_ATTRIB(a, val) \ +if (val != WAFFLE_DONT_CARE) {\ +self->attribs[attr++] = a; \ +self->attribs[attr++] = val;\ +} + +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_ALPHA_SIZE, attrs->alpha_size); +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_BLUE_SIZE, attrs->blue_size); +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_GREEN_SIZE, attrs->green_size); +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_RED_SIZE, attrs->red_size); +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_DEPTH_SIZE, attrs->depth_size); +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_STENCIL_SIZE, attrs->stencil_size); +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_SAMPLES,attrs->samples); +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, attrs->sample_buffers); + +// Note, we have to have at least 1x1 size so that initial context +// backing surface creation will succeed without errors. Later on +// it is resized by window creation/resize. +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_WIDTH, 1); +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_HEIGHT, 1); +PUSH_ATTRIB(PP_GRAPHICS3DATTRIB_NONE, 0); + +#undef PUSH_ATTRIB + ok = wcore_config_init(&self->wcore, wc_dpy, attrs); if (!ok) goto error; diff --git a/src/waffle/nacl/nacl_config.h b/src/waffle/nacl/nacl_config.h index 3270179..47fa252 100644 --- a/src/waffle/nacl/nacl_config.h +++ b/src/waffle/nacl/nacl_config.h @@ -33,6 +33,7 @@ struct wcore_platform; struct nacl_config { struct wcore_config wcore; +int32_t attribs[64]; }; DEFINE_CONTAINER_CAST_FUNC(nacl_config, -- 2.1.0 ___ waffle mailing list waffle@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/waffle
[waffle] [PATCH v2 8/8] nacl: add implementation for waffle_dl_sym
v2: use wcore_calloc, code cleanup (Emil Velikov) open dll only once in can_open (Chad Versace) Signed-off-by: Tapani Pälli --- src/waffle/nacl/nacl_platform.c | 69 +++-- src/waffle/nacl/nacl_platform.h | 1 + 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/waffle/nacl/nacl_platform.c b/src/waffle/nacl/nacl_platform.c index c4fefe5..22169da 100644 --- a/src/waffle/nacl/nacl_platform.c +++ b/src/waffle/nacl/nacl_platform.c @@ -43,6 +43,11 @@ nacl_platform_destroy(struct wcore_platform *wc_self) nacl_teardown(self->nacl); +if (self->gl_dl) +if (dlclose(self->gl_dl) != 0) +wcore_errorf(WAFFLE_ERROR_UNKNOWN, "dlclose failed: %s", + dlerror()); + free(self); return ok; } @@ -51,7 +56,41 @@ static bool nacl_platform_dl_can_open(struct wcore_platform *wc_self, int32_t waffle_dl) { -return false; +struct nacl_platform *self = nacl_platform(wc_self); + +switch (waffle_dl) { +case WAFFLE_DL_OPENGL_ES2: +if (!self->gl_dl) +self->gl_dl = dlopen(NACL_GLES2_LIBRARY, RTLD_LAZY); +break; +// API not supported +default: +return false; +} + +if (!self->gl_dl) +wcore_errorf(WAFFLE_ERROR_UNKNOWN, "dlopen failed: %s", dlerror()); + +return self->gl_dl ? true : false; +} + +// Construct a string that maps GL function to NaCl function +// by concating given prefix and function name tail from 'src'. +static char * +nacl_prefix(const char *src, const char *prefix) +{ +if (strncmp(src, "gl", 2) != 0) +return NULL; + +uint32_t len = strlen(src) + strlen(prefix); + +char *dst = wcore_calloc(len); +if (!dst) +return NULL; + +snprintf(dst, len, "%s%s", prefix, src + 2); + +return dst; } static void* @@ -59,7 +98,33 @@ nacl_platform_dl_sym(struct wcore_platform *wc_self, int32_t waffle_dl, const char *name) { -return NULL; +struct nacl_platform *self = nacl_platform(wc_self); +char *nacl_name = NULL; +void *func = NULL; + +if (!self->gl_dl) +if (!nacl_platform_dl_can_open(wc_self, waffle_dl)) +return false; + +nacl_name = nacl_prefix(name, "GLES2"); + +if (!nacl_name) +return NULL; + +func = dlsym(self->gl_dl, nacl_name); + +if (!func) { +const char *error = dlerror(); +if (error) { +wcore_errorf(WAFFLE_ERROR_UNKNOWN, + "dlsym(libname=\"%s\", symbol=\"%s\") failed: %s", + NACL_GLES2_LIBRARY, nacl_name, error); +} +} + +free(nacl_name); + +return func; } static bool diff --git a/src/waffle/nacl/nacl_platform.h b/src/waffle/nacl/nacl_platform.h index ba58de5..fa2d364 100644 --- a/src/waffle/nacl/nacl_platform.h +++ b/src/waffle/nacl/nacl_platform.h @@ -38,6 +38,7 @@ struct nacl_platform { struct wcore_platform wcore; struct nacl_container *nacl; +void *gl_dl; }; DEFINE_CONTAINER_CAST_FUNC(nacl_platform, -- 2.1.0 ___ waffle mailing list waffle@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/waffle
[waffle] [PATCH v2 2/8] nacl: add supports_context_api implementation
Currently only OpenGL ES 2.0 is supported. v2: throw error only on erroneous input (Chad Versace) Signed-off-by: Tapani Pälli --- src/waffle/nacl/nacl_display.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/waffle/nacl/nacl_display.c b/src/waffle/nacl/nacl_display.c index 2d1162e..d1906fe 100644 --- a/src/waffle/nacl/nacl_display.c +++ b/src/waffle/nacl/nacl_display.c @@ -66,5 +66,16 @@ bool nacl_display_supports_context_api(struct wcore_display *wc_self, int32_t context_api) { -return false; +switch (context_api) { +case WAFFLE_CONTEXT_OPENGL_ES2: +return true; +case WAFFLE_CONTEXT_OPENGL: +case WAFFLE_CONTEXT_OPENGL_ES1: +case WAFFLE_CONTEXT_OPENGL_ES3: +return false; +default: +wcore_error_internal("waffle_context_api has bad value %#x", + context_api); +return false; +} } -- 2.1.0 ___ waffle mailing list waffle@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/waffle
[waffle] [PATCH v2 6/8] nacl: add implementation for waffle_make_current
v2: cleanup code, no need for separate c++ function (Chad Versace) release context when ctx and window are NULL (Emil Velikov) Signed-off-by: Tapani Pälli --- src/waffle/nacl/nacl_container.cpp | 13 + src/waffle/nacl/nacl_container.h | 1 + src/waffle/nacl/nacl_platform.c| 4 +++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/waffle/nacl/nacl_container.cpp b/src/waffle/nacl/nacl_container.cpp index 5dd44a8..fe907ff 100644 --- a/src/waffle/nacl/nacl_container.cpp +++ b/src/waffle/nacl/nacl_container.cpp @@ -181,3 +181,16 @@ nacl_resize(struct nacl_container *nc, int32_t width, int32_t height) } return false; } + +extern "C" bool +nacl_makecurrent(nacl_container *nc, bool release) +{ +waffle::nacl_container *cpp_nc = +reinterpret_cast(nc); + +PP_Resource ctx = release ? 0 : cpp_nc->ctx->pp_resource(); + +cpp_nc->glSetCurrentContextPPAPI(ctx); + +return true; +} diff --git a/src/waffle/nacl/nacl_container.h b/src/waffle/nacl/nacl_container.h index d1cb11d..ca26a1f 100644 --- a/src/waffle/nacl/nacl_container.h +++ b/src/waffle/nacl/nacl_container.h @@ -41,6 +41,7 @@ struct nacl_container *nacl_init(); void nacl_teardown(struct nacl_container *nc); bool nacl_context_init(struct nacl_container *nc, struct nacl_config *cfg); bool nacl_resize(struct nacl_container *nc, int32_t width, int32_t height); +bool nacl_makecurrent(struct nacl_container *nc, bool release); void nacl_context_fini(struct nacl_container *nc); #ifdef __cplusplus diff --git a/src/waffle/nacl/nacl_platform.c b/src/waffle/nacl/nacl_platform.c index b4df9d9..c4fefe5 100644 --- a/src/waffle/nacl/nacl_platform.c +++ b/src/waffle/nacl/nacl_platform.c @@ -68,7 +68,9 @@ nacl_platform_make_current(struct wcore_platform *wc_self, struct wcore_window *wc_window, struct wcore_context *wc_ctx) { -return false; +bool release = (!wc_window && !wc_ctx); +return nacl_makecurrent(nacl_platform(wc_self)->nacl, +release); } struct wcore_platform* -- 2.1.0 ___ waffle mailing list waffle@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/waffle
[waffle] [PATCH v2 0/8] nacl backend implementation
Here's v2 of the nacl backend implementation patches. I've gone through review comments and hopefully did not forget anything. I changed the way how swapbuffers is implemented and now it blocks (so no event required). All patches are in tree here: http://cgit.freedesktop.org/~tpalli/waffle/log/?h=nacl Alternative tree with extra patch to have naclgears testcase: http://cgit.freedesktop.org/~tpalli/waffle/log/?h=naclgears Thanks; Tapani Pälli (8): nacl: add attrib_list parameter to create_window nacl: add supports_context_api implementation nacl: add implementation for waffle_config_choose nacl: add implementation for waffle_context_create nacl: add implementation for window create and resize nacl: add implementation for waffle_make_current nacl: add implementation for waffle_window_swap_buffers nacl: add implementation for waffle_dl_sym src/waffle/nacl/nacl_config.c | 37 ++ src/waffle/nacl/nacl_config.h | 1 + src/waffle/nacl/nacl_container.cpp | 144 - src/waffle/nacl/nacl_container.h | 13 +++- src/waffle/nacl/nacl_context.c | 12 src/waffle/nacl/nacl_display.c | 13 +++- src/waffle/nacl/nacl_platform.c| 73 ++- src/waffle/nacl/nacl_platform.h| 1 + src/waffle/nacl/nacl_swap_thread.h | 93 src/waffle/nacl/nacl_window.c | 22 -- src/waffle/nacl/nacl_window.h | 4 +- 11 files changed, 401 insertions(+), 12 deletions(-) create mode 100644 src/waffle/nacl/nacl_swap_thread.h -- 2.1.0 ___ waffle mailing list waffle@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/waffle
[waffle] [PATCH v2 5/8] nacl: add implementation for window create and resize
v2: cleanup + throw error if resize fails (Chad Versace) Signed-off-by: Tapani Pälli --- src/waffle/nacl/nacl_container.cpp | 27 +++ src/waffle/nacl/nacl_container.h | 1 + src/waffle/nacl/nacl_window.c | 9 ++--- src/waffle/nacl/nacl_window.h | 1 + 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/waffle/nacl/nacl_container.cpp b/src/waffle/nacl/nacl_container.cpp index e4bf07a..5dd44a8 100644 --- a/src/waffle/nacl/nacl_container.cpp +++ b/src/waffle/nacl/nacl_container.cpp @@ -26,6 +26,7 @@ #include "ppapi/cpp/graphics_3d.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" +#include "ppapi/c/pp_errors.h" #include "nacl_container.h" namespace waffle { @@ -154,3 +155,29 @@ nacl_context_fini(struct nacl_container *nc) cpp_nc->glSetCurrentContextPPAPI(0); cpp_nc->glTerminatePPAPI(); } + +extern "C" bool +nacl_resize(struct nacl_container *nc, int32_t width, int32_t height) +{ +waffle::nacl_container *cpp_nc = +reinterpret_cast(nc); + +int32_t error = cpp_nc->ctx->ResizeBuffers(width, height); + +if (error == PP_OK) + return true; + +switch (error) { +case PP_ERROR_BADRESOURCE: +wcore_errorf(WAFFLE_ERROR_FATAL, "Invalid NaCl 3D context."); +break; +case PP_ERROR_BADARGUMENT: +wcore_errorf(WAFFLE_ERROR_BAD_PARAMETER, + "Invalid values given for resize (w %d h %d)", + width, height); +break; +default: +wcore_errorf(WAFFLE_ERROR_UNKNOWN, "NaCl resize failed."); +} +return false; +} diff --git a/src/waffle/nacl/nacl_container.h b/src/waffle/nacl/nacl_container.h index af08116..d1cb11d 100644 --- a/src/waffle/nacl/nacl_container.h +++ b/src/waffle/nacl/nacl_container.h @@ -40,6 +40,7 @@ struct nacl_container; struct nacl_container *nacl_init(); void nacl_teardown(struct nacl_container *nc); bool nacl_context_init(struct nacl_container *nc, struct nacl_config *cfg); +bool nacl_resize(struct nacl_container *nc, int32_t width, int32_t height); void nacl_context_fini(struct nacl_container *nc); #ifdef __cplusplus diff --git a/src/waffle/nacl/nacl_window.c b/src/waffle/nacl/nacl_window.c index 3596327..7b7121f 100644 --- a/src/waffle/nacl/nacl_window.c +++ b/src/waffle/nacl/nacl_window.c @@ -53,6 +53,7 @@ nacl_window_create(struct wcore_platform *wc_plat, { struct nacl_window *self; +struct nacl_platform *nplat = nacl_platform(wc_plat); bool ok = true; if (wcore_attrib_list_length(attrib_list) > 0) { @@ -68,8 +69,9 @@ nacl_window_create(struct wcore_platform *wc_plat, if (!ok) goto error; -if (!ok) -goto error; +// Set requested dimensions for the backing surface. +if (!nacl_resize(nplat->nacl, width, height)) + goto error; return &self->wcore; @@ -88,7 +90,8 @@ bool nacl_window_resize(struct wcore_window *wc_self, int32_t width, int32_t height) { -return false; +struct nacl_platform *plat = nacl_platform(wc_self->display->platform); +return nacl_resize(plat->nacl, width, height); } bool diff --git a/src/waffle/nacl/nacl_window.h b/src/waffle/nacl/nacl_window.h index 48567b1..d3465f3 100644 --- a/src/waffle/nacl/nacl_window.h +++ b/src/waffle/nacl/nacl_window.h @@ -27,6 +27,7 @@ #include "wcore_window.h" #include "wcore_util.h" +#include "nacl_container.h" #include "nacl_platform.h" struct wcore_platform; -- 2.1.0 ___ waffle mailing list waffle@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/waffle
[waffle] [PATCH v2 7/8] nacl: add implementation for waffle_window_swap_buffers
Implementation for nacl is somewhat different as for other platforms, platform needs to ensure that the previous swap has finished before issuing GL commands or more swaps. This is done by introducing a worker thread that does buffer swaps from a work queue and uses a semaphore to lock main thread until swap is finished. v2: add error messaging if pp::Graphics3D::SwapBuffers fails add semaphore to implement blocking swap() remove extra nacl_swapbuffers() c++ function (Chad, Emil) Signed-off-by: Tapani Pälli --- src/waffle/nacl/nacl_container.cpp | 12 + src/waffle/nacl/nacl_container.h | 2 +- src/waffle/nacl/nacl_swap_thread.h | 93 ++ src/waffle/nacl/nacl_window.c | 3 +- 4 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 src/waffle/nacl/nacl_swap_thread.h diff --git a/src/waffle/nacl/nacl_container.cpp b/src/waffle/nacl/nacl_container.cpp index fe907ff..84ab1da 100644 --- a/src/waffle/nacl/nacl_container.cpp +++ b/src/waffle/nacl/nacl_container.cpp @@ -28,11 +28,13 @@ #include "ppapi/cpp/module.h" #include "ppapi/c/pp_errors.h" #include "nacl_container.h" +#include "nacl_swap_thread.h" namespace waffle { struct nacl_container { pp::Graphics3D *ctx; +NaclSwapThread *swapper; void *glapi; bool (*glInitializePPAPI) (PPB_GetInterface); @@ -49,6 +51,7 @@ nacl_container_dtor(waffle::nacl_container *nc) if (nc->glapi) dlclose(nc->glapi); +delete nc->swapper; delete nc; } @@ -119,6 +122,7 @@ nacl_context_init(waffle::nacl_container *nc, struct nacl_config *cfg) return false; } +nc->swapper = new NaclSwapThread(pp_instance, nc->ctx); return true; } @@ -194,3 +198,11 @@ nacl_makecurrent(nacl_container *nc, bool release) return true; } + +extern "C" bool +nacl_swapbuffers(nacl_container *nc) +{ +waffle::nacl_container *cpp_nc = +reinterpret_cast(nc); +return cpp_nc->swapper->swap(); +} diff --git a/src/waffle/nacl/nacl_container.h b/src/waffle/nacl/nacl_container.h index ca26a1f..579856d 100644 --- a/src/waffle/nacl/nacl_container.h +++ b/src/waffle/nacl/nacl_container.h @@ -43,7 +43,7 @@ bool nacl_context_init(struct nacl_container *nc, struct nacl_config *cfg); bool nacl_resize(struct nacl_container *nc, int32_t width, int32_t height); bool nacl_makecurrent(struct nacl_container *nc, bool release); void nacl_context_fini(struct nacl_container *nc); - +bool nacl_swapbuffers(struct nacl_container *nc); #ifdef __cplusplus }; #endif diff --git a/src/waffle/nacl/nacl_swap_thread.h b/src/waffle/nacl/nacl_swap_thread.h new file mode 100644 index 000..98d4630 --- /dev/null +++ b/src/waffle/nacl/nacl_swap_thread.h @@ -0,0 +1,93 @@ +// Copyright 2014 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "ppapi/cpp/graphics_3d.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/utility/completion_callback_factory.h" +#include "ppapi/utility/threading/simple_thread.h" +#include "wcore_error.h" +#include + +// Thread takes care that we do not issue another buffer +// swap before previous swap has completed. +class NaclSwapThread : public pp::SimpleThread +{ +public: +explicit NaclSwapThread(const pp::InstanceHandle &instance, +pp::Graphics3D *_ctx) : +pp::SimpleThread(instance), +ctx(_ctx), +cbf(this) +{ +Start(); +sem_init(&sem, 0, 0); +} + +~NaclSwapThread() +{ +message_loop().PostQuit(true); +} + +bool swap() +{ +pp::CompletionCallback cb = +cbf.NewCallback(&NaclSwapThread::swap_buffers);
[waffle] [PATCH v2 4/8] nacl: add implementation for waffle_context_create
Patch creates and initializes pp::Graphics3D context for OpenGL ES 2.0. v2: fix error messages and context object initialization (Chad Versace) dlclose on teardown, free the context properly (Emil Velikov) Signed-off-by: Tapani Pälli --- src/waffle/nacl/nacl_container.cpp | 92 +- src/waffle/nacl/nacl_container.h | 9 src/waffle/nacl/nacl_context.c | 12 + 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/src/waffle/nacl/nacl_container.cpp b/src/waffle/nacl/nacl_container.cpp index 3e8073c..e4bf07a 100644 --- a/src/waffle/nacl/nacl_container.cpp +++ b/src/waffle/nacl/nacl_container.cpp @@ -24,12 +24,19 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ppapi/cpp/graphics_3d.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" #include "nacl_container.h" namespace waffle { struct nacl_container { -pp::Graphics3D ctx; +pp::Graphics3D *ctx; + +void *glapi; +bool (*glInitializePPAPI) (PPB_GetInterface); +void (*glSetCurrentContextPPAPI) (PP_Resource); +bool (*glTerminatePPAPI) (void); }; static void @@ -37,6 +44,10 @@ nacl_container_dtor(waffle::nacl_container *nc) { if (!nc) return; + +if (nc->glapi) +dlclose(nc->glapi); + delete nc; } @@ -51,6 +62,65 @@ nacl_container_ctor() return nc; } +static bool +nacl_context_init(waffle::nacl_container *nc, struct nacl_config *cfg) +{ +// There is no way currently to pass a pp::Instance for Waffle, so +// we fetch a map of all instances and if there's only one we select +// that one, otherwise we fail. +const pp::Module::InstanceMap instances = +pp::Module::Get()->current_instances(); + +if (instances.size() != 1) { +wcore_errorf(WAFFLE_ERROR_FATAL, +"Could not find a pp::Instance for Waffle to use."); +return false; +} + +pp::Instance *pp_instance = instances.begin()->second; +nc->ctx = new pp::Graphics3D(pp_instance, pp::Graphics3D(), cfg->attribs); + +if (nc->ctx->is_null()) { +wcore_errorf(WAFFLE_ERROR_FATAL, "Unable to create NaCl 3D context."); +return false; +} + +// We need to fetch NaCl specific init, makecurrent and terminate +// functions that communicate with the browser interface. As nacl_config +// currently supports only ES2, this is hardcoded for ES2. +nc->glapi = dlopen(NACL_GLES2_LIBRARY, RTLD_LAZY); +if (!nc->glapi) { +wcore_errorf(WAFFLE_ERROR_FATAL, "dlopen failed: %s", dlerror()); +return false; +} + +#define RESOLVE(func) \ +nc->func = (typeof(nc->func)) dlsym(nc->glapi, (#func)); \ +if (!nc->func) { \ +wcore_errorf(WAFFLE_ERROR_FATAL, "failed to resolve %s", #func); \ +return false; \ +} + +RESOLVE(glInitializePPAPI); +RESOLVE(glSetCurrentContextPPAPI); +RESOLVE(glTerminatePPAPI); + +#undef RESOLVE + +if (!nc->glInitializePPAPI(pp::Module::Get()->get_browser_interface())) { +wcore_errorf(WAFFLE_ERROR_FATAL, +"Unable to initialize GL PPAPI!"); +return false; +} + +if (!pp_instance->BindGraphics(*nc->ctx)) { +wcore_errorf(WAFFLE_ERROR_FATAL, "Unable to bind NaCl 3D context."); +return false; +} + +return true; +} + }; // namespace waffle ends extern "C" struct nacl_container* @@ -64,3 +134,23 @@ nacl_teardown(nacl_container *nc) { waffle::nacl_container_dtor(reinterpret_cast(nc)); } + +extern "C" bool +nacl_context_init(struct nacl_container *nc, struct nacl_config *cfg) +{ +return waffle::nacl_context_init( + reinterpret_cast(nc), cfg); +} + +extern "C" void +nacl_context_fini(struct nacl_container *nc) +{ +waffle::nacl_container *cpp_nc = +reinterpret_cast(nc); + +delete cpp_nc->ctx; +cpp_nc->ctx = NULL; + +cpp_nc->glSetCurrentContextPPAPI(0); +cpp_nc->glTerminatePPAPI(); +} diff --git a/src/waffle/nacl/nacl_container.h b/src/waffle/nacl/nacl_container.h index 61d935c..af08116 100644 --- a/src/waffle/nacl/nacl_container.h +++ b/src/waffle/nacl/nacl_container.h @@ -25,13 +25,22 @@ #ifdef __cplusplus +#include + extern "C" { #endif +#include "nacl_config.h" +#include "wcore_error.h" + +#define NACL_GLES2_LIBRARY "libppapi_gles2.so" + struct nacl_container; struct nacl_container *nacl_init(); void nacl_teardown(struct nacl_container *nc); +bool nacl_context_init(struct nacl_container *nc, struct nacl_config *cfg); +void nacl_context_fini(struct nacl_container *nc); #ifdef __cplusplus }; diff --git a/src/waffle/nacl/nacl_context.c b/src/waffle/nacl/nacl_context.c index 2e68a64..962c4d9 100644 --- a/src/waffle/nacl/nacl_context.c +++ b/src/waffle/nacl/nacl_context.c @@ -24,6 +24,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "nacl_context.h" +#include "api_priv.h" bool nacl_con
[waffle] [PATCH v2 1/8] nacl: add attrib_list parameter to create_window
Signed-off-by: Tapani Pälli --- src/waffle/nacl/nacl_window.c | 10 +- src/waffle/nacl/nacl_window.h | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/waffle/nacl/nacl_window.c b/src/waffle/nacl/nacl_window.c index c5ba4e0..3596327 100644 --- a/src/waffle/nacl/nacl_window.c +++ b/src/waffle/nacl/nacl_window.c @@ -24,6 +24,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "wcore_error.h" +#include "wcore_attrib_list.h" #include "nacl_config.h" #include "nacl_display.h" #include "nacl_window.h" @@ -47,11 +48,18 @@ struct wcore_window* nacl_window_create(struct wcore_platform *wc_plat, struct wcore_config *wc_config, int width, - int height) + int height, + const intptr_t attrib_list[]) + { struct nacl_window *self; bool ok = true; +if (wcore_attrib_list_length(attrib_list) > 0) { +wcore_error_bad_attribute(attrib_list[0]); +return NULL; +} + self = wcore_calloc(sizeof(*self)); if (self == NULL) return NULL; diff --git a/src/waffle/nacl/nacl_window.h b/src/waffle/nacl/nacl_window.h index 5f0906d..48567b1 100644 --- a/src/waffle/nacl/nacl_window.h +++ b/src/waffle/nacl/nacl_window.h @@ -43,7 +43,8 @@ struct wcore_window* nacl_window_create(struct wcore_platform *wc_plat, struct wcore_config *wc_config, int width, - int height); + int height, + const intptr_t attrib_list[]); bool nacl_window_destroy(struct wcore_window *wc_self); -- 2.1.0 ___ waffle mailing list waffle@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/waffle
[waffle] [PATCH v3] nacl: add implementation for waffle_window_swap_buffers
Implementation for nacl is somewhat different as for other platforms, platform needs to ensure that the previous swap has finished before issuing GL commands or more swaps. This is done by introducing a worker thread that does buffer swaps from a work queue and uses a semaphore to lock main thread until swap is finished. v2: add error messaging if pp::Graphics3D::SwapBuffers fails add semaphore to implement blocking swap() remove extra nacl_swapbuffers() c++ function (Chad, Emil) v3: destroy semaphore when thread dies Signed-off-by: Tapani Pälli --- src/waffle/nacl/nacl_container.cpp | 12 + src/waffle/nacl/nacl_container.h | 2 +- src/waffle/nacl/nacl_swap_thread.h | 94 ++ src/waffle/nacl/nacl_window.c | 3 +- 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/waffle/nacl/nacl_swap_thread.h diff --git a/src/waffle/nacl/nacl_container.cpp b/src/waffle/nacl/nacl_container.cpp index fe907ff..84ab1da 100644 --- a/src/waffle/nacl/nacl_container.cpp +++ b/src/waffle/nacl/nacl_container.cpp @@ -28,11 +28,13 @@ #include "ppapi/cpp/module.h" #include "ppapi/c/pp_errors.h" #include "nacl_container.h" +#include "nacl_swap_thread.h" namespace waffle { struct nacl_container { pp::Graphics3D *ctx; +NaclSwapThread *swapper; void *glapi; bool (*glInitializePPAPI) (PPB_GetInterface); @@ -49,6 +51,7 @@ nacl_container_dtor(waffle::nacl_container *nc) if (nc->glapi) dlclose(nc->glapi); +delete nc->swapper; delete nc; } @@ -119,6 +122,7 @@ nacl_context_init(waffle::nacl_container *nc, struct nacl_config *cfg) return false; } +nc->swapper = new NaclSwapThread(pp_instance, nc->ctx); return true; } @@ -194,3 +198,11 @@ nacl_makecurrent(nacl_container *nc, bool release) return true; } + +extern "C" bool +nacl_swapbuffers(nacl_container *nc) +{ +waffle::nacl_container *cpp_nc = +reinterpret_cast(nc); +return cpp_nc->swapper->swap(); +} diff --git a/src/waffle/nacl/nacl_container.h b/src/waffle/nacl/nacl_container.h index ca26a1f..579856d 100644 --- a/src/waffle/nacl/nacl_container.h +++ b/src/waffle/nacl/nacl_container.h @@ -43,7 +43,7 @@ bool nacl_context_init(struct nacl_container *nc, struct nacl_config *cfg); bool nacl_resize(struct nacl_container *nc, int32_t width, int32_t height); bool nacl_makecurrent(struct nacl_container *nc, bool release); void nacl_context_fini(struct nacl_container *nc); - +bool nacl_swapbuffers(struct nacl_container *nc); #ifdef __cplusplus }; #endif diff --git a/src/waffle/nacl/nacl_swap_thread.h b/src/waffle/nacl/nacl_swap_thread.h new file mode 100644 index 000..8e8687b --- /dev/null +++ b/src/waffle/nacl/nacl_swap_thread.h @@ -0,0 +1,94 @@ +// Copyright 2014 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "ppapi/cpp/graphics_3d.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/utility/completion_callback_factory.h" +#include "ppapi/utility/threading/simple_thread.h" +#include "wcore_error.h" +#include + +// Thread takes care that we do not issue another buffer +// swap before previous swap has completed. +class NaclSwapThread : public pp::SimpleThread +{ +public: +explicit NaclSwapThread(const pp::InstanceHandle &instance, +pp::Graphics3D *_ctx) : +pp::SimpleThread(instance), +ctx(_ctx), +cbf(this) +{ +Start(); +sem_init(&sem, 0, 0); +} + +~NaclSwapThread() +{ +sem_destroy(&sem); +message_loop().PostQuit(true); +} + +bool swap() +{ +pp::CompletionCallba