build: scope ABI-staleness invalidation to the config being built

The relibc-consumer ABI sweep looped over the whole shared repo/*.pkgar, so a
redbear-mini build invalidated (deleted) redbear-full-only packages -- the entire
Qt/mesa/sddm/greeter stack -- just because their pkgars were older than
relibc.pkgar. Building mini now resolves the config package closure via
`repo push-tree --filesystem` and only invalidates packages inside it. Build
mini, touch mini; full artifacts are never collateral. No env flag needed for
the common case.
This commit is contained in:
2026-07-25 07:14:09 +09:00
parent 4822c85e5c
commit 087cae5d35
10 changed files with 11302 additions and 2 deletions
+2 -2
View File
@@ -93,8 +93,8 @@ cookbook_meson \
-Dglx=disabled \
-Dgallium-drivers=softpipe,llvmpipe,virgl,iris,radeonsi \
-Dllvm=enabled \
-Dplatforms=wayland \
-Degl-native-platform=surfaceless \
-Dplatforms=wayland,redox \
-Degl-native-platform=redox \
-Dshader-cache=disabled \
-Dc_args="['-include','alloca.h','-DCLOCK_MONOTONIC_RAW=(CLOCK_MONOTONIC+1000)','-Wno-error=implicit-function-declaration','-Wno-error=missing-prototypes','-Wno-error=return-type','-Wno-error=empty-body','-Wno-error=incompatible-pointer-types','-Wno-error=int-conversion','-Wno-error=format','-Wno-error','-std=gnu11','-Dstatic_assert=_Static_assert']" \
-Dcpp_args="['-include','alloca.h','-Wno-error=implicit-function-declaration','-Wno-error=missing-prototypes','-Wno-error=return-type','-Wno-error=empty-body','-Wno-error=incompatible-pointer-types','-Wno-error=int-conversion','-Wno-error=format','-Wno-error']" \
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,881 @@
# Copyright © 2017-2019 Intel Corporation
# SPDX-License-Identifier: MIT
option(
'split-debug',
type : 'feature',
value : 'disabled',
description : 'split debug information (-gsplit-dwarf compile flag) and debug information in the gdb index format (--gdb-index)',
)
option(
'platforms',
type : 'array',
value : ['auto'],
choices : [
'auto', 'x11', 'wayland', 'haiku', 'android', 'windows', 'macos', 'redox',
],
description : 'window systems to support. If this is set to `auto`, all ' +
'platforms applicable will be enabled.'
)
option(
'egl-native-platform',
type : 'combo',
value : 'auto',
choices : [
'auto', 'x11', 'wayland', 'haiku', 'android', 'windows',
'surfaceless', 'drm', 'redox',
],
description : 'the window system EGL assumes for EGL_DEFAULT_DISPLAY',
)
option(
'android-stub',
type : 'boolean',
value : false,
description : 'Build against android-stub',
)
option(
'android-strict',
type : 'boolean',
value : true,
description : 'Enable strict Android compliance. Disabling may cause CTS ' +
'failures or other problems, but allows drivers to expose ' +
'capabilities that are normally hidden. Default: true'
)
option(
'android-libbacktrace',
type : 'feature',
description : 'Use Android\'s libbacktrace',
)
option(
'android-libperfetto',
type : 'feature',
description : 'Use Android\'s libperfetto',
)
option(
'dri-drivers-path',
type : 'string',
value : '',
description : 'Location to install dri drivers. Default: $libdir/dri.'
)
option(
'unversion-libgallium',
type : 'boolean',
value : false,
description : 'Do not include mesa version in libgallium DSO filename. ' +
'Do not enable unless you know what you are doing. Default: false'
)
option(
'expat',
type : 'feature',
value : 'auto',
description : 'Controls the use of expat. ' +
'Cannot be disabled if xmlconfig is enabled.'
)
option(
'gallium-drivers',
type : 'array',
value : ['auto'],
choices : [
'all', 'auto',
'asahi', 'crocus', 'd3d12', 'ethosu', 'etnaviv', 'freedreno', 'i915', 'iris',
'lima', 'llvmpipe', 'nouveau', 'panfrost', 'r300', 'r600', 'radeonsi',
'rocket', 'softpipe', 'svga', 'tegra', 'v3d', 'vc4', 'virgl', 'zink',
],
description : 'List of gallium drivers to build. If this is set to auto ' +
'all drivers applicable to the target OS/architecture ' +
'will be built.'
)
option(
'gallium-extra-hud',
type : 'boolean',
value : false,
description : 'Enable HUD block/NIC I/O HUD status support',
)
option(
'gallium-va',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'enable gallium va frontend.',
)
option(
'gallium-mediafoundation',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'enable gallium mediafoundation frontend.',
)
option(
'gallium-mediafoundation-test',
type : 'boolean',
value : false,
description : 'enable gallium mediafoundation frontend tests.',
)
option(
'va-libs-path',
type : 'string',
value : '',
description : 'path to put va libraries. defaults to $libdir/dri.'
)
option(
'gallium-d3d10umd',
type : 'boolean',
value : false,
description : 'build gallium D3D10 WDDM UMD frontend.',
)
option(
'gallium-rusticl',
type : 'boolean',
value : false,
description : 'build gallium "rusticl" OpenCL frontend.',
)
option(
'gallium-rusticl-enable-drivers',
type : 'array',
value : ['auto'],
choices : ['auto', 'asahi', 'freedreno', 'radeonsi'],
description : 'List of gallium drivers for which rusticl will be enabled ' +
'by default',
)
option(
'gallium-wgl-dll-name',
type : 'string',
value : 'libgallium_wgl',
description : 'name of gallium wgl target DLL built for Windows. ' +
'defaults to libgallium_wgl.dll to match DRI',
)
option(
'gallium-d3d10-dll-name',
type : 'string',
value : 'libgallium_d3d10',
description : 'name of gallium d3d10 target DLL built for Windows. ' +
'defaults to libgallium_d3d10.dll to match DRI',
)
option(
'mediafoundation-store-dll',
type : 'boolean',
value : false,
description : 'Selects whether the gallium mediafoundation DLL is built for the store. ',
)
option(
'mediafoundation-codecs',
type : 'array',
value : ['all'],
choices: [
'all', 'h264enc', 'h265enc', 'av1enc'
],
description : 'List of codecs to build mediafoundation frontend DLLs for. ' +
'These will generate different MFT DLLs per codec and link' +
'against the gallium drivers which uses the video-codecs option'
)
option(
'static-libclc',
type : 'array',
value : [],
choices : ['spirv', 'spirv64', 'all'],
description : 'Link libclc SPIR-V statically.',
)
option(
'd3d-drivers-path',
type : 'string',
value : '',
description : 'Location of D3D drivers. Default: $libdir/d3d',
)
option(
'vulkan-drivers',
type : 'array',
value : ['auto'],
choices : ['auto', 'amd', 'broadcom', 'freedreno', 'intel', 'intel_hasvk',
'panfrost', 'swrast', 'virtio', 'imagination',
'microsoft-experimental', 'nouveau', 'asahi', 'gfxstream',
'kosmickrisp', 'all'],
description : 'List of vulkan drivers to build. If this is set to auto ' +
'all drivers applicable to the target OS/architecture ' +
'will be built'
)
# Note that the freedreno gallium driver doesn't support KGSL.
# On those systems, zink with Turnip should be used instead.
# WSL is only supported for the replay tool.
option(
'freedreno-kmds',
type : 'array',
value : ['msm'],
choices : ['msm', 'kgsl', 'virtio', 'wsl'],
description : 'List of kernel-mode drivers to enable for freedreno ' +
'gallium and vulkan driver',
)
option(
'amdgpu-virtio',
type : 'boolean',
value : false,
description : 'use experimental virtio backend for radeonsi/radv',
)
option(
'imagination-srv',
type : 'boolean',
value : false,
description : 'Enable Services backend for Imagination Technologies ' +
'vulkan driver',
)
option('imagination-uscgen-devices',
type : 'array',
value : [],
choices : ['axe-1-16m', 'bxs-4-64', 'gx6250'],
description : 'List of devices for which to pre-build USC program binaries.',
)
option(
'shader-cache',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build with on-disk shader cache support.',
)
option(
'shader-cache-default',
type : 'boolean',
value : true,
description : 'If set to false, the feature is only activated when ' +
'environment variable MESA_SHADER_CACHE_DISABLE is set ' +
'to false',
)
option(
'shader-cache-max-size',
type : 'string',
value : '',
description : 'Default value for MESA_SHADER_CACHE_MAX_SIZE enviroment ' +
'variable. If set, determines the maximum size of the ' +
'on-disk cache of compiled shader programs, can be overriden ' +
'by enviroment variable if needed. Should be set to a number ' +
'optionally followed by ``K``, ``M``, or ``G`` to specify ' +
'a size in kilobytes, megabytes, or gigabytes. By default, ' +
'gigabytes will be assumed. And if unset, a maximum size of ' +
'1GB will be used.'
)
option(
'vulkan-icd-dir',
type : 'string',
value : '',
description : 'Location relative to prefix to put vulkan icds on install. ' +
'Default: $datadir/vulkan/icd.d'
)
option(
'vulkan-manifest-per-architecture',
type : 'boolean',
value : true,
description : 'If true, Vulkan ICDs have a separate JSON manifest per ' +
'architecture, for example lvp_icd.x86_64.json. ' +
'(Recommended for non-default ${prefix}.) ' +
'If false, all architectures share a single JSON manifest, ' +
'for example lvp_icd.json, referencing the library by its ' +
'basename. ' +
'(Recommended for Unix OS distros installing into /usr.)'
)
option(
'moltenvk-dir',
type : 'string',
value : '',
description : 'Location of the MoltenVk SDK. Default: '
)
option(
'vulkan-layers',
type : 'array',
value : [],
choices : [
'device-select', 'intel-nullhw', 'overlay', 'screenshot', 'anti-lag',
'vram-report-limit',
],
description : 'List of vulkan layers to build'
)
option(
'shared-glapi',
type : 'feature',
deprecated: true,
description : 'Does nothing, left here for a while to avoid build breakages.',
)
option(
'gles1',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build support for OpenGL ES 1.x'
)
option(
'gles2',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build support for OpenGL ES 2.x and 3.x'
)
option(
'opengl',
type : 'boolean',
value : true,
description : 'Build support for desktop OpenGL'
)
option(
'gbm',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build support for gbm platform'
)
option(
'libgbm-external',
type: 'boolean',
value: false,
description: 'Whether to use external libgbm (default: use in-tree copy)'
)
option(
'gbm-backends-path',
type : 'string',
value : '',
description : 'Locations to search for gbm backends, passed as colon ' +
'separated list. Default: $libdir/gbm.'
)
option(
'glx',
type : 'combo',
value : 'auto',
choices : ['auto', 'disabled', 'dri', 'xlib'],
description : 'Build support for GLX platform'
)
option(
'egl',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build support for EGL platform'
)
option(
'glvnd',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Enable GLVND support.'
)
option(
'microsoft-clc',
type : 'feature',
value : 'auto',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build support for the Microsoft CLC to DXIL compiler'
)
option(
'spirv-to-dxil',
type : 'boolean',
value : false,
description : 'Build support for the SPIR-V to DXIL library'
)
option(
'glvnd-vendor-name',
type : 'string',
value : 'mesa',
description : 'Vendor name string to use for glvnd libraries'
)
option(
'glx-read-only-text',
type : 'boolean',
value : false,
description : 'Disable writable .text section on x86 (decreases performance)'
)
option(
'llvm',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build with LLVM support.'
)
option(
'shared-llvm',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Whether to link LLVM shared or statically.'
)
option(
'draw-use-llvm',
type : 'boolean',
value : true,
description : 'Whether to use LLVM for the Gallium draw module, if LLVM ' +
'is included.'
)
option(
'amd-use-llvm',
type : 'boolean',
value : true,
description : 'Whether to use LLVM for the AMD drivers, if LLVM ' +
'is included.'
)
option (
'llvm-orcjit',
type : 'boolean',
value : false,
description: 'Build llvmpipe with LLVM ORCJIT support. Has no effect when ' +
'building for architectures without LLVM MCJIT support -- ' +
'ORCJIT is the only choice on such architectures and will ' +
'always be enabled.'
)
option(
'valgrind',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build with valgrind support'
)
option(
'libunwind',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Use libunwind for stack-traces'
)
option(
'lmsensors',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Enable HUD lmsensors support.'
)
option(
'build-tests',
type : 'boolean',
value : false,
description : 'Build unit tests. Currently this will build *all* unit ' +
'tests except the ACO tests, which may build more than expected.'
)
option(
'enable-glcpp-tests',
type : 'boolean',
value : true,
description : 'Build glcpp unit tests. These are flaky on CI.'
)
option(
'build-radv-tests',
type : 'boolean',
value : false,
description : 'Build RADV tests. These do not require an AMD GPU.'
)
option(
'build-aco-tests',
type : 'boolean',
value : false,
description : 'Build ACO tests. These require RADV and glslang but not ' +
'an AMD GPU.'
)
option(
'install-intel-gpu-tests',
type : 'boolean',
value : false,
description : 'Build and install Intel unit tests which require the GPU. ' +
'This option is for developers and the Intel CI system only.'
)
option(
'html-docs',
type : 'feature',
value : 'disabled',
description : 'Build HTML documentation.'
)
option(
'html-docs-path',
type : 'string',
value : '',
description : 'Location to install HTML documentation. Default: $datadir/doc/mesa.'
)
option(
'selinux',
type : 'boolean',
deprecated : true,
description : 'Does nothing, left here for a while to avoid build breakages.',
)
option(
'execmem',
type : 'boolean',
deprecated : true,
description : 'Does nothing, left here for a while to avoid build breakages.',
)
option(
'tools',
type : 'array',
value : [],
choices : ['drm-shim', 'etnaviv', 'freedreno', 'glsl', 'intel', 'intel-ui',
'nir', 'nouveau', 'lima', 'panfrost', 'asahi', 'imagination',
'zink', 'all', 'dlclose-skip'],
description : 'List of tools to build. (Note: `intel-ui` selects `intel`)',
)
option(
'power8',
type : 'feature',
description : 'Does nothing, left here for a while to avoid build breakages.',
deprecated: true,
)
option(
'xlib-lease',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Enable VK_EXT_acquire_xlib_display.'
)
option(
'glx-direct',
type : 'boolean',
value : true,
description : 'Enable direct rendering in GLX and EGL for DRI',
)
option('egl-lib-suffix',
type : 'string',
value : '',
description : 'Suffix to append to EGL library name. Default: none.'
)
option(
'gles-lib-suffix',
type : 'string',
value : '',
description : 'Suffix to append to GLES library names. Default: none.'
)
option(
'platform-sdk-version',
type : 'integer',
min : 25,
max : 10000,
value : 35,
description : 'Android Platform SDK version. Default: Android15 version.'
)
option(
'allow-kcmp',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Allow using KCMP_FILE to compare file descriptions. ' +
'auto = allowed everywhere except on Android'
)
option(
'zstd',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Use ZSTD instead of ZLIB in some cases.'
)
option(
'zlib',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
value : 'enabled',
description : 'Use ZLIB to build driver. Default: enabled'
)
option(
'display-info',
type : 'feature',
description : 'Use libdisplay-info to build driver.'
)
option(
'sse2',
type : 'boolean',
value : true,
description : 'use msse2 flag for x86. Uses sse/sse2 instead of x87. Default: true',
)
option(
'perfetto',
type : 'boolean',
value : false,
description : 'Enable performance analysis with Perfetto. Default: false'
)
option(
'datasources',
type : 'array',
value : ['auto'],
choices : ['auto', 'panfrost', 'intel', 'freedreno'],
description : 'List of Perfetto datasources to build. If this is set to ' +
'`auto`, datasources that can not be build are skipped. ' +
'Default: [`auto`]'
)
option(
'teflon',
type : 'boolean',
value : false,
description : 'Enable TensorFlow Lite delegate. Default: false'
)
option(
'gpuvis',
type : 'boolean',
value : false,
description : 'Enable tracing markers for gpuvis. Default: false'
)
option(
'sysprof',
type : 'boolean',
value : false,
description : 'Enable tracing markers for sysprof. Default: false'
)
option(
'custom-shader-replacement',
type : 'string',
value : '',
description : 'Enable a custom shader replacement mechanism. Note that ' +
'enabling this option requires adding/generating a ' +
'shader_replacement.h file that can be included (see ' +
'shaderapi.c).'
)
option(
'vmware-mks-stats',
type : 'boolean',
value : false,
description : 'Build gallium VMware/svga driver with mksGuestStats ' +
'instrumentation.'
)
option(
'vulkan-beta',
type : 'boolean',
value : false,
description : 'Build vulkan drivers with BETA extensions enabled.'
)
option(
'intel-rt',
type : 'feature',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build Ray Tracing on supported hardware.'
)
option(
'intel-elk',
type : 'boolean',
value : true,
description : 'Build ELK compiler (used for Gfx8 and earlier). ' +
'This is required for Crocus and Hasvk, and it is ' +
'optional for Iris and various developer tools.'
)
option(
'video-codecs',
type : 'array',
value : ['all_free'],
choices: [
'all', 'all_free', 'vc1dec', 'h264dec', 'h264enc', 'h265dec', 'h265enc',
'av1dec', 'av1enc', 'vp9dec', 'mpeg12dec', 'jpegdec'
],
description : 'List of codecs to build support for. ' +
'Distros might want to consult their legal department before ' +
'enabling these. This is used for all video APIs (vaapi, ' +
'vulkan). Non-patent encumbered codecs will be ' +
'enabled by default with the all_free default value.'
)
option(
'gallium-d3d12-video',
type : 'feature',
value : 'auto',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'build gallium d3d12 with video support.',
)
option(
'gallium-d3d12-graphics',
type : 'feature',
value : 'auto',
description : 'build gallium d3d12 with graphics pipeline support.',
)
option(
'radv-build-id',
type : 'string',
value : '',
description : 'Override build id for shader cache keys (hex string). ' +
'Can be extracted with readelf -x .note.gnu.build-id'
)
option(
'radeonsi-build-id',
type : 'string',
value : '',
description : 'Override build id for shader cache keys (hex string). ' +
'Can be extracted with readelf -x .note.gnu.build-id'
)
option(
'min-windows-version',
type : 'integer',
min : 7,
max : 11,
value : 8,
description : 'Minimum Windows version to support. Defaults to Windows 8.'
)
option(
'xmlconfig',
type : 'feature',
value : 'auto',
deprecated: {'true': 'enabled', 'false': 'disabled'},
description : 'Build custom xmlconfig (driconf) support. If disabled, ' +
'the default driconf file is hardcoded into Mesa. ' +
'Requires expat.'
)
option(
'legacy-wayland',
type : 'array',
value : [],
description : 'Build legacy Wayland support features.',
choices : [
'bind-wayland-display',
],
)
option(
'legacy-x11',
type : 'array',
value : [],
description : 'Build legacy X11 support features.',
deprecated : true,
choices : [
],
)
option(
'mesa-clc',
type : 'combo',
value : 'auto',
choices : [
'enabled', 'system', 'auto'
],
description : 'Build the mesa-clc compiler or use a system version.'
)
option(
'install-mesa-clc',
type : 'boolean',
value : false,
description : 'Install the mesa-clc compiler (if needed for cross builds).'
)
option(
'mesa-clc-bundle-headers',
type : 'combo',
value : 'auto',
choices : [
'enabled', 'auto'
],
description : 'Bundle the OpenCL headers into the mesa-clc binary (default to bundle if static LLVM is used). Note, it might require rebuilding mesa-clc if opencl-c.h or opencl-c-base.h are changed (e.g. on Clang upgrades).'
)
option(
'precomp-compiler',
type : 'combo',
value : 'auto',
choices : [
'enabled', 'system', 'auto'
],
description : 'Build drivers internal shader compilers or use a system version'
)
option(
'install-precomp-compiler',
type : 'boolean',
value : false,
description : 'Install the drivers internal shader compilers (if needed for cross builds).'
)
option(
'allow-fallback-for',
type : 'array',
value : ['perfetto'],
choices : [
'libdrm', 'libva', 'perfetto',
],
description : 'Allows the fallback mechanism if the dependency is not available on the system, or too old.'
)
option(
'virtgpu_kumquat',
type : 'boolean',
value : false,
description : 'Build virtgpu_kumquat (only useful with gfxstream currently)'
)
option(
'spirv-tools',
type : 'feature',
description : 'Use SPIRV-Tools for dumping SPIR-V for debugging purposes (required by CLC)'
)
option(
'allow-broken-lto',
type : 'boolean',
value : false,
description : 'Manual override switch to enable LTO, which is unsupported due to being broken. WARNING: This option may break your driver randomly!'
)
option(
'intel-virtio-experimental',
type : 'boolean',
value : false,
description : 'use experimental virtio backend for intel driver',
)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,298 @@
/*
* Mesa 3-D graphics library
*
* Copyright © 2026 Red Bear OS
*
* SPDX-License-Identifier: MIT
*/
#include <dlfcn.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "egl_dri2.h"
#include "eglglobals.h"
#include "kopper_interface.h"
#include "loader.h"
#include "loader_dri_helper.h"
#include "dri_util.h"
#include "dri_screen.h"
#define REDOX_DRM_DEVICE_PATH "/scheme/drm/card0"
static struct dri_image *
redox_alloc_image(struct dri2_egl_display *dri2_dpy,
struct dri2_egl_surface *dri2_surf)
{
return dri_create_image(dri2_dpy->dri_screen_render_gpu,
dri2_surf->base.Width,
dri2_surf->base.Height,
dri2_surf->visual, NULL, 0, 0, NULL);
}
static void
redox_free_images(struct dri2_egl_surface *dri2_surf)
{
if (dri2_surf->front) {
dri2_destroy_image(dri2_surf->front);
dri2_surf->front = NULL;
}
free(dri2_surf->swrast_device_buffer);
dri2_surf->swrast_device_buffer = NULL;
}
static int
redox_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format,
uint32_t *stamp, void *loaderPrivate,
uint32_t buffer_mask, struct __DRIimageList *buffers)
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
buffers->image_mask = 0;
buffers->front = NULL;
buffers->back = NULL;
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
if (!dri2_surf->front)
dri2_surf->front = redox_alloc_image(dri2_dpy, dri2_surf);
buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
buffers->front = dri2_surf->front;
}
return 1;
}
static void
redox_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate)
{
}
static unsigned
redox_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
{
switch (cap) {
case DRI_LOADER_CAP_FP16:
return 1;
case DRI_LOADER_CAP_RGBA_ORDERING:
return 1;
default:
return 0;
}
}
static const __DRIimageLoaderExtension redox_image_loader_extension = {
.base = {__DRI_IMAGE_LOADER, 2},
.getBuffers = redox_image_get_buffers,
.flushFrontBuffer = redox_flush_front_buffer,
.getCapability = redox_get_capability,
};
static const __DRIextension *image_loader_extensions[] = {
&redox_image_loader_extension.base,
&image_lookup_extension.base,
&use_invalidate.base,
NULL,
};
static const __DRIextension *swrast_loader_extensions[] = {
&swrast_pbuffer_loader_extension.base,
&redox_image_loader_extension.base,
&image_lookup_extension.base,
&use_invalidate.base,
NULL,
};
static const __DRIextension *kopper_loader_extensions[] = {
&kopper_pbuffer_loader_extension.base,
&image_lookup_extension.base,
NULL,
};
static _EGLSurface *
redox_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
struct dri2_egl_surface *dri2_surf;
const struct dri_config *config;
dri2_surf = calloc(1, sizeof *dri2_surf);
if (!dri2_surf) {
_eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
return NULL;
}
if (!dri2_init_surface(&dri2_surf->base, disp, EGL_PBUFFER_BIT, conf,
attrib_list, false, NULL))
goto cleanup_surface;
config = dri2_get_dri_config(dri2_conf, EGL_PBUFFER_BIT,
dri2_surf->base.GLColorspace);
if (!config) {
_eglError(EGL_BAD_MATCH,
"Unsupported surfacetype/colorspace configuration");
goto cleanup_surface;
}
dri2_surf->visual = dri2_image_format_for_pbuffer_config(dri2_dpy, config);
if (dri2_surf->visual == PIPE_FORMAT_NONE)
goto cleanup_surface;
if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf))
goto cleanup_surface;
return &dri2_surf->base;
cleanup_surface:
free(dri2_surf);
return NULL;
}
static EGLBoolean
redox_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
redox_free_images(dri2_surf);
driDestroyDrawable(dri2_surf->dri_drawable);
dri2_fini_surface(surf);
free(dri2_surf);
return EGL_TRUE;
}
static const struct dri2_egl_display_vtbl dri2_redox_display_vtbl = {
.create_pbuffer_surface = redox_create_pbuffer_surface,
.destroy_surface = redox_destroy_surface,
.create_image = dri2_create_image_khr,
.get_dri_drawable = dri2_surface_get_dri_drawable,
.flush_get_images = dri2_flush_get_images_for_swap_buffers_with_damage,
.image_get_buffers = redox_image_get_buffers,
};
static bool
redox_probe_device_hw(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
int fd = -1;
char *driver_name = NULL;
fd = open(REDOX_DRM_DEVICE_PATH, O_RDWR | O_CLOEXEC);
if (fd < 0) {
_eglLog(_EGL_DEBUG, "redox-egl: no DRM device at %s",
REDOX_DRM_DEVICE_PATH);
return false;
}
driver_name = loader_get_driver_for_fd(fd);
if (!driver_name) {
_eglLog(_EGL_WARNING, "redox-egl: loader_get_driver_for_fd failed");
close(fd);
return false;
}
if (strcmp(driver_name, "swrast") == 0 ||
strcmp(driver_name, "kms_swrast") == 0) {
_eglLog(_EGL_DEBUG, "redox-egl: driver is swrast, skipping HW path");
free(driver_name);
close(fd);
return false;
}
dri2_dpy->fd_render_gpu = fd;
dri2_dpy->driver_name = driver_name;
if (!dri2_load_driver_dri3(disp)) {
_eglLog(_EGL_WARNING, "redox-egl: dri2_load_driver_dri3 failed");
free(dri2_dpy->driver_name);
dri2_dpy->driver_name = NULL;
close(dri2_dpy->fd_render_gpu);
dri2_dpy->fd_render_gpu = -1;
return false;
}
dri2_dpy->loader_extensions = kopper_loader_extensions;
return true;
}
static bool
redox_probe_device_sw(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
dri2_dpy->driver_name = strdup("swrast");
if (!dri2_dpy->driver_name)
return false;
dri2_detect_swrast_kopper(disp);
if (dri2_dpy->kopper)
dri2_dpy->loader_extensions = kopper_loader_extensions;
else
dri2_dpy->loader_extensions = swrast_loader_extensions;
dri2_dpy->fd_render_gpu = -1;
dri2_dpy->fd_display_gpu = -1;
if (!dri2_create_screen(disp)) {
_eglLog(_EGL_WARNING, "DRI2: failed to create swrast screen");
free(dri2_dpy->driver_name);
dri2_dpy->driver_name = NULL;
return false;
}
return true;
}
EGLBoolean
dri2_initialize_redox(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy;
bool driver_loaded = false;
dri2_dpy = dri2_display_create();
if (!dri2_dpy)
return _eglError(EGL_BAD_ALLOC, "dri2_display_create");
disp->DriverData = (void *)dri2_dpy;
driver_loaded = redox_probe_device_hw(disp);
if (!driver_loaded) {
_eglLog(_EGL_DEBUG, "redox-egl: HW probe failed, falling back to swrast");
driver_loaded = redox_probe_device_sw(disp);
}
if (!driver_loaded) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to load any driver");
goto cleanup;
}
dri2_dpy->fd_display_gpu = dri2_dpy->fd_render_gpu;
if (dri2_dpy->fd_render_gpu >= 0 && !dri2_create_screen(disp)) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to create screen");
goto cleanup;
}
if (!dri2_setup_extensions(disp)) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find required DRI extensions");
goto cleanup;
}
dri2_setup_screen(disp);
dri2_add_pbuffer_configs_for_visuals(disp);
dri2_dpy->vtbl = &dri2_redox_display_vtbl;
return EGL_TRUE;
cleanup:
dri2_display_destroy(disp);
return EGL_FALSE;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,767 @@
/**************************************************************************
*
* Copyright 2008 VMware, Inc.
* Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
* Copyright 2010-2011 LunarG, Inc.
* All Rights Reserved.
*
* 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, sub license, 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.
*
**************************************************************************/
/**
* Functions related to EGLDisplay.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include <fcntl.h>
#include "c11/threads.h"
#include "util/macros.h"
#include "util/os_file.h"
#include "util/os_misc.h"
#include "util/u_atomic.h"
#include "eglcontext.h"
#include "eglcurrent.h"
#include "egldevice.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "eglimage.h"
#include "egllog.h"
#include "eglsurface.h"
#include "eglsync.h"
/* Includes for _eglNativePlatformDetectNativeDisplay */
#ifdef HAVE_WAYLAND_PLATFORM
#include <wayland-client.h>
#endif
#ifdef HAVE_DRM_PLATFORM
#include <gbm.h>
#endif
#ifdef HAVE_WINDOWS_PLATFORM
#include <windows.h>
#endif
/**
* Map build-system platform names to platform types.
*/
static const struct {
_EGLPlatformType platform;
const char *name;
} egl_platforms[] = {
{_EGL_PLATFORM_X11, "x11"},
{_EGL_PLATFORM_XCB, "xcb"},
{_EGL_PLATFORM_WAYLAND, "wayland"},
{_EGL_PLATFORM_DRM, "drm"},
{_EGL_PLATFORM_ANDROID, "android"},
{_EGL_PLATFORM_HAIKU, "haiku"},
{_EGL_PLATFORM_SURFACELESS, "surfaceless"},
{_EGL_PLATFORM_DEVICE, "device"},
{_EGL_PLATFORM_WINDOWS, "windows"},
{_EGL_PLATFORM_REDOX, "redox"},
};
/**
* Return the native platform by parsing EGL_PLATFORM.
*/
static _EGLPlatformType
_eglGetNativePlatformFromEnv(void)
{
_EGLPlatformType plat = _EGL_INVALID_PLATFORM;
const char *plat_name;
EGLint i;
static_assert(ARRAY_SIZE(egl_platforms) == _EGL_NUM_PLATFORMS,
"Missing platform");
plat_name = os_get_option("EGL_PLATFORM");
/* try deprecated env variable */
if (!plat_name || !plat_name[0])
plat_name = os_get_option("EGL_DISPLAY");
if (!plat_name || !plat_name[0])
return _EGL_INVALID_PLATFORM;
for (i = 0; i < ARRAY_SIZE(egl_platforms); i++) {
if (strcmp(egl_platforms[i].name, plat_name) == 0) {
plat = egl_platforms[i].platform;
break;
}
}
if (plat == _EGL_INVALID_PLATFORM)
_eglLog(_EGL_WARNING, "invalid EGL_PLATFORM given");
return plat;
}
/**
* Try detecting native platform with the help of native display characteristics.
*/
static _EGLPlatformType
_eglNativePlatformDetectNativeDisplay(void *nativeDisplay)
{
if (nativeDisplay == EGL_DEFAULT_DISPLAY)
return _EGL_INVALID_PLATFORM;
#ifdef HAVE_WINDOWS_PLATFORM
if (GetObjectType(nativeDisplay) == OBJ_DC)
return _EGL_PLATFORM_WINDOWS;
#endif
#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM)
if (_eglPointerIsDereferenceable(nativeDisplay)) {
void *first_pointer = *(void **)nativeDisplay;
#ifdef HAVE_WAYLAND_PLATFORM
/* wl_display is a wl_proxy, which is a wl_object.
* wl_object's first element points to the interfacetype. */
if (first_pointer == &wl_display_interface)
return _EGL_PLATFORM_WAYLAND;
#endif
#ifdef HAVE_DRM_PLATFORM
/* gbm has a pointer to its constructor as first element. */
if (first_pointer == gbm_create_device)
return _EGL_PLATFORM_DRM;
#endif
}
#endif
return _EGL_INVALID_PLATFORM;
}
/**
* Return the native platform. It is the platform of the EGL native types.
*/
_EGLPlatformType
_eglGetNativePlatform(void *nativeDisplay)
{
_EGLPlatformType detected_platform = _eglGetNativePlatformFromEnv();
const char *detection_method = "environment";
if (detected_platform == _EGL_INVALID_PLATFORM) {
detected_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay);
detection_method = "autodetected";
}
if (detected_platform == _EGL_INVALID_PLATFORM) {
detected_platform = _EGL_NATIVE_PLATFORM;
detection_method = "build-time configuration";
}
_eglLog(_EGL_DEBUG, "Native platform type: %s (%s)",
egl_platforms[detected_platform].name, detection_method);
return detected_platform;
}
/**
* Finish display management.
*/
void
_eglFiniDisplay(void)
{
_EGLDisplay *dispList, *disp;
/* atexit function is called with global mutex locked */
dispList = _eglGlobal.DisplayList;
while (dispList) {
EGLint i;
/* pop list head */
disp = dispList;
dispList = dispList->Next;
for (i = 0; i < _EGL_NUM_RESOURCES; i++) {
if (disp->ResourceLists[i]) {
_eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", disp);
break;
}
}
/* The fcntl() code in _eglGetDeviceDisplay() ensures that valid fd >= 3,
* and invalid one is 0.
*/
if (disp->Options.fd)
close(disp->Options.fd);
free(disp->Options.Attribs);
free(disp);
}
_eglGlobal.DisplayList = NULL;
}
static EGLBoolean
_eglSameAttribs(const EGLAttrib *a, const EGLAttrib *b)
{
size_t na = _eglNumAttribs(a);
size_t nb = _eglNumAttribs(b);
/* different numbers of attributes must be different */
if (na != nb)
return EGL_FALSE;
/* both lists NULL are the same */
if (!a && !b)
return EGL_TRUE;
/* otherwise, compare the lists */
return memcmp(a, b, na * sizeof(a[0])) == 0 ? EGL_TRUE : EGL_FALSE;
}
/**
* Find the display corresponding to the specified native display, or create a
* new one. EGL 1.5 says:
*
* Multiple calls made to eglGetPlatformDisplay with the same parameters
* will return the same EGLDisplay handle.
*
* We read this extremely strictly, and treat a call with NULL attribs as
* different from a call with attribs only equal to { EGL_NONE }. Similarly
* we do not sort the attribute list, so even if all attribute _values_ are
* identical, different attribute orders will be considered different
* parameters.
*/
_EGLDisplay *
_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy,
const EGLAttrib *attrib_list)
{
_EGLDisplay *disp;
size_t num_attribs;
if (plat == _EGL_INVALID_PLATFORM)
return NULL;
simple_mtx_lock(_eglGlobal.Mutex);
/* search the display list first */
for (disp = _eglGlobal.DisplayList; disp; disp = disp->Next) {
if (disp->Platform == plat && disp->PlatformDisplay == plat_dpy &&
_eglSameAttribs(disp->Options.Attribs, attrib_list))
goto out;
}
/* create a new display */
assert(!disp);
disp = calloc(1, sizeof(_EGLDisplay));
if (!disp)
goto out;
simple_mtx_init(&disp->Mutex, mtx_plain);
u_rwlock_init(&disp->TerminateLock);
disp->Platform = plat;
disp->PlatformDisplay = plat_dpy;
num_attribs = _eglNumAttribs(attrib_list);
if (num_attribs) {
disp->Options.Attribs = calloc(num_attribs, sizeof(EGLAttrib));
if (!disp->Options.Attribs) {
free(disp);
disp = NULL;
goto out;
}
memcpy(disp->Options.Attribs, attrib_list,
num_attribs * sizeof(EGLAttrib));
}
/* add to the display list */
disp->Next = _eglGlobal.DisplayList;
_eglGlobal.DisplayList = disp;
out:
simple_mtx_unlock(_eglGlobal.Mutex);
return disp;
}
/**
* Destroy the contexts and surfaces that are linked to the display.
*/
void
_eglReleaseDisplayResources(_EGLDisplay *display)
{
_EGLResource *list;
const _EGLDriver *drv = display->Driver;
simple_mtx_assert_locked(&display->Mutex);
list = display->ResourceLists[_EGL_RESOURCE_CONTEXT];
while (list) {
_EGLContext *ctx = (_EGLContext *)list;
list = list->Next;
_eglUnlinkContext(ctx);
drv->DestroyContext(display, ctx);
}
assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]);
list = display->ResourceLists[_EGL_RESOURCE_SURFACE];
while (list) {
_EGLSurface *surf = (_EGLSurface *)list;
list = list->Next;
_eglUnlinkSurface(surf);
drv->DestroySurface(display, surf);
}
assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]);
list = display->ResourceLists[_EGL_RESOURCE_IMAGE];
while (list) {
_EGLImage *image = (_EGLImage *)list;
list = list->Next;
_eglUnlinkImage(image);
drv->DestroyImageKHR(display, image);
}
assert(!display->ResourceLists[_EGL_RESOURCE_IMAGE]);
list = display->ResourceLists[_EGL_RESOURCE_SYNC];
while (list) {
_EGLSync *sync = (_EGLSync *)list;
list = list->Next;
_eglUnlinkSync(sync);
drv->DestroySyncKHR(display, sync);
}
assert(!display->ResourceLists[_EGL_RESOURCE_SYNC]);
}
/**
* Free all the data hanging of an _EGLDisplay object, but not
* the object itself.
*/
void
_eglCleanupDisplay(_EGLDisplay *disp)
{
if (disp->Configs) {
_eglDestroyArray(disp->Configs, free);
disp->Configs = NULL;
}
/* XXX incomplete */
}
/**
* Return EGL_TRUE if the given resource is valid. That is, the display does
* own the resource.
*/
EGLBoolean
_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *disp)
{
_EGLResource *list = disp->ResourceLists[type];
simple_mtx_assert_locked(&disp->Mutex);
if (!res)
return EGL_FALSE;
while (list) {
if (res == (void *)list) {
assert(list->Display == disp);
break;
}
list = list->Next;
}
return (list != NULL);
}
/**
* Initialize a display resource. The size of the subclass object is
* specified.
*
* This is supposed to be called from the initializers of subclasses, such as
* _eglInitContext or _eglInitSurface.
*/
void
_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *disp)
{
memset(res, 0, size);
res->Display = disp;
res->RefCount = 1;
}
/**
* Increment reference count for the resource.
*/
void
_eglGetResource(_EGLResource *res)
{
assert(res && res->RefCount > 0);
p_atomic_inc(&res->RefCount);
}
/**
* Decrement reference count for the resource.
*/
EGLBoolean
_eglPutResource(_EGLResource *res)
{
assert(res && res->RefCount > 0);
return p_atomic_dec_zero(&res->RefCount);
}
/**
* Link a resource to its display.
*/
void
_eglLinkResource(_EGLResource *res, _EGLResourceType type)
{
assert(res->Display);
simple_mtx_assert_locked(&res->Display->Mutex);
res->IsLinked = EGL_TRUE;
res->Next = res->Display->ResourceLists[type];
res->Display->ResourceLists[type] = res;
_eglGetResource(res);
}
/**
* Unlink a linked resource from its display.
*/
void
_eglUnlinkResource(_EGLResource *res, _EGLResourceType type)
{
_EGLResource *prev;
simple_mtx_assert_locked(&res->Display->Mutex);
prev = res->Display->ResourceLists[type];
if (prev != res) {
while (prev) {
if (prev->Next == res)
break;
prev = prev->Next;
}
assert(prev);
prev->Next = res->Next;
} else {
res->Display->ResourceLists[type] = res->Next;
}
res->Next = NULL;
res->IsLinked = EGL_FALSE;
_eglPutResource(res);
/* We always unlink before destroy. The driver still owns a reference */
assert(res->RefCount);
}
#ifdef HAVE_X11_PLATFORM
_EGLDisplay *
_eglGetX11Display(Display *native_display, const EGLAttrib *attrib_list)
{
_EGLDisplay *dpy;
_EGLDevice *dev = NULL;
/* EGL_EXT_platform_x11 adds EGL_PLATFORM_X11_SCREEN_EXT,
* which is optional.
*/
if (attrib_list != NULL) {
for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
EGLAttrib attrib = attrib_list[i];
EGLAttrib value = attrib_list[i + 1];
switch (attrib) {
case EGL_DEVICE_EXT:
dev = _eglLookupDevice((void *)value);
if (!dev) {
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
return NULL;
}
break;
/* EGL_EXT_platform_x11 adds EGL_PLATFORM_X11_SCREEN_EXT,
* which is optional.
*/
case EGL_PLATFORM_X11_SCREEN_EXT:
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
return NULL;
}
}
}
dpy = _eglFindDisplay(_EGL_PLATFORM_X11, native_display, attrib_list);
if (dpy) {
dpy->Device = dev;
}
return dpy;
}
#endif /* HAVE_X11_PLATFORM */
#ifdef HAVE_XCB_PLATFORM
_EGLDisplay *
_eglGetXcbDisplay(xcb_connection_t *native_display,
const EGLAttrib *attrib_list)
{
_EGLDisplay *dpy;
_EGLDevice *dev = NULL;
/* EGL_EXT_platform_xcb recognizes exactly one attribute,
* EGL_PLATFORM_XCB_SCREEN_EXT, which is optional.
*/
if (attrib_list != NULL) {
for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
EGLAttrib attrib = attrib_list[i];
EGLAttrib value = attrib_list[i + 1];
switch (attrib) {
case EGL_DEVICE_EXT:
dev = _eglLookupDevice((void *)value);
if (!dev) {
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
return NULL;
}
break;
case EGL_PLATFORM_XCB_SCREEN_EXT:
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
return NULL;
}
}
}
dpy = _eglFindDisplay(_EGL_PLATFORM_XCB, native_display, attrib_list);
if (dpy) {
dpy->Device = dev;
}
return dpy;
}
#endif /* HAVE_XCB_PLATFORM */
#ifdef HAVE_DRM_PLATFORM
_EGLDisplay *
_eglGetGbmDisplay(struct gbm_device *native_display,
const EGLAttrib *attrib_list)
{
_EGLDisplay *dpy;
_EGLDevice *dev = NULL;
/* This platform recognizes only EXT_explicit_device */
if (attrib_list) {
for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
EGLAttrib attrib = attrib_list[i];
EGLAttrib value = attrib_list[i + 1];
switch (attrib) {
case EGL_DEVICE_EXT:
dev = _eglLookupDevice((void *)value);
if (!dev) {
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
return NULL;
}
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
return NULL;
}
}
}
dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, native_display, attrib_list);
if (dpy) {
dpy->Device = dev;
}
return dpy;
}
#endif /* HAVE_DRM_PLATFORM */
#ifdef HAVE_WAYLAND_PLATFORM
_EGLDisplay *
_eglGetWaylandDisplay(struct wl_display *native_display,
const EGLAttrib *attrib_list)
{
_EGLDisplay *dpy;
_EGLDevice *dev = NULL;
/* This platform recognizes only EXT_explicit_device */
if (attrib_list) {
for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
EGLAttrib attrib = attrib_list[i];
EGLAttrib value = attrib_list[i + 1];
switch (attrib) {
case EGL_DEVICE_EXT:
dev = _eglLookupDevice((void *)value);
if (!dev) {
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
return NULL;
}
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
return NULL;
}
}
}
dpy = _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display, attrib_list);
if (dpy) {
dpy->Device = dev;
}
return dpy;
}
#endif /* HAVE_WAYLAND_PLATFORM */
_EGLDisplay *
_eglGetSurfacelessDisplay(void *native_display, const EGLAttrib *attrib_list)
{
_EGLDisplay *dpy;
_EGLDevice *dev = NULL;
/* Any native display must be an EGLDeviceEXT we know about */
if (native_display != NULL) {
_eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay");
return NULL;
}
/* This platform recognizes only EXT_explicit_device */
if (attrib_list) {
for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
EGLAttrib attrib = attrib_list[i];
EGLAttrib value = attrib_list[i + 1];
switch (attrib) {
case EGL_DEVICE_EXT:
dev = _eglLookupDevice((void *)value);
if (!dev) {
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
return NULL;
}
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
return NULL;
}
}
}
dpy = _eglFindDisplay(_EGL_PLATFORM_SURFACELESS, NULL, attrib_list);
if (dpy) {
dpy->Device = dev;
}
return dpy;
}
#ifdef HAVE_ANDROID_PLATFORM
_EGLDisplay *
_eglGetAndroidDisplay(void *native_display, const EGLAttrib *attrib_list)
{
/* This platform recognizes no display attributes. */
if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
return NULL;
}
return _eglFindDisplay(_EGL_PLATFORM_ANDROID, native_display, attrib_list);
}
#endif /* HAVE_ANDROID_PLATFORM */
#ifdef HAVE_REDOX_PLATFORM
_EGLDisplay *
_eglGetRedoxDisplay(void *native_display, const EGLAttrib *attrib_list)
{
/* Redox has no real display surface; native_display is
* always NULL. The platform probes /scheme/drm/card0 in
* dri2_initialize_redox() and falls back to swrast.
*/
(void) native_display;
return _eglFindDisplay(_EGL_PLATFORM_REDOX, NULL, attrib_list);
}
#endif /* HAVE_REDOX_PLATFORM */
_EGLDisplay *
_eglGetDeviceDisplay(void *native_display, const EGLAttrib *attrib_list)
{
_EGLDevice *dev;
_EGLDisplay *display;
int fd = -1;
dev = _eglLookupDevice(native_display);
if (!dev) {
_eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay");
return NULL;
}
if (attrib_list) {
for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
EGLAttrib attrib = attrib_list[i];
EGLAttrib value = attrib_list[i + 1];
/* EGL_EXT_platform_device does not recognize any attributes,
* EGL_EXT_device_drm adds the optional EGL_DRM_MASTER_FD_EXT.
*/
if (!_eglDeviceSupports(dev, _EGL_DEVICE_DRM) ||
attrib != EGL_DRM_MASTER_FD_EXT) {
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
return NULL;
}
fd = (int)value;
}
}
display = _eglFindDisplay(_EGL_PLATFORM_DEVICE, native_display, attrib_list);
if (!display) {
_eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay");
return NULL;
}
/* If the fd is explicitly provided and we did not dup() it yet, do so.
* The spec mandates that we do so, since we'll need it past the
* eglGetPlatformDisplay call.
*
* The new fd is guaranteed to be 3 or greater.
*/
if (fd != -1 && display->Options.fd == 0) {
display->Options.fd = os_dupfd_cloexec(fd);
if (display->Options.fd == -1) {
/* Do not (really) need to teardown the display */
_eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay");
return NULL;
}
}
return display;
}
@@ -0,0 +1,367 @@
/**************************************************************************
*
* Copyright 2008 VMware, Inc.
* Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
* Copyright 2010-2011 LunarG, Inc.
* All Rights Reserved.
*
* 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, sub license, 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.
*
**************************************************************************/
#ifndef EGLDISPLAY_INCLUDED
#define EGLDISPLAY_INCLUDED
#include "util/rwlock.h"
#include "util/simple_mtx.h"
#include "eglarray.h"
#include "egldefines.h"
#include "egltypedefs.h"
#ifdef HAVE_X11_PLATFORM
#include <X11/Xlib.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum _egl_platform_type {
_EGL_PLATFORM_X11,
_EGL_PLATFORM_XCB,
_EGL_PLATFORM_WAYLAND,
_EGL_PLATFORM_DRM,
_EGL_PLATFORM_ANDROID,
_EGL_PLATFORM_HAIKU,
_EGL_PLATFORM_SURFACELESS,
_EGL_PLATFORM_DEVICE,
_EGL_PLATFORM_WINDOWS,
_EGL_PLATFORM_REDOX,
_EGL_NUM_PLATFORMS,
_EGL_INVALID_PLATFORM = -1
};
typedef enum _egl_platform_type _EGLPlatformType;
enum _egl_resource_type {
_EGL_RESOURCE_CONTEXT,
_EGL_RESOURCE_SURFACE,
_EGL_RESOURCE_IMAGE,
_EGL_RESOURCE_SYNC,
_EGL_NUM_RESOURCES
};
/* this cannot and need not go into egltypedefs.h */
typedef enum _egl_resource_type _EGLResourceType;
/**
* A resource of a display.
*/
struct _egl_resource {
/* which display the resource belongs to */
_EGLDisplay *Display;
EGLBoolean IsLinked;
EGLint RefCount;
EGLLabelKHR Label;
/* used to link resources of the same type */
_EGLResource *Next;
};
/**
* Optional EGL extensions info.
*/
struct _egl_extensions {
/* Please keep these sorted alphabetically. */
EGLBoolean ANDROID_blob_cache;
EGLBoolean ANDROID_framebuffer_target;
EGLBoolean ANDROID_image_native_buffer;
EGLBoolean ANDROID_native_fence_sync;
EGLBoolean ANDROID_recordable;
EGLBoolean ANGLE_sync_control_rate;
EGLBoolean CHROMIUM_sync_control;
EGLBoolean EXT_buffer_age;
EGLBoolean EXT_config_select_group;
EGLBoolean EXT_create_context_robustness;
EGLBoolean EXT_image_dma_buf_import;
EGLBoolean EXT_image_dma_buf_import_modifiers;
EGLBoolean EXT_pixel_format_float;
EGLBoolean EXT_present_opaque;
EGLBoolean EXT_protected_content;
EGLBoolean EXT_protected_surface;
EGLBoolean EXT_query_reset_notification_strategy;
EGLBoolean EXT_surface_compression;
EGLBoolean EXT_surface_CTA861_3_metadata;
EGLBoolean EXT_surface_SMPTE2086_metadata;
EGLBoolean EXT_swap_buffers_with_damage;
unsigned int IMG_context_priority;
#define __EGL_CONTEXT_PRIORITY_LOW_BIT 0
#define __EGL_CONTEXT_PRIORITY_MEDIUM_BIT 1
#define __EGL_CONTEXT_PRIORITY_HIGH_BIT 2
#define __EGL_CONTEXT_PRIORITY_REALTIME_BIT 3
EGLBoolean KHR_cl_event2;
EGLBoolean KHR_config_attribs;
EGLBoolean KHR_context_flush_control;
EGLBoolean KHR_create_context;
EGLBoolean KHR_create_context_no_error;
EGLBoolean KHR_fence_sync;
EGLBoolean KHR_get_all_proc_addresses;
EGLBoolean KHR_gl_colorspace;
EGLBoolean KHR_gl_renderbuffer_image;
EGLBoolean KHR_gl_texture_2D_image;
EGLBoolean KHR_gl_texture_3D_image;
EGLBoolean KHR_gl_texture_cubemap_image;
EGLBoolean KHR_image;
EGLBoolean KHR_image_base;
EGLBoolean KHR_image_pixmap;
EGLBoolean KHR_mutable_render_buffer;
EGLBoolean KHR_no_config_context;
EGLBoolean KHR_partial_update;
EGLBoolean KHR_reusable_sync;
EGLBoolean KHR_surfaceless_context;
EGLBoolean KHR_wait_sync;
EGLBoolean MESA_gl_interop;
EGLBoolean MESA_image_dma_buf_export;
EGLBoolean MESA_query_driver;
EGLBoolean MESA_x11_native_visual_id;
EGLBoolean NOK_texture_from_pixmap;
EGLBoolean NV_context_priority_realtime;
EGLBoolean WL_bind_wayland_display;
EGLBoolean WL_create_wayland_buffer_from_image;
};
struct _egl_display {
/* used to link displays */
_EGLDisplay *Next;
/**
* The big-display-lock (BDL) which protects our internal state. EGL
* drivers should use their own locking, as needed, to protect their
* own state, rather than relying on this.
*/
simple_mtx_t Mutex;
/**
* The spec appears to allow eglTerminate() to race with more or less
* any other egl call. To allow for this, while relaxing the BDL to
* allow other egl calls to happen in parallel, a rwlock is used. All
* points where the BDL lock is acquired also acquire TerminateLock
* for reading, while eglTerminate() itself acquires the TerminateLock
* for writing.
*
* Note, we could conceivably just replace the BDL with a single
* rwlock. But there are a couple shortcomings of u_rwlock:
*
* 1) The WIN32 implementation does not allow promoting a read-
* lock to write-lock, nor recursive locking, whereas the
* pthread based implementation does. Because of this, it
* would be difficult to keep the eglapi layer portable if
* we depended on any less-than-trivial rwlock usage.
*
* 2) We'd lose simple_mtx_assert_locked().
*/
struct u_rwlock TerminateLock;
_EGLPlatformType Platform; /**< The type of the platform display */
void *PlatformDisplay; /**< A pointer to the platform display */
_EGLDevice *Device; /**< Device backing the display */
const _EGLDriver *Driver; /**< Matched driver of the display */
EGLBoolean Initialized; /**< True if the display is initialized */
/* options that affect how the driver initializes the display */
struct {
EGLBoolean Zink; /**< Use kopper only */
EGLBoolean ForceSoftware; /**< Use software path only */
EGLBoolean GalliumHudWarn; /**< Using hud, warn when querying buffer age */
EGLAttrib *Attribs; /**< Platform-specific options */
int fd; /**< Platform device specific, local fd */
} Options;
/* these fields are set by the driver during init */
void *DriverData; /**< Driver private data */
EGLint Version; /**< EGL version major*10+minor */
EGLint ClientAPIs; /**< Bitmask of APIs supported (EGL_xxx_BIT) */
_EGLExtensions Extensions; /**< Extensions supported */
EGLBoolean RobustBufferAccess; /**< Supports robust buffer access behavior */
/* these fields are derived from above */
char VersionString[100]; /**< EGL_VERSION */
char ClientAPIsString[100]; /**< EGL_CLIENT_APIS */
char ExtensionsString[_EGL_MAX_EXTENSIONS_LEN]; /**< EGL_EXTENSIONS */
_EGLArray *Configs;
/* lists of resources */
_EGLResource *ResourceLists[_EGL_NUM_RESOURCES];
EGLLabelKHR Label;
EGLSetBlobFuncANDROID BlobCacheSet;
EGLGetBlobFuncANDROID BlobCacheGet;
};
extern _EGLDisplay *
_eglLockDisplay(EGLDisplay dpy);
extern void
_eglUnlockDisplay(_EGLDisplay *disp);
extern _EGLPlatformType
_eglGetNativePlatform(void *nativeDisplay);
extern void
_eglFiniDisplay(void);
extern _EGLDisplay *
_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy, const EGLAttrib *attr);
extern void
_eglReleaseDisplayResources(_EGLDisplay *disp);
extern void
_eglCleanupDisplay(_EGLDisplay *disp);
extern EGLBoolean
_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *disp);
/**
* Return the handle of a linked display, or EGL_NO_DISPLAY.
*/
static inline EGLDisplay
_eglGetDisplayHandle(_EGLDisplay *disp)
{
return (EGLDisplay)((disp) ? disp : EGL_NO_DISPLAY);
}
static inline EGLBoolean
_eglHasAttrib(_EGLDisplay *disp, EGLAttrib attrib)
{
EGLAttrib *attribs = disp->Options.Attribs;
if (!attribs) {
return EGL_FALSE;
}
for (int i = 0; attribs[i] != EGL_NONE; i += 2) {
if (attrib == attribs[i]) {
return EGL_TRUE;
}
}
return EGL_FALSE;
}
extern void
_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *disp);
extern void
_eglGetResource(_EGLResource *res);
extern EGLBoolean
_eglPutResource(_EGLResource *res);
extern void
_eglLinkResource(_EGLResource *res, _EGLResourceType type);
extern void
_eglUnlinkResource(_EGLResource *res, _EGLResourceType type);
/**
* Return true if the resource is linked.
*/
static inline EGLBoolean
_eglIsResourceLinked(_EGLResource *res)
{
return res->IsLinked;
}
static inline size_t
_eglNumAttribs(const EGLAttrib *attribs)
{
size_t len = 0;
if (attribs) {
while (attribs[len] != EGL_NONE)
len += 2;
len++;
}
return len;
}
#ifdef HAVE_X11_PLATFORM
_EGLDisplay *
_eglGetX11Display(Display *native_display, const EGLAttrib *attrib_list);
#endif
#ifdef HAVE_XCB_PLATFORM
typedef struct xcb_connection_t xcb_connection_t;
_EGLDisplay *
_eglGetXcbDisplay(xcb_connection_t *native_display,
const EGLAttrib *attrib_list);
#endif
#ifdef HAVE_DRM_PLATFORM
struct gbm_device;
_EGLDisplay *
_eglGetGbmDisplay(struct gbm_device *native_display,
const EGLAttrib *attrib_list);
#endif
#ifdef HAVE_WAYLAND_PLATFORM
struct wl_display;
_EGLDisplay *
_eglGetWaylandDisplay(struct wl_display *native_display,
const EGLAttrib *attrib_list);
#endif
_EGLDisplay *
_eglGetSurfacelessDisplay(void *native_display, const EGLAttrib *attrib_list);
#ifdef HAVE_ANDROID_PLATFORM
_EGLDisplay *
_eglGetAndroidDisplay(void *native_display, const EGLAttrib *attrib_list);
#endif
#ifdef HAVE_REDOX_PLATFORM
_EGLDisplay *
_eglGetRedoxDisplay(void *native_display, const EGLAttrib *attrib_list);
#endif
_EGLDisplay *
_eglGetDeviceDisplay(void *native_display, const EGLAttrib *attrib_list);
#ifdef __cplusplus
}
#endif
#endif /* EGLDISPLAY_INCLUDED */
@@ -0,0 +1,276 @@
# Copyright © 2017-2019 Intel Corporation
# SPDX-License-Identifier: MIT
inc_egl = include_directories('.', 'main')
c_args_for_egl = [asan_c_args]
cpp_args_for_egl = []
link_args_for_egl = []
link_deps_for_egl = []
link_for_egl = []
if with_dri
link_for_egl += libgallium_dri
endif
if with_platform_windows
link_for_egl += libgallium_wgl
endif
deps_for_egl = []
incs_for_egl = [inc_include, inc_src, inc_egl]
files_egl = files(
'main/eglapi.c',
'main/eglarray.c',
'main/eglarray.h',
'main/eglconfigdebug.c',
'main/eglconfigdebug.h',
'main/eglconfig.c',
'main/eglconfig.h',
'main/eglcontext.c',
'main/eglcontext.h',
'main/eglcurrent.c',
'main/eglcurrent.h',
'main/egldefines.h',
'main/egldevice.c',
'main/egldevice.h',
'main/egldisplay.c',
'main/egldisplay.h',
'main/egldriver.h',
'main/eglglobals.c',
'main/eglglobals.h',
'main/eglimage.c',
'main/eglimage.h',
'main/egllog.c',
'main/egllog.h',
'main/eglsurface.c',
'main/eglsurface.h',
'main/eglsync.c',
'main/eglsync.h',
'main/eglentrypoint.h',
'main/egltypedefs.h',
)
# Remove the argument parsing from gen_egl_dispatch.py when removing this
# option
gen_args = []
if with_wayland_bind_display
gen_args += [ '--bind-wl-display' ]
endif
g_egldispatchstubs_c = custom_target(
'g_egldispatchstubs.c',
input : [
'generate/gen_egl_dispatch.py',
'generate/egl.xml', 'generate/egl_other.xml'
],
output : 'g_egldispatchstubs.c',
command : [
prog_python, '@INPUT0@', gen_args, 'source', '@INPUT1@', '@INPUT2@'
],
depend_files : [ 'generate/eglFunctionList.py', glapi_xml_py_deps],
capture : true,
)
g_egldispatchstubs_h = custom_target(
'g_egldispatchstubs.h',
input : [
'generate/gen_egl_dispatch.py',
'generate/egl.xml', 'generate/egl_other.xml'
],
output : 'g_egldispatchstubs.h',
command : [
prog_python, '@INPUT0@', gen_args, 'header', '@INPUT1@', '@INPUT2@'
],
depend_files : [ 'generate/eglFunctionList.py', glapi_xml_py_deps],
capture : true,
)
if with_dri
files_egl += files(
'drivers/dri2/egl_dri2.c',
'drivers/dri2/egl_dri2.h',
)
files_egl += sha1_h
files_egl += main_dispatch_h
deps_for_egl += idep_xmlconfig
link_for_egl += libloader
incs_for_egl += inc_loader
incs_for_egl += inc_gallium
incs_for_egl += inc_gallium_aux
incs_for_egl += inc_mesa
incs_for_egl += inc_st_dri
files_egl += files(
'drivers/dri2/platform_device.c',
'drivers/dri2/platform_surfaceless.c',
)
if with_platform_x11
files_egl += files('drivers/dri2/platform_x11.c')
incs_for_egl += inc_loader_x11
link_for_egl += libloader_x11
if with_dri_platform == 'drm' or with_dri_platform == 'pseudo-drm'
files_egl += files('drivers/dri2/platform_x11_dri3.c')
endif
deps_for_egl += [dep_x11_xcb, dep_xcb_xrandr, dep_xcb_xfixes, dep_xcb_shm]
endif
if with_platform_redox
files_egl += files('drivers/dri2/platform_redox.c')
c_args_for_egl += ['-DHAVE_REDOX_PLATFORM']
endif
if with_gbm and not with_platform_android
files_egl += files('drivers/dri2/platform_drm.c')
incs_for_egl += [include_directories('../gbm/backends/dri')]
deps_for_egl += [dep_libdrm, dep_gbm]
endif
if with_platform_wayland
deps_for_egl += [dep_wayland_client, dep_wayland_server, dep_wayland_egl_headers]
link_for_egl += libloader_wayland_helper
files_egl += files('drivers/dri2/platform_wayland.c')
files_egl += wp_files['linux-dmabuf-unstable-v1']
files_egl += wp_files['presentation-time']
if with_wayland_bind_display
files_egl += [wayland_drm_client_protocol_h]
link_for_egl += [libwayland_drm]
incs_for_egl += include_directories('wayland/wayland-drm')
c_args_for_egl += [
'-DHAVE_BIND_WL_DISPLAY'
]
endif
endif
if with_platform_android
deps_for_egl += [dep_android, idep_u_gralloc]
files_egl += files('drivers/dri2/platform_android.c')
endif
elif with_platform_haiku
c_args_for_egl += [
'-D_EGL_BUILT_IN_DRIVER_HAIKU',
]
files_egl += files('drivers/haiku/egl_haiku.cpp')
incs_for_egl += [inc_gallium, inc_gallium_aux, inc_gallium_drivers, inc_gallium_winsys, inc_gallium_winsys_sw]
incs_for_egl += [inc_mesa]
incs_for_egl += [include_directories('../gallium/frontends/hgl')]
link_for_egl += [libmesa, libgallium, libswhgl, libsthgl, libglapi]
deps_for_egl += [cpp.find_library('be'), driver_swrast]
elif with_platform_windows
c_args_for_egl += [
'-DEGLAPI=', '-DPUBLIC='
]
files_egl += files('drivers/wgl/egl_wgl.c')
files_egl += main_dispatch_h
incs_for_egl += [inc_wgl, inc_gallium, inc_gallium_aux, inc_mesa]
link_for_egl += libgallium_wgl
else
error('No EGL driver available.')
endif
if cc.has_function('mincore')
c_args_for_egl += '-DHAVE_MINCORE'
endif
if not with_glvnd
egl_lib_name = 'EGL' + get_option('egl-lib-suffix')
egl_lib_version = '1.0.0'
egl_lib_soversion = host_machine.system() == 'windows' ? '' : '1'
else
egl_lib_name = 'EGL_@0@'.format(glvnd_vendor_name)
egl_lib_version = '0.0.0'
egl_lib_soversion = '0'
deps_for_egl += dep_glvnd
files_egl += [g_egldispatchstubs_h, g_egldispatchstubs_c]
files_egl += files('main/eglglvnd.c', 'main/egldispatchstubs.c')
endif
if with_ld_version_script
if with_glvnd
link_args_for_egl += [
'-Wl,--version-script', join_paths(meson.current_source_dir(), 'egl-glvnd.sym')
]
link_deps_for_egl += files('egl-glvnd.sym')
else
link_args_for_egl += [
'-Wl,--version-script', join_paths(meson.current_source_dir(), 'egl.sym')
]
link_deps_for_egl += files('egl.sym')
endif
endif
egl_def = custom_target(
'egl.def',
input: 'main/egl.def.in',
output : 'egl.def',
command : gen_vs_module_defs_normal_command,
)
libegl = shared_library(
egl_lib_name,
files_egl,
c_args : [
c_args_for_egl,
'-D_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_@0@'.format(egl_native_platform.to_upper()),
],
cpp_args : [cpp_args_for_egl],
gnu_symbol_visibility : 'hidden',
include_directories : incs_for_egl,
link_with : [link_for_egl],
link_args : [ld_args_bsymbolic, ld_args_gc_sections, link_args_for_egl],
link_depends : [link_deps_for_egl],
dependencies : [deps_for_egl, dep_dl, dep_libdrm, dep_clock, dep_thread, idep_mesautil],
install : true,
version : egl_lib_version,
soversion : egl_lib_soversion,
name_prefix : host_machine.system() == 'windows' ? 'lib' : [], # always use lib, but avoid warnings on !windows
vs_module_defs : egl_def
)
if with_glvnd
configure_file(
configuration: {'library_path' : 'libEGL_@0@.so.0'.format(glvnd_vendor_name)},
input : 'main/50_mesa.json',
output: '50_@0@.json'.format(glvnd_vendor_name),
install : true,
install_tag : 'runtime',
install_dir : join_paths(get_option('datadir'), 'glvnd', 'egl_vendor.d')
)
devenv_glvnd_egl_json_file = configure_file(
configuration: {'library_path' : libegl.full_path()},
input : 'main/50_mesa.json',
output: 'devenv_glvnd_egl.json',
)
devenv.set('__EGL_VENDOR_LIBRARY_FILENAMES', devenv_glvnd_egl_json_file.full_path())
else
pkg.generate(
name : 'egl',
description : 'Mesa EGL Library',
version : meson.project_version(),
libraries : libegl,
libraries_private: gl_priv_libs,
requires_private : gl_priv_reqs,
extra_cflags : gl_pkgconfig_c_flags,
)
endif
if with_symbols_check
if with_glvnd
egl_symbols = files('egl-glvnd-symbols.txt')
else
egl_symbols = files('egl-symbols.txt')
endif
test('egl-symbols-check',
symbols_check,
args : [
'--lib', libegl,
'--symbols-file', egl_symbols,
symbols_check_args,
],
suite : ['egl'],
)
test('egl-entrypoint-check',
prog_python,
args : files('egl-entrypoint-check.py', 'main/eglentrypoint.h'),
suite : ['egl'],
)
endif
+30
View File
@@ -739,8 +739,36 @@ if [ "$NO_CACHE" != "1" ]; then
*) return 1 ;;
esac
}
# ── Config-scoped ABI invalidation ──────────────────────────────────
# repo/ is shared across configs, so a `redbear-mini` build must NOT nuke
# packages that only `redbear-full` builds (Qt, mesa, sddm, ...) just because
# their pkgars sit in the repo older than relibc.pkgar. Resolve the closure
# of the config being built and only ever invalidate packages inside it.
# No env flag needed — you named the config, so we know it's mini not full.
declare -A _config_pkg_set
_config_scoped=0
_cfg_file="$PROJECT_ROOT/config/$CONFIG.toml"
if [ -f "$_cfg_file" ]; then
while read -r _p; do
[ -n "$_p" ] && _config_pkg_set["$_p"]=1
done < <(timeout 120 "$PROJECT_ROOT/target/release/repo" push-tree \
--filesystem="$_cfg_file" 2>/dev/null \
| sed -E 's/^[^A-Za-z0-9_]+//' | awk '{print $1}' | grep -E '^[A-Za-z0-9]')
[ "${#_config_pkg_set[@]}" -gt 0 ] && _config_scoped=1
fi
if [ "$_config_scoped" = "1" ]; then
echo ">>> ABI-staleness scoped to $CONFIG (${#_config_pkg_set[@]} pkgs); other configs' repo packages untouched."
else
echo ">>> NOTE: could not resolve $CONFIG package closure; ABI sweep is repo-wide (fallback)."
fi
_pkg_in_config() {
# true unless we have a config closure and pkg is outside it
[ "$_config_scoped" != "1" ] && return 0
[ -n "${_config_pkg_set[$1]:-}" ]
}
invalidate_consumer() {
local pkg="$1"
_pkg_in_config "$pkg" || return 0
rm -f "$REPO_DIR/$pkg".*
find "$PROJECT_ROOT/recipes" "$PROJECT_ROOT/local/recipes" \
-path "*/$pkg/target" -type d -exec rm -rf {} + 2>/dev/null || true
@@ -762,6 +790,7 @@ if [ "$NO_CACHE" != "1" ]; then
for _pkgar in "$REPO_DIR"/*.pkgar; do
[ -f "$_pkgar" ] || continue
_pkg="$(basename "$_pkgar" .pkgar)"
_pkg_in_config "$_pkg" || continue
if _rb_preserve_toolchain "$_pkg"; then
echo ">>> preserving ABI-inert toolchain pkg '$_pkg' (consumer relinks;" \
"set REDBEAR_FORCE_TOOLCHAIN_RECOOK=1 to force a full re-cook)."
@@ -775,6 +804,7 @@ if [ "$NO_CACHE" != "1" ]; then
[ -f "$_pkgar" ] || continue
_pkg="$(basename "$_pkgar" .pkgar)"
[ "$_pkg" = "relibc" ] && continue
_pkg_in_config "$_pkg" || continue
_rb_preserve_toolchain "$_pkg" && continue
_pkg_ts=$(stat -c %Y "$_pkgar" 2>/dev/null || echo "0")
if [ "$relibc_ts" != "0" ] && [ "$relibc_ts" -gt "$_pkg_ts" ]; then