Browse Source

Include pugl wasm code directly, instead of in submodule

Signed-off-by: falkTX <falktx@falktx.com>
pull/397/head
falkTX 2 years ago
parent
commit
24fe04fcbd
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
4 changed files with 1331 additions and 0 deletions
  1. +1032
    -0
      dgl/src/pugl-extra/wasm.c
  2. +45
    -0
      dgl/src/pugl-extra/wasm.h
  3. +228
    -0
      dgl/src/pugl-extra/wasm_gl.c
  4. +26
    -0
      dgl/src/pugl-extra/wasm_stub.c

+ 1032
- 0
dgl/src/pugl-extra/wasm.c
File diff suppressed because it is too large
View File


+ 45
- 0
dgl/src/pugl-extra/wasm.h View File

@@ -0,0 +1,45 @@
// Copyright 2012-2022 David Robillard <d@drobilla.net>
// Copyright 2021-2022 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: ISC

#ifndef PUGL_SRC_WASM_H
#define PUGL_SRC_WASM_H

// #include "attributes.h"
#include "types.h"

#include "pugl/pugl.h"

// #define PUGL_WASM_ASYNC_CLIPBOARD

struct PuglTimer {
PuglView* view;
uintptr_t id;
};

struct PuglWorldInternalsImpl {
double scaleFactor;
};

struct LastMotionValues {
double x, y, xRoot, yRoot;
};

struct PuglInternalsImpl {
PuglSurface* surface;
bool needsRepaint;
bool pointerLocked;
uint32_t numTimers;
LastMotionValues lastMotion;
long buttonPressTimeout;
PuglEvent nextButtonEvent;
#ifdef PUGL_WASM_ASYNC_CLIPBOARD
PuglViewHintValue supportsClipboardRead;
PuglViewHintValue supportsClipboardWrite;
#endif
PuglViewHintValue supportsTouch;
char* clipboardData;
struct PuglTimer* timers;
};

#endif // PUGL_SRC_WASM_H

+ 228
- 0
dgl/src/pugl-extra/wasm_gl.c View File

@@ -0,0 +1,228 @@
// Copyright 2012-2022 David Robillard <d@drobilla.net>
// Copyright 2021-2022 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: ISC

#include "stub.h"
#include "wasm.h"

#include "pugl/pugl.h"

#include <stdio.h>
#include <stdlib.h>

#include <EGL/egl.h>

// for performance reasons we can keep a single EGL context always active
#define PUGL_WASM_SINGLE_EGL_CONTEXT

typedef struct {
EGLDisplay display;
EGLConfig config;
EGLContext context;
EGLSurface surface;
} PuglWasmGlSurface;

static EGLint
puglWasmGlHintValue(const int value)
{
return value == PUGL_DONT_CARE ? EGL_DONT_CARE : value;
}

static int
puglWasmGlGetAttrib(const EGLDisplay display,
const EGLConfig config,
const EGLint attrib)
{
EGLint value = 0;
eglGetConfigAttrib(display, config, attrib, &value);
return value;
}

static PuglStatus
puglWasmGlConfigure(PuglView* view)
{
PuglInternals* const impl = view->impl;

const EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

if (display == EGL_NO_DISPLAY) {
return PUGL_CREATE_CONTEXT_FAILED;
}

int major, minor;
if (eglInitialize(display, &major, &minor) != EGL_TRUE) {
return PUGL_CREATE_CONTEXT_FAILED;
}

EGLConfig config;
int numConfigs;

if (eglGetConfigs(display, &config, 1, &numConfigs) != EGL_TRUE || numConfigs != 1) {
eglTerminate(display);
return PUGL_CREATE_CONTEXT_FAILED;
}

// clang-format off
const EGLint attrs[] = {
/*
GLX_X_RENDERABLE, True,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
EGL_SAMPLE_BUFFERS, view->hints[PUGL_MULTI_SAMPLE] ? 1 : 0,
*/
EGL_SAMPLES, puglWasmGlHintValue(view->hints[PUGL_SAMPLES]),
EGL_RED_SIZE, puglWasmGlHintValue(view->hints[PUGL_RED_BITS]),
EGL_GREEN_SIZE, puglWasmGlHintValue(view->hints[PUGL_GREEN_BITS]),
EGL_BLUE_SIZE, puglWasmGlHintValue(view->hints[PUGL_BLUE_BITS]),
EGL_ALPHA_SIZE, puglWasmGlHintValue(view->hints[PUGL_ALPHA_BITS]),
EGL_DEPTH_SIZE, puglWasmGlHintValue(view->hints[PUGL_DEPTH_BITS]),
EGL_STENCIL_SIZE, puglWasmGlHintValue(view->hints[PUGL_STENCIL_BITS]),
EGL_NONE
};
// clang-format on

if (eglChooseConfig(display, attrs, &config, 1, &numConfigs) != EGL_TRUE || numConfigs != 1) {
eglTerminate(display);
return PUGL_CREATE_CONTEXT_FAILED;
}

PuglWasmGlSurface* const surface =
(PuglWasmGlSurface*)calloc(1, sizeof(PuglWasmGlSurface));
impl->surface = surface;

surface->display = display;
surface->config = config;
surface->context = EGL_NO_SURFACE;
surface->surface = EGL_NO_CONTEXT;

view->hints[PUGL_RED_BITS] =
puglWasmGlGetAttrib(display, config, EGL_RED_SIZE);
view->hints[PUGL_GREEN_BITS] =
puglWasmGlGetAttrib(display, config, EGL_GREEN_SIZE);
view->hints[PUGL_BLUE_BITS] =
puglWasmGlGetAttrib(display, config, EGL_BLUE_SIZE);
view->hints[PUGL_ALPHA_BITS] =
puglWasmGlGetAttrib(display, config, EGL_ALPHA_SIZE);
view->hints[PUGL_DEPTH_BITS] =
puglWasmGlGetAttrib(display, config, EGL_DEPTH_SIZE);
view->hints[PUGL_STENCIL_BITS] =
puglWasmGlGetAttrib(display, config, EGL_STENCIL_SIZE);
view->hints[PUGL_SAMPLES] =
puglWasmGlGetAttrib(display, config, EGL_SAMPLES);

// double-buffering is always enabled for EGL
view->hints[PUGL_DOUBLE_BUFFER] = 1;

return PUGL_SUCCESS;
}

