[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