aboutsummaryrefslogtreecommitdiffstats
path: root/main/xorg-server/xwayland-glx.patch
diff options
context:
space:
mode:
authorLeo <thinkabit.ukim@gmail.com>2019-12-14 18:34:31 +0100
committerLeo <thinkabit.ukim@gmail.com>2020-03-29 15:50:11 +0000
commit653fa49568caedccb992c0fd89c6497b6a683576 (patch)
treea8997af7762f9415dabfd06698c4ce473a9fd749 /main/xorg-server/xwayland-glx.patch
parentbf07e823f55d63193b32450022b0098c03f73c9d (diff)
downloadaports-653fa49568caedccb992c0fd89c6497b6a683576.tar.gz
aports-653fa49568caedccb992c0fd89c6497b6a683576.tar.bz2
aports-653fa49568caedccb992c0fd89c6497b6a683576.tar.xz
main/xorg-server: switch to meson and add GLX provider for xwayland
- Switch to meson - Add patch for an GLX provider based on EGL - Clean up APKBUILD by removing stuff that is done automatically like the suid wrapper
Diffstat (limited to 'main/xorg-server/xwayland-glx.patch')
-rw-r--r--main/xorg-server/xwayland-glx.patch419
1 files changed, 419 insertions, 0 deletions
diff --git a/main/xorg-server/xwayland-glx.patch b/main/xorg-server/xwayland-glx.patch
new file mode 100644
index 0000000000..c6a750af70
--- /dev/null
+++ b/main/xorg-server/xwayland-glx.patch
@@ -0,0 +1,419 @@
+diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
+index 36bf213..c8746e5 100644
+--- a/hw/xwayland/meson.build
++++ b/hw/xwayland/meson.build
+@@ -54,6 +54,9 @@ xwayland_glamor = []
+ eglstream_srcs = []
+ if build_glamor
+ srcs += 'xwayland-glamor.c'
++ if build_glx
++ srcs += 'xwayland-glx.c'
++ endif
+ if gbm_dep.found()
+ srcs += 'xwayland-glamor-gbm.c'
+ endif
+@@ -80,10 +83,15 @@ if build_glamor
+ xwayland_glamor += glamor
+ endif
+
++wayland_inc = [ inc, ]
++if build_glx
++ wayland_inc += glx_inc
++endif
++
+ executable(
+ 'Xwayland',
+ srcs,
+- include_directories: inc,
++ include_directories: wayland_inc,
+ dependencies: [
+ common_dep,
+ xwayland_dep,
+diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
+index 48e330a..dcfc7f1 100644
+--- a/hw/xwayland/xwayland-glamor.c
++++ b/hw/xwayland/xwayland-glamor.c
+@@ -31,6 +31,9 @@
+
+ #include <glamor.h>
+ #include <glamor_context.h>
++#ifdef GLXEXT
++#include "glx_extinit.h"
++#endif
+
+ static void
+ glamor_egl_make_current(struct glamor_context *glamor_ctx)
+@@ -262,5 +265,9 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
+ ErrorF("Failed to initialize glamor Xv extension\n");
+ #endif
+
++#ifdef GLXEXT
++ GlxPushProvider(&glamor_provider);
++#endif
++
+ return TRUE;
+ }
+diff --git a/hw/xwayland/xwayland-glx.c b/hw/xwayland/xwayland-glx.c
+new file mode 100644
+index 0000000..71c9aad
+--- /dev/null
++++ b/hw/xwayland/xwayland-glx.c
+@@ -0,0 +1,344 @@
++/*
++ * Copyright © 2019 Red Hat, Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the next
++ * paragraph) shall be included in all copies or substantial portions of the
++ * Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ *
++ * Authors:
++ * Adam Jackson <ajax@redhat.com>
++ */
++
++/*
++ * Sets up GLX capabilities based on the EGL capabilities of the glamor
++ * renderer for the screen. Without this you will get whatever swrast
++ * can do, which often does not include things like multisample visuals.
++ */
++
++#include <xwayland-config.h>
++#include "xwayland.h"
++#define MESA_EGL_NO_X11_HEADERS
++// #include <EGL/egl.h>
++#include <epoxy/egl.h>
++#include "glxserver.h"
++#include "glxutil.h"
++#include "compint.h"
++#include <X11/extensions/composite.h>
++#include "glamor_context.h"
++#include "glamor.h"
++
++/* Can't get these from <GL/glx.h> since it pulls in client headers */
++#define GLX_RGBA_BIT 0x00000001
++#define GLX_WINDOW_BIT 0x00000001
++#define GLX_PIXMAP_BIT 0x00000002
++#define GLX_PBUFFER_BIT 0x00000004
++#define GLX_NONE 0x8000
++#define GLX_SLOW_CONFIG 0x8001
++#define GLX_TRUE_COLOR 0x8002
++#define GLX_DIRECT_COLOR 0x8003
++#define GLX_NON_CONFORMANT_CONFIG 0x800D
++#define GLX_DONT_CARE 0xFFFFFFFF
++#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
++#define GLX_SWAP_UNDEFINED_OML 0x8063
++
++struct egl_config {
++ __GLXconfig base;
++ EGLConfig config;
++};
++
++struct egl_screen {
++ __GLXscreen base;
++ EGLDisplay display;
++ EGLConfig *configs;
++};
++
++static void
++egl_screen_destroy(__GLXscreen *_screen)
++{
++ struct egl_screen *screen = (struct egl_screen *)_screen;
++
++ /* XXX do we leak the fbconfig list? */
++
++ free(screen->configs);
++ __glXScreenDestroy(_screen);
++ free(_screen);
++}
++
++static void
++egl_drawable_destroy(__GLXdrawable *draw)
++{
++ free(draw);
++}
++
++static GLboolean
++egl_drawable_swap_buffers(ClientPtr client, __GLXdrawable *draw)
++{
++ return GL_FALSE;
++}
++
++static void
++egl_drawable_copy_sub_buffer(__GLXdrawable *draw, int x, int y, int w, int h)
++{
++}
++
++static void
++egl_drawable_wait_x(__GLXdrawable *draw)
++{
++ glamor_block_handler(draw->pDraw->pScreen);
++}
++
++static void
++egl_drawable_wait_gl(__GLXdrawable *draw)
++{
++}
++
++static __GLXdrawable *
++egl_create_glx_drawable(ClientPtr client, __GLXscreen *screen,
++ DrawablePtr draw, XID drawid, int type,
++ XID glxdrawid, __GLXconfig *modes)
++{
++ __GLXdrawable *ret;
++
++ ret = calloc(1, sizeof *ret);
++ if (!ret)
++ return NULL;
++
++ if (!__glXDrawableInit(ret, screen, draw, type, glxdrawid, modes)) {
++ free(ret);
++ return NULL;
++ }
++
++ ret->destroy = egl_drawable_destroy;
++ ret->swapBuffers = egl_drawable_swap_buffers;
++ ret->copySubBuffer = egl_drawable_copy_sub_buffer;
++ ret->waitX = egl_drawable_wait_x;
++ ret->waitGL = egl_drawable_wait_gl;
++
++ return ret;
++}
++
++/*
++ * TODO:
++ *
++ * - figure out sRGB
++ * - bindToTextureTargets is suspicious
++ * - better channel mask setup
++ * - drawable type masks is suspicious
++ */
++static struct egl_config *
++translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
++ struct egl_config *chain, Bool direct_color,
++ Bool double_buffer)
++{
++ EGLint value;
++ struct egl_config *c = calloc(1, sizeof *c);
++
++ if (!c)
++ return chain;
++
++ /* constants. changing these requires (at least) new EGL extensions */
++ c->base.stereoMode = GL_FALSE;
++ c->base.numAuxBuffers = 0;
++ c->base.level = 0;
++ c->base.transparentAlpha = 0;
++ c->base.transparentIndex = 0;
++ c->base.transparentPixel = GLX_NONE;
++ c->base.visualSelectGroup = 0;
++ c->base.indexBits = 0;
++ c->base.optimalPbufferWidth = 0;
++ c->base.optimalPbufferHeight = 0;
++ c->base.bindToMipmapTexture = 0;
++ c->base.bindToTextureTargets = GLX_DONT_CARE;
++ c->base.sRGBCapable = 0;
++ c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
++
++ /* this is... suspect */
++ c->base.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
++
++ /* hmm */
++ c->base.bindToTextureRgb = GL_TRUE;
++ c->base.bindToTextureRgba = GL_TRUE;
++
++ /*
++ * glx conformance failure: there's no such thing as accumulation
++ * buffers in EGL. they should be emulable with shaders and fbos,
++ * but i'm pretty sure nobody's using this feature since it's
++ * entirely software. note that glx conformance merely requires
++ * that an accum buffer _exist_, not a minimum bitness.
++ */
++ c->base.accumRedBits = 0;
++ c->base.accumGreenBits = 0;
++ c->base.accumBlueBits = 0;
++ c->base.accumAlphaBits = 0;
++
++ /* parametric state */
++ if (direct_color)
++ c->base.visualType = GLX_DIRECT_COLOR;
++ else
++ c->base.visualType = GLX_TRUE_COLOR;
++
++ if (double_buffer)
++ c->base.doubleBufferMode = GL_TRUE;
++ else
++ c->base.doubleBufferMode = GL_FALSE;
++
++ /* direct-mapped state */
++#define GET(attr, slot) \
++ eglGetConfigAttrib(screen->display, hc, attr, &c->base.slot)
++ GET(EGL_RED_SIZE, redBits);
++ GET(EGL_GREEN_SIZE, greenBits);
++ GET(EGL_BLUE_SIZE, blueBits);
++ GET(EGL_ALPHA_SIZE, alphaBits);
++ GET(EGL_BUFFER_SIZE, rgbBits);
++ GET(EGL_DEPTH_SIZE, depthBits);
++ GET(EGL_STENCIL_SIZE, stencilBits);
++ GET(EGL_TRANSPARENT_RED_VALUE, transparentRed);
++ GET(EGL_TRANSPARENT_GREEN_VALUE, transparentGreen);
++ GET(EGL_TRANSPARENT_BLUE_VALUE, transparentBlue);
++ GET(EGL_SAMPLE_BUFFERS, sampleBuffers);
++ GET(EGL_SAMPLES, samples);
++ if (c->base.renderType & GLX_PBUFFER_BIT) {
++ GET(EGL_MAX_PBUFFER_WIDTH, maxPbufferWidth);
++ GET(EGL_MAX_PBUFFER_HEIGHT, maxPbufferHeight);
++ GET(EGL_MAX_PBUFFER_PIXELS, maxPbufferPixels);
++ }
++#undef GET
++
++ /* derived state: config caveats */
++ eglGetConfigAttrib(screen->display, hc, EGL_CONFIG_CAVEAT, &value);
++ if (value == EGL_NONE)
++ c->base.visualRating = GLX_NONE;
++ else if (value == EGL_SLOW_CONFIG)
++ c->base.visualRating = GLX_SLOW_CONFIG;
++ else if (value == EGL_NON_CONFORMANT_CONFIG)
++ c->base.visualRating = GLX_NON_CONFORMANT_CONFIG;
++ /* else panic */
++
++ /* derived state: float configs */
++ c->base.renderType = GLX_RGBA_BIT;
++ if (eglGetConfigAttrib(screen->display, hc, EGL_COLOR_COMPONENT_TYPE_EXT,
++ &value) == EGL_TRUE) {
++ if (value == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) {
++ c->base.renderType = GLX_RGBA_FLOAT_BIT_ARB;
++ }
++ /* else panic */
++ }
++
++ /* map to the backend's config */
++ c->config = hc;
++
++ /*
++ * XXX do something less ugly
++ */
++ if (c->base.renderType == GLX_RGBA_BIT) {
++ if (c->base.rgbBits == 24 || c->base.rgbBits == 32) {
++ c->base.redMask = 0xff0000;
++ c->base.greenMask = 0x00ff00;
++ c->base.blueMask = 0x0000ff;
++ if (c->base.alphaBits)
++ /* assume all remaining bits are alpha */
++ c->base.alphaMask = 0xff000000;
++ }
++ }
++
++ c->base.next = chain ? &chain->base : NULL;
++ return c;
++}
++
++static __GLXconfig *
++egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen)
++{
++ int i, j, k, nconfigs;
++ struct egl_config *c = NULL;
++ EGLConfig *host_configs = NULL;
++ Bool offon[] = { FALSE, TRUE };
++
++ eglGetConfigs(screen->display, NULL, 0, &nconfigs);
++ if (!(host_configs = calloc(nconfigs, sizeof *host_configs)))
++ return NULL;
++
++ eglGetConfigs(screen->display, host_configs, nconfigs, &nconfigs);
++
++ /* We walk the EGL configs backwards to make building the
++ * ->next chain easier.
++ */
++ for (i = nconfigs - 1; i > 0; i--)
++ for (j = 0; j < 2; j++) /* direct_color */
++ for (k = 0; k < 2; k++) /* direct_color */
++ c = translate_eglconfig(screen, host_configs[i], c,
++ /* direct_color */ offon[j],
++ /* double_buffer */ offon[k]
++ );
++
++ screen->configs = host_configs;
++ return c ? &c->base : NULL;
++}
++
++static __GLXscreen *
++egl_screen_probe(ScreenPtr pScreen)
++{
++ struct egl_screen *screen;
++ struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
++ __GLXscreen *base;
++
++ if (enableIndirectGLX)
++ return NULL; /* not implemented */
++
++ if (!(screen = calloc(1, sizeof *screen)))
++ return NULL;
++
++ base = &screen->base;
++ base->destroy = egl_screen_destroy;
++ base->createDrawable = egl_create_glx_drawable;
++ /* base.swapInterval = NULL; */
++
++ screen->display = xwl_screen->glamor_ctx->display;
++
++ __glXInitExtensionEnableBits(screen->base.glx_enable_bits);
++ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_context_flush_control");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_no_error");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_profile");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_robustness");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_fbconfig_float");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es2_profile");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es_profile");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_fbconfig_packed_float");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_framebuffer_sRGB");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_no_config_context");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_texture_from_pixmap");
++ __glXEnableExtension(base->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
++ // __glXEnableExtension(base->glx_enable_bits, "GLX_SGI_swap_control");
++
++ base->fbconfigs = egl_mirror_configs(pScreen, screen);
++ if (!base->fbconfigs) {
++ free(screen);
++ return NULL;
++ }
++
++ __glXScreenInit(base, pScreen);
++ __glXsetGetProcAddress(eglGetProcAddress);
++
++ return base;
++}
++
++__GLXprovider glamor_provider = {
++ egl_screen_probe,
++ "glamor",
++ NULL
++};
+diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
+index 0854df4..a4804fe 100644
+--- a/hw/xwayland/xwayland.h
++++ b/hw/xwayland/xwayland.h
+@@ -488,4 +488,9 @@ static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
+ }
+ #endif
+
++#ifdef GLXEXT
++#include "glx_extinit.h"
++extern __GLXprovider glamor_provider;
++#endif
++
+ #endif