Browse Source

Platform: support for NaCl applications.

pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
643977abbd
  1. 4
      CMakeLists.txt
  2. 4
      modules/FindMagnum.cmake
  3. 12
      src/Platform/CMakeLists.txt
  4. 97
      src/Platform/NaClApplication.cpp
  5. 175
      src/Platform/NaClApplication.h

4
CMakeLists.txt

@ -21,7 +21,9 @@ option(WITH_GLXAPPLICATION "Build GlxApplication library" OFF)
cmake_dependent_option(WITH_XEGLAPPLICATION "Build XEglApplication library" OFF "TARGET_GLES" OFF)
cmake_dependent_option(WITH_GLUTAPPLICATION "Build GlutApplication library" OFF "NOT TARGET_GLES" OFF)
option(WITH_SDL2APPLICATION "Build Sdl2Application library" OFF)
if(${CMAKE_SYSTEM_NAME} STREQUAL NaCl)
option(WITH_NACLAPPLICATION "Build NaClApplication library" OFF)
endif()
option(BUILD_TESTS "Build unit tests." OFF)
if(BUILD_TESTS)

4
modules/FindMagnum.cmake

@ -25,6 +25,8 @@
# XEglApplication - X/EGL application (depends on EGL and X11 libraries)
# GlutApplication - GLUT application (depends on GLUT library)
# Sdl2Application - SDL2 application (depends on SDL2 library)
# NaClApplication - NaCl application (only if targetting Google Chrome
# Native Client)
# Example usage with specifying additional components is:
# find_package(Magnum [REQUIRED|COMPONENTS]
# MeshTools Primitives GlutApplication)
@ -134,6 +136,8 @@ foreach(component ${Magnum_FIND_COMPONENTS})
endif()
endif()
# NaCl application has no additional dependencies
# GLX application dependencies
if(${component} STREQUAL GlxApplication)
find_package(X11)

12
src/Platform/CMakeLists.txt

