MetaEgl: Add EGL procs necessary for EGLDevice based rendering

https://bugzilla.gnome.org/show_bug.cgi?id=773629
This commit is contained in:
Jonas Ådahl 2016-08-18 11:27:45 +08:00
parent f692eb3677
commit b735bdcf2f
3 changed files with 422 additions and 0 deletions

View File

@ -0,0 +1,52 @@
/*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* 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, 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.
*/
#ifndef META_EGL_EXT_H
#define META_EGL_EXT_H
#include <EGL/egl.h>
#include <EGL/eglext.h>
/*
* FIXME: Remove both EGL_EXT_stream_acquire_mode and
* EGL_NV_output_drm_flip_event definitions below once both extensions
* get published by Khronos and incorportated into Khronos' header files
*/
#ifndef EGL_EXT_stream_acquire_mode
#define EGL_EXT_stream_acquire_mode 1
#define EGL_CONSUMER_AUTO_ACQUIRE_EXT 0x332B
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribEXT (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
#endif
#endif /* EGL_EXT_stream_acquire_mode */
#ifndef EGL_NV_output_drm_flip_event
#define EGL_NV_output_drm_flip_event 1
#define EGL_DRM_FLIP_EVENT_DATA_NV 0x333E
#endif /* EGL_NV_output_drm_flip_event */
#endif /* META_EGL_EXT_H */

View File

@ -26,6 +26,7 @@
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/meta-egl.h" #include "backends/meta-egl.h"
#include "backends/meta-egl-ext.h"
#include "meta/util.h" #include "meta/util.h"
#include <EGL/egl.h> #include <EGL/egl.h>
@ -39,6 +40,24 @@ struct _MetaEgl
GObject parent; GObject parent;
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT; PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT;
PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT;
PFNEGLGETOUTPUTLAYERSEXTPROC eglGetOutputLayersEXT;
PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC eglQueryOutputLayerAttribEXT;
PFNEGLCREATESTREAMKHRPROC eglCreateStreamKHR;
PFNEGLDESTROYSTREAMKHRPROC eglDestroyStreamKHR;
PFNEGLQUERYSTREAMKHRPROC eglQueryStreamKHR;
PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC eglCreateStreamProducerSurfaceKHR;
PFNEGLSTREAMCONSUMEROUTPUTEXTPROC eglStreamConsumerOutputEXT;
PFNEGLSTREAMCONSUMERACQUIREATTRIBEXTPROC eglStreamConsumerAcquireAttribEXT;
PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC eglStreamConsumerGLTextureExternalKHR;
}; };
G_DEFINE_TYPE (MetaEgl, meta_egl, G_TYPE_OBJECT) G_DEFINE_TYPE (MetaEgl, meta_egl, G_TYPE_OBJECT)
@ -305,6 +324,266 @@ meta_egl_get_platform_display (MetaEgl *egl,
return display; return display;
} }
gboolean
meta_egl_query_devices (MetaEgl *egl,
EGLint max_devices,
EGLDeviceEXT *devices,
EGLint *num_devices,
GError **error)
{
if (!is_egl_proc_valid (egl->eglQueryDevicesEXT, error))
return FALSE;
if (!egl->eglQueryDevicesEXT (max_devices,
devices,
num_devices))
{
set_egl_error (error);
return FALSE;
}
return TRUE;
}
const char *
meta_egl_query_device_string (MetaEgl *egl,
EGLDeviceEXT device,
EGLint name,
GError **error)
{
const char *device_string;
if (!is_egl_proc_valid (egl->eglQueryDeviceStringEXT, error))
return NULL;
device_string = egl->eglQueryDeviceStringEXT (device, name);
if (!device_string)
{
set_egl_error (error);
return NULL;
}
return device_string;
}
gboolean
meta_egl_egl_device_has_extensions (MetaEgl *egl,
EGLDeviceEXT device,
char ***missing_extensions,
char *first_extension,
...)
{
va_list var_args;
const char *extensions_str;
gboolean has_extensions;
GError *error = NULL;
extensions_str = meta_egl_query_device_string (egl, device, EGL_EXTENSIONS,
&error);
if (!extensions_str)
{
g_warning ("Failed to query device string: %s", error->message);
g_error_free (error);
return FALSE;
}
va_start (var_args, first_extension);
has_extensions = extensions_string_has_extensions_valist (extensions_str,
missing_extensions,
first_extension,
var_args);
va_end (var_args);
return has_extensions;
}
gboolean
meta_egl_get_output_layers (MetaEgl *egl,
EGLDisplay display,
const EGLAttrib *attrib_list,
EGLOutputLayerEXT *layers,
EGLint max_layers,
EGLint *num_layers,
GError **error)
{
if (!is_egl_proc_valid (egl->eglGetOutputLayersEXT, error))
return FALSE;
if (!egl->eglGetOutputLayersEXT (display,
attrib_list,
layers,
max_layers,
num_layers))
{
set_egl_error (error);
return FALSE;
}
return TRUE;
}
gboolean
meta_egl_query_output_layer_attrib (MetaEgl *egl,
EGLDisplay display,
EGLOutputLayerEXT layer,
EGLint attribute,
EGLAttrib *value,
GError **error)
{
if (!is_egl_proc_valid (egl->eglQueryOutputLayerAttribEXT, error))
return FALSE;
if (!egl->eglQueryOutputLayerAttribEXT (display, layer,
attribute, value))
{
set_egl_error (error);
return FALSE;
}
return TRUE;
}
EGLStreamKHR
meta_egl_create_stream (MetaEgl *egl,
EGLDisplay display,
const EGLint *attrib_list,
GError **error)
{
EGLStreamKHR stream;
if (!is_egl_proc_valid (egl->eglCreateStreamKHR, error))
return EGL_NO_STREAM_KHR;
stream = egl->eglCreateStreamKHR (display, attrib_list);
if (stream == EGL_NO_STREAM_KHR)
{
set_egl_error (error);
return EGL_NO_STREAM_KHR;
}
return stream;
}
gboolean
meta_egl_destroy_stream (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
GError **error)
{
if (!is_egl_proc_valid (egl->eglDestroyStreamKHR, error))
return FALSE;
if (!egl->eglDestroyStreamKHR (display, stream))
{
set_egl_error (error);
return FALSE;
}
return TRUE;
}
gboolean
meta_egl_query_stream (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
EGLenum attribute,
EGLint *value,
GError **error)
{
if (!is_egl_proc_valid (egl->eglQueryStreamKHR, error))
return FALSE;
if (!egl->eglQueryStreamKHR (display, stream, attribute, value))
{
set_egl_error (error);
return FALSE;
}
return TRUE;
}
EGLSurface
meta_egl_create_stream_producer_surface (MetaEgl *egl,
EGLDisplay display,
EGLConfig config,
EGLStreamKHR stream,
const EGLint *attrib_list,
GError **error)
{
EGLSurface surface;
if (!is_egl_proc_valid (egl->eglCreateStreamProducerSurfaceKHR, error))
return EGL_NO_SURFACE;
surface = egl->eglCreateStreamProducerSurfaceKHR (display,
config,
stream,
attrib_list);
if (surface == EGL_NO_SURFACE)
{
set_egl_error (error);
return EGL_NO_SURFACE;
}
return surface;
}
gboolean
meta_egl_stream_consumer_output (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
EGLOutputLayerEXT layer,
GError **error)
{
if (!is_egl_proc_valid (egl->eglStreamConsumerOutputEXT, error))
return FALSE;
if (!egl->eglStreamConsumerOutputEXT (display, stream, layer))
{
set_egl_error (error);
return FALSE;
}
return TRUE;
}
gboolean
meta_egl_stream_consumer_acquire_attrib (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
EGLAttrib *attrib_list,
GError **error)
{
if (!is_egl_proc_valid (egl->eglStreamConsumerAcquireAttribEXT, error))
return FALSE;
if (!egl->eglStreamConsumerAcquireAttribEXT (display, stream, attrib_list))
{
set_egl_error (error);
return FALSE;
}
return TRUE;
}
gboolean
meta_egl_stream_consumer_gl_texture_external (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
GError **error)
{
if (!is_egl_proc_valid (egl->eglStreamConsumerGLTextureExternalKHR, error))
return FALSE;
if (!egl->eglStreamConsumerGLTextureExternalKHR (display, stream))
{
set_egl_error (error);
return FALSE;
}
return TRUE;
}
#define GET_EGL_PROC_ADDR(proc) \ #define GET_EGL_PROC_ADDR(proc) \
egl->proc = (void *) eglGetProcAddress (#proc); egl->proc = (void *) eglGetProcAddress (#proc);
@ -321,6 +600,24 @@ meta_egl_constructed (GObject *object)
MetaEgl *egl = META_EGL (object); MetaEgl *egl = META_EGL (object);
GET_EGL_PROC_ADDR_REQUIRED (eglGetPlatformDisplayEXT); GET_EGL_PROC_ADDR_REQUIRED (eglGetPlatformDisplayEXT);
GET_EGL_PROC_ADDR (eglQueryDevicesEXT);
GET_EGL_PROC_ADDR (eglQueryDeviceStringEXT);
GET_EGL_PROC_ADDR (eglGetOutputLayersEXT);
GET_EGL_PROC_ADDR (eglQueryOutputLayerAttribEXT);
GET_EGL_PROC_ADDR (eglCreateStreamKHR);
GET_EGL_PROC_ADDR (eglDestroyStreamKHR);
GET_EGL_PROC_ADDR (eglQueryStreamKHR);
GET_EGL_PROC_ADDR (eglCreateStreamProducerSurfaceKHR);
GET_EGL_PROC_ADDR (eglStreamConsumerOutputEXT);
GET_EGL_PROC_ADDR (eglStreamConsumerAcquireAttribEXT);
GET_EGL_PROC_ADDR (eglStreamConsumerGLTextureExternalKHR);
} }
#undef GET_EGL_PROC_ADDR #undef GET_EGL_PROC_ADDR

