On 02/09/2015 06:22 AM, Tapani Pälli wrote:
> 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 <tapani.pa...@intel.com>
> ---
>  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<waffle::nacl_container*>(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 0000000..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 <semaphore.h>
> +
> +// 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::CompletionCallback cb =
> +            cbf.NewCallback(&NaclSwapThread::swap_buffers);
> +
> +        if (message_loop().PostWork(cb) != PP_OK)
> +            return false;

I don't understand NaCl's message loop. When you post a callback
to the message loop, does NaCl provide any guarantees on which
thread executes the callback?

> +
> +        sem_wait(&sem);
> +
> +        return true;
> +    }
> +
> +private:
> +
> +    void swap_buffers(int32_t result)
> +    {
> +        int32_t error = ctx->SwapBuffers(pp::BlockUntilComplete());
> +        switch (error) {
> +            case PP_OK:
> +                break;
> +            case PP_ERROR_NOMEMORY:
> +                wcore_errorf(WAFFLE_ERROR_BAD_ALLOC,
> +                             "pp::Graphics3D::SwapBuffers: Out of memory.");
> +                break;
> +            case PP_ERROR_CONTEXT_LOST:
> +                wcore_errorf(WAFFLE_ERROR_FATAL,
> +                             "pp::Graphics3D::SwapBuffers: 3D context 
> lost.");
> +                break;
> +            default:
> +                wcore_errorf(WAFFLE_ERROR_UNKNOWN,
> +                             "pp::Graphics3D::SwapBuffers: Unknown error.");
> +                break;
> +        }
> +        sem_post(&sem);
> +    }
> +
> +    pp::Graphics3D *ctx;
> +    pp::CompletionCallbackFactory<NaclSwapThread> cbf;
> +    sem_t sem;
> +};
> diff --git a/src/waffle/nacl/nacl_window.c b/src/waffle/nacl/nacl_window.c
> index 7b7121f..5ac031c 100644
> --- a/src/waffle/nacl/nacl_window.c
> +++ b/src/waffle/nacl/nacl_window.c
> @@ -97,5 +97,6 @@ nacl_window_resize(struct wcore_window *wc_self,
>  bool
>  nacl_window_swap_buffers(struct wcore_window *wc_self)
>  {
> -    return false;
> +    struct nacl_platform *plat = nacl_platform(wc_self->display->platform);
> +    return nacl_swapbuffers(plat->nacl);
>  }
> 


Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
waffle mailing list
waffle@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/waffle

Reply via email to