@ -35,6 +35,18 @@ if(WITH_SDL2APPLICATION)
endif()
endif()
# NaCl application
if(WITH_NACLAPPLICATION)
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL NaCl)
message(FATAL_ERROR "NaClApplication is available only when targetting Google Chrome Native Client. Set WITH_NACLAPPLICATION to OFF to skip building it.")
endif()
add_library(MagnumNaClApplication STATIC
NaClApplication.cpp)
install(FILES NaClApplication.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform)
install(TARGETS MagnumNaClApplication DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
endif()
# GLX application
if(WITH_GLXAPPLICATION)
set(NEED_ABSTRACTXAPPLICATION 1)

97
src/Platform/NaClApplication.cpp

@ -0,0 +1,97 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "NaClApplication.h"
#include <ppapi/cpp/graphics_3d.h>
#include <ppapi/lib/gl/gles2/gl2ext_ppapi.h>
#include <ppapi/cpp/completion_callback.h>
#include "Context.h"
namespace Magnum { namespace Platform {
NaClApplication::NaClApplication(PP_Instance instance, const Math::Vector2<GLsizei>& size): Instance(instance), Graphics3DClient(this), viewportSize(size) {
int32_t attributes[] = {
PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24,
PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8,
PP_GRAPHICS3DATTRIB_SAMPLES, 0,
PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
PP_GRAPHICS3DATTRIB_WIDTH, size.x(),
PP_GRAPHICS3DATTRIB_HEIGHT, size.y(),
PP_GRAPHICS3DATTRIB_NONE
};
graphics = new pp::Graphics3D(this, attributes);
if(graphics->is_null()) {
Error() << "Platform::NaClApplication::NaClApplication(): cannot create graphics";
exit(1);
}
if(!BindGraphics(*graphics)) {
Error() << "Platform::NaClApplication::NaClApplication(): cannot bind graphics";
exit(1);
}
glSetCurrentContextPPAPI(graphics->pp_resource());
c = new Context;
}
NaClApplication::~NaClApplication() {
delete c;
delete graphics;
}
void NaClApplication::DidChangeView(const pp::View& view) {
Math::Vector2<GLsizei> size(view.GetRect().width(), view.GetRect().height());
/* Canvas resized */
if(viewportSize != size) {
graphics->ResizeBuffers(size.x(), size.y());
viewportSize = size;
flags |= Flag::ViewportUpdated;
}
/* Update viewport, if changed */
if(!(flags & Flag::ViewportUpdated)) {
flags &= ~Flag::ViewportUpdated;
viewportEvent(size);
}
drawEvent();
}
void NaClApplication::swapBuffers() {
/* Swap already in progress, do nothing */
if(flags & Flag::SwapInProgress) return;
/* Swap buffers and call swapCallback() when done */
flags |= Flag::SwapInProgress;
graphics->SwapBuffers(pp::CompletionCallback(&swapCallback, this));
}
void NaClApplication::swapCallback(void* applicationInstance, std::int32_t) {
NaClApplication* instance = static_cast<NaClApplication*>(applicationInstance);
instance->flags &= ~Flag::SwapInProgress;
/* Redraw, if requested */
if(instance->flags & Flag::Redraw) {
instance->flags &= ~Flag::Redraw;
instance->drawEvent();
}
}
}}

175
src/Platform/NaClApplication.h

@ -0,0 +1,175 @@
#ifndef Magnum_Platform_NaClApplication_h
#define Magnum_Platform_NaClApplication_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Class Magnum::Platform::NaClApplication
*/
#include <string>
#include <Containers/EnumSet.h>
#include <ppapi/cpp/instance.h>
#include <ppapi/cpp/instance_handle.h>
#include <ppapi/cpp/module.h>
#include <ppapi/cpp/graphics_3d_client.h>
#include <ppapi/gles2/gl2ext_ppapi.h>
#include "Math/Vector2.h"
#include "Magnum.h"
#include "magnumCompatibility.h"
namespace pp {
class Graphics3D;
}
namespace Magnum {
class Context;
namespace Platform {
/** @nosubgrouping
@brief NaCl application
@section NaClApplication-usage Usage
You need to implement at least drawEvent() and viewportEvent() to be able to
draw on the screen. The subclass must be then registered to NaCl API using
MAGNUM_NACLAPPLICATION_MAIN() macro.
@code
class MyApplication: public Magnum::Platform::Sdl2Application {
// implement required methods...
};
MAGNUM_NACLAPPLICATION_MAIN(MyApplication)
@endcode
*/
class NaClApplication: public pp::Instance, public pp::Graphics3DClient {
public:
/**
* @brief Constructor
* @param instance Module instance
* @param size Rendering size
*
* Creates double-buffered RGBA canvas with depth and stencil buffers.
*/
explicit NaClApplication(PP_Instance instance, const Math::Vector2<GLsizei>& size = Math::Vector2<GLsizei>(640, 480));
~NaClApplication();
/** @{ @name Drawing functions */
protected:
/**
* @brief Viewport event
*
* Called when viewport size changes. You should pass the new size to
* Framebuffer::setViewport() or SceneGraph::Camera::setViewport(),
* if using scene graph.
*/
virtual void viewportEvent(const Math::Vector2<GLsizei>& size) = 0;
/**
* @brief Draw event
*
* Here implement your drawing functions, such as calling
* SceneGraph::Camera::draw(). After drawing is finished, call
* swapBuffers(). If you want to draw immediately again, call also
* redraw().
*/
virtual void drawEvent() = 0;
/**
* @brief Swap buffers
*
* Paints currently rendered framebuffer on screen.
*/
void swapBuffers();
/**
* @brief Redraw immediately
*
* Marks the window for redrawing, resulting in call of drawEvent()
* in the next iteration.
*/
inline void redraw() {
flags |= Flag::Redraw;
}
/*@}*/
private:
enum class Flag: std::uint8_t {
ViewportUpdated = 1 << 0,
SwapInProgress = 1 << 1,
Redraw = 1 << 2
};
typedef Corrade::Containers::EnumSet<Flag, std::uint8_t> Flags;
inline void Graphics3DContextLost() override {
CORRADE_ASSERT(false, "NaClApplication: context unexpectedly lost", );
}
void DidChangeView(const pp::View& view) override;
static void swapCallback(void* applicationInstance, std::int32_t);
pp::Graphics3D* graphics;
Context* c;
Math::Vector2<GLsizei> viewportSize;
Flags flags;
CORRADE_ENUMSET_FRIEND_OPERATORS(Flags)
};
CORRADE_ENUMSET_OPERATORS(NaClApplication::Flags)
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<class Application> class NaClModule: public pp::Module {
public:
inline ~NaClModule() {
glTerminatePPAPI();
}
inline bool Init() override {
return glInitializePPAPI(get_browser_interface()) == GL_TRUE;
}
inline pp::Instance* CreateInstance(PP_Instance instance) {
return new Application(instance);
}
};
}
#endif
/** @hideinitializer
@brief Entry point for NaCl application
@param application Application class name
See NaClApplication for more information.
*/
/* look at that insane placement of __attribute__. WTF. */
#define MAGNUM_NACLAPPLICATION_MAIN(application) \
namespace pp { \
Module __attribute__ ((visibility ("default"))) * CreateModule() { \
return new Magnum::Platform::Implementation::NaClModule<application>(); \
} \
}
}}
#endif
Loading…
Cancel
Save