View File

@ -60,4 +60,77 @@ EGLDisplay meta_egl_get_platform_display (MetaEgl *egl,
const EGLint *attrib_list, const EGLint *attrib_list,
GError **error); GError **error);
gboolean meta_egl_query_devices (MetaEgl *egl,
EGLint max_devices,
EGLDeviceEXT *devices,
EGLint *num_devices,
GError **error);
const char * meta_egl_query_device_string (MetaEgl *egl,
EGLDeviceEXT device,
EGLint name,
GError **error);
gboolean meta_egl_egl_device_has_extensions (MetaEgl *egl,
EGLDeviceEXT device,
char ***missing_extensions,
char *first_extension,
...);
gboolean meta_egl_get_output_layers (MetaEgl *egl,
EGLDisplay display,
const EGLAttrib *attrib_list,
EGLOutputLayerEXT *layers,
EGLint max_layers,
EGLint *num_layers,
GError **error);
gboolean meta_egl_query_output_layer_attrib (MetaEgl *egl,
EGLDisplay display,
EGLOutputLayerEXT layer,
EGLint attribute,
EGLAttrib *value,
GError **error);
EGLStreamKHR meta_egl_create_stream (MetaEgl *egl,
EGLDisplay display,
const EGLint *attrib_list,
GError **error);
gboolean meta_egl_destroy_stream (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
GError **error);
gboolean meta_egl_query_stream (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
EGLenum attribute,
EGLint *value,
GError **error);
EGLSurface meta_egl_create_stream_producer_surface (MetaEgl *egl,
EGLDisplay display,
EGLConfig config,
EGLStreamKHR stream,
const EGLint *attrib_list,
GError **error);
gboolean meta_egl_stream_consumer_output (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
EGLOutputLayerEXT layer,
GError **error);
gboolean meta_egl_stream_consumer_acquire_attrib (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
EGLAttrib *attrib_list,
GError **error);
gboolean meta_egl_stream_consumer_gl_texture_external (MetaEgl *egl,
EGLDisplay display,
EGLStreamKHR stream,
GError **error);
#endif /* META_EGL_H */ #endif /* META_EGL_H */