Make code friendly to WebAssembly. (#140)

This does not add any build stuff or new sample code yet, it just does
some prep to our C++ codebase:

- Similar to Android, WebAssembly will not be using BlueGL. We were
  using a mixture of #if and #ifdef when checking for the existence of
  certain GL prototypes, but the latter is what we want in order to
  build robustly with any GL headers. (We still perform run-time checks
  for extensions, this doesn't change that.)

- Add a trivial ContextManager, does a bit more than Dummy since it
  needs to create an actual driver. This doesn't get compiled yet, it
  just adds files to the tree.

- WebAssembly does not support mmap, execinfo, or asm volatile.
This commit is contained in:
Philip Rideout
2018-08-24 17:17:40 -07:00
committed by GitHub
parent a0d1084b40
commit 446959042f
8 changed files with 144 additions and 15 deletions

View File

@@ -16,9 +16,12 @@
#include "driver/CircularBuffer.h"
#if !defined(WIN32)
#if !defined(WIN32) && !defined(__EMSCRIPTEN__)
# include <sys/mman.h>
# include <unistd.h>
# define HAS_MMAP 1
#else
# define HAS_MMAP 0
#endif
#include <stdio.h>
@@ -27,12 +30,6 @@
#include <utils/Log.h>
#include <utils/Panic.h>
#if defined(WIN32)
# define HAS_MMAP 0
#else
# define HAS_MMAP 1
#endif
using namespace utils;
namespace filament {

View File

@@ -44,6 +44,8 @@
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "driver/vulkan/ContextManagerVkWindows.h"
#endif
#elif defined(__EMSCRIPTEN__)
#include "driver/opengl/ContextManagerWebGL.h"
#else
#ifndef USE_EXTERNAL_GLES3
#include "driver/opengl/ContextManagerDummy.h"
@@ -92,6 +94,8 @@ ExternalContext* ExternalContext::create(Backend* backend) noexcept {
return new ContextManagerGLX();
#elif defined(WIN32)
return new ContextManagerWGL();
#elif defined(__EMSCRIPTEN__)
return new ContextManagerWebGL();
#else
return new ContextManagerDummy();
#endif

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "driver/opengl/ContextManagerWebGL.h"
#include "driver/opengl/OpenGLDriver.h"
namespace filament {
using namespace driver;
std::unique_ptr<Driver> ContextManagerWebGL::createDriver(void* const sharedGLContext) noexcept {
return OpenGLDriver::create(this, sharedGLContext);
}
void ContextManagerWebGL::terminate() noexcept {
}
ExternalContext::SwapChain* ContextManagerWebGL::createSwapChain(
void* nativeWindow, uint64_t& flags) noexcept {
return (SwapChain*) nativeWindow;
}
void ContextManagerWebGL::destroySwapChain(ExternalContext::SwapChain* swapChain) noexcept {
}
void ContextManagerWebGL::makeCurrent(ExternalContext::SwapChain* swapChain) noexcept {
}
void ContextManagerWebGL::commit(ExternalContext::SwapChain* swapChain) noexcept {
}
ExternalContext::Fence* ContextManagerWebGL::createFence() noexcept {
Fence* f = new Fence();
return f;
}
void ContextManagerWebGL::destroyFence(Fence* fence) noexcept {
delete fence;
}
driver::FenceStatus ContextManagerWebGL::waitFence(Fence* fence, uint64_t timeout) noexcept {
return driver::FenceStatus::CONDITION_SATISFIED;
}
} // namespace filament

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_CONTEXT_MANAGER_WEBGL_H
#define TNT_FILAMENT_DRIVER_OPENGL_CONTEXT_MANAGER_WEBGL_H
#include <stdint.h>
#include <filament/driver/DriverEnums.h>
#include <filament/driver/ExternalContext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
namespace filament {
class ContextManagerWebGL final : public driver::ContextManagerGL {
public:
std::unique_ptr<Driver> createDriver(void* const sharedGLContext) noexcept override;
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept final override;
void destroySwapChain(SwapChain* swapChain) noexcept final override;
void makeCurrent(SwapChain* swapChain) noexcept final override;
void commit(SwapChain* swapChain) noexcept final override;
Fence* createFence() noexcept final override;
void destroyFence(Fence* fence) noexcept final override;
driver::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final override;
Stream* createStream(void* nativeStream) noexcept final override { return nullptr; }
void destroyStream(Stream* stream) noexcept final override {}
void attach(Stream* stream, intptr_t tname) noexcept final override {}
void detach(Stream* stream) noexcept final override {}
void updateTexImage(Stream* stream) noexcept final override {}
ExternalTexture* createExternalTextureStorage() noexcept final override { return nullptr; }
void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, driver::TextureFormat format) noexcept final override { }
void destroyExternalTextureStorage(ExternalTexture* ets) noexcept final override { }
int getOSVersion() const noexcept final override { return 0; }
};
using ContextManager = filament::ContextManagerWebGL;
} // namespace filament
#endif // TNT_FILAMENT_DRIVER_OPENGL_CONTEXT_MANAGER_WEBGL_H

View File

@@ -2368,7 +2368,7 @@ GLuint OpenGLDriver::getSamplerSlow(driver::SamplerParams params) const noexcept
}
void OpenGLDriver::insertEventMarker(char const* string, size_t len) {
#if GL_EXT_debug_marker
#ifdef GL_EXT_debug_marker
if (ext.EXT_debug_marker) {
glInsertEventMarkerEXT(GLsizei(len ? len : strlen(string)), string);
}
@@ -2376,7 +2376,7 @@ void OpenGLDriver::insertEventMarker(char const* string, size_t len) {
}
void OpenGLDriver::pushGroupMarker(char const* string, size_t len) {
#if GL_EXT_debug_marker
#ifdef GL_EXT_debug_marker
if (ext.EXT_debug_marker) {
glPushGroupMarkerEXT(GLsizei(len ? len : strlen(string)), string);
}
@@ -2384,7 +2384,7 @@ void OpenGLDriver::pushGroupMarker(char const* string, size_t len) {
}
void OpenGLDriver::popGroupMarker(int) {
#if GL_EXT_debug_marker
#ifdef GL_EXT_debug_marker
if (ext.EXT_debug_marker) {
glPopGroupMarkerEXT();
}

View File

@@ -31,7 +31,7 @@
#ifdef GL_OES_EGL_image
extern PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
#endif
#if GL_EXT_debug_marker
#ifdef GL_EXT_debug_marker
extern PFNGLINSERTEVENTMARKEREXTPROC glInsertEventMarkerEXT;
extern PFNGLPUSHGROUPMARKEREXTPROC glPushGroupMarkerEXT;
extern PFNGLPOPGROUPMARKEREXTPROC glPopGroupMarkerEXT;

View File

@@ -110,7 +110,11 @@
#define UTILS_RESTRICT __restrict__
// TODO: set the proper alignment for the target
#ifndef __EMSCRIPTEN__
#define UTILS_ALIGN_LOOP {__asm__ __volatile__(".align 4");}
#else
#define UTILS_ALIGN_LOOP
#endif
#if __has_feature(cxx_thread_local)
# ifdef ANDROID

View File

@@ -22,9 +22,12 @@
#include <algorithm>
#include <memory>
// FIXME: Android doesn't have execinfo.h (but has unwind.h)
#if !defined(ANDROID) && !defined(WIN32)
// FIXME: Some platforms do not have execinfo.h (but have unwind.h)
#if !defined(ANDROID) && !defined(WIN32) && !defined(__EMSCRIPTEN__)
#include <execinfo.h>
#define HAS_EXECINFO 1
#else
#define HAS_EXECINFO 0
#endif
#if !defined(WIN32)
@@ -76,7 +79,7 @@ void CallStack::update_gcc(size_t ignore) noexcept {
ssize_t size = 0;
void *array[NUM_FRAMES];
#if !defined(ANDROID) && !defined(WIN32)
#if HAS_EXECINFO
size = ::backtrace(array, NUM_FRAMES);
size -= ignore;
#endif
@@ -115,7 +118,7 @@ utils::CString CallStack::demangleTypeName(const char* mangled) {
// ------------------------------------------------------------------------------------------------
io::ostream& operator<<(io::ostream& stream, const CallStack& callstack) {
#if !defined(ANDROID) && !defined(WIN32)
#if HAS_EXECINFO
size_t size = callstack.getFrameCount();
for (size_t i = 0; i < size; i++) {
intptr_t pc = callstack[i];