[waffle] [PATCH v2 4/8] nacl: add implementation for waffle_context_create
Tapani Pälli
tapani.palli at intel.com
Mon Feb 9 05:24:45 PST 2015
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 <tapani.palli at intel.com>
---
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<waffle::nacl_container*>(nc));
}
+
+extern "C" bool
+nacl_context_init(struct nacl_container *nc, struct nacl_config *cfg)
+{
+ return waffle::nacl_context_init(
+ reinterpret_cast<waffle::nacl_container*>(nc), cfg);
+}
+
+extern "C" void
+nacl_context_fini(struct nacl_container *nc)
+{
+ waffle::nacl_container *cpp_nc =
+ reinterpret_cast<waffle::nacl_container*>(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 <dlfcn.h>
+
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_context_destroy(struct wcore_context *wc_self)
@@ -34,8 +35,13 @@ nacl_context_destroy(struct wcore_context *wc_self)
if (!wc_self)
return ok;
+ struct nacl_platform *nacl_plat =
+ nacl_platform(api_platform);
+
self = nacl_context(wc_self);
+ nacl_context_fini(nacl_plat->nacl);
+
ok &= wcore_context_teardown(wc_self);
free(self);
return ok;
@@ -47,6 +53,8 @@ nacl_context_create(struct wcore_platform *wc_plat,
struct wcore_context *wc_share_ctx)
{
struct nacl_context *self;
+ struct nacl_config *config = nacl_config(wc_config);
+ struct nacl_platform *platform = nacl_platform(wc_plat);
bool ok = true;
self = wcore_calloc(sizeof(*self));
@@ -57,6 +65,10 @@ nacl_context_create(struct wcore_platform *wc_plat,
if (!ok)
goto error;
+ ok = nacl_context_init(platform->nacl, config);
+ if (!ok)
+ goto error;
+
return &self->wcore;
error:
--
2.1.0
More information about the waffle
mailing list