PUGL_WARN_UNUSED_RESULT
static PuglStatus
puglWasmGlEnter(PuglView* view, const PuglExposeEvent* PUGL_UNUSED(expose))
{
PuglWasmGlSurface* const surface = (PuglWasmGlSurface*)view->impl->surface;
if (!surface || !surface->context || !surface->surface) {
return PUGL_FAILURE;
}

#ifndef PUGL_WASM_SINGLE_EGL_CONTEXT
return eglMakeCurrent(surface->display, surface->surface, surface->surface, surface->context) ? PUGL_SUCCESS : PUGL_FAILURE;
#else
return PUGL_SUCCESS;
#endif
}

PUGL_WARN_UNUSED_RESULT
static PuglStatus
puglWasmGlLeave(PuglView* view, const PuglExposeEvent* expose)
{
PuglWasmGlSurface* const surface = (PuglWasmGlSurface*)view->impl->surface;

if (expose) { // note: swap buffers always enabled for EGL
eglSwapBuffers(surface->display, surface->surface);
}

#ifndef PUGL_WASM_SINGLE_EGL_CONTEXT
return eglMakeCurrent(surface->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ? PUGL_SUCCESS : PUGL_FAILURE;
#else
return PUGL_SUCCESS;
#endif
}

static PuglStatus
puglWasmGlCreate(PuglView* view)
{
PuglWasmGlSurface* const surface = (PuglWasmGlSurface*)view->impl->surface;
const EGLDisplay display = surface->display;
const EGLConfig config = surface->config;

const EGLint attrs[] = {
EGL_CONTEXT_CLIENT_VERSION,
view->hints[PUGL_CONTEXT_VERSION_MAJOR],

EGL_CONTEXT_MAJOR_VERSION,
view->hints[PUGL_CONTEXT_VERSION_MAJOR],

/*
EGL_CONTEXT_MINOR_VERSION,
view->hints[PUGL_CONTEXT_VERSION_MINOR],

EGL_CONTEXT_OPENGL_DEBUG,
(view->hints[PUGL_USE_DEBUG_CONTEXT] ? EGL_TRUE : EGL_FALSE),

EGL_CONTEXT_OPENGL_PROFILE_MASK,
(view->hints[PUGL_USE_COMPAT_PROFILE]
? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT
: EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT),
*/

EGL_NONE
};

surface->context = eglCreateContext(display, config, EGL_NO_CONTEXT, attrs);

if (surface->context == EGL_NO_CONTEXT) {
return PUGL_CREATE_CONTEXT_FAILED;
}

surface->surface = eglCreateWindowSurface(display, config, 0, NULL);

if (surface->surface == EGL_NO_SURFACE) {
return PUGL_CREATE_CONTEXT_FAILED;
}

#ifdef PUGL_WASM_SINGLE_EGL_CONTEXT
eglMakeCurrent(surface->display, surface->surface, surface->surface, surface->context);
#endif

return PUGL_SUCCESS;
}

static void
puglWasmGlDestroy(PuglView* view)
{
PuglWasmGlSurface* surface = (PuglWasmGlSurface*)view->impl->surface;
if (surface) {
const EGLDisplay display = surface->display;
if (surface->surface != EGL_NO_SURFACE)
eglDestroySurface(display, surface->surface);
if (surface->context != EGL_NO_CONTEXT)
eglDestroyContext(display, surface->context);
eglTerminate(display);
free(surface);
view->impl->surface = NULL;
}
}

const PuglBackend*
puglGlBackend(void)
{
static const PuglBackend backend = {puglWasmGlConfigure,
puglWasmGlCreate,
puglWasmGlDestroy,
puglWasmGlEnter,
puglWasmGlLeave,
puglStubGetContext};
return &backend;
}

+ 26
- 0
dgl/src/pugl-extra/wasm_stub.c View File

@@ -0,0 +1,26 @@
// Copyright 2012-2022 David Robillard <d@drobilla.net>
// Copyright 2021-2022 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: ISC

#include "pugl/stub.h"

#include "stub.h"
// #include "types.h"
// #include "wasm.h"

#include "pugl/pugl.h"

const PuglBackend*
puglStubBackend(void)
{
static const PuglBackend backend = {
puglStubConfigure,
puglStubCreate,
puglStubDestroy,
puglStubEnter,
puglStubLeave,
puglStubGetContext,
};

return &backend;
}

Loading…
Cancel
Save