X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fegl%2Fcommon%2Fegl_g3d.c;h=6649f02b244fa8e304aa9ae7103354e56f25323f;hb=4683529048ee133481b2d8f1cae1685aa1736f9a;hp=30ddcd5bc14c0a03c151e5962b9d6b6b7d162bb4;hpb=4926c5748028d33da4808f8a5473aa7b2f2bdc62;p=mesa.git diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 30ddcd5bc14..6649f02b244 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -31,6 +31,7 @@ #include "util/u_memory.h" #include "util/u_format.h" #include "util/u_string.h" +#include "util/u_atomic.h" #include "egl_g3d.h" #include "egl_g3d_api.h" @@ -38,6 +39,56 @@ #include "egl_g3d_loader.h" #include "native.h" +static void +egl_g3d_invalid_surface(struct native_display *ndpy, + struct native_surface *nsurf, + unsigned int seq_num) +{ + /* XXX not thread safe? */ + struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data); + + if (gsurf && gsurf->stfbi) + p_atomic_inc(&gsurf->stfbi->stamp); +} + +static struct pipe_screen * +egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd) +{ + _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + return gdpy->loader->create_drm_screen(name, fd); +} + +static struct pipe_screen * +egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws) +{ + _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + return gdpy->loader->create_sw_screen(ws); +} + +static struct pipe_resource * +egl_g3d_lookup_egl_image(struct native_display *ndpy, void *egl_image) +{ + _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct st_egl_image img; + struct pipe_resource *resource = NULL; + + memset(&img, 0, sizeof(img)); + if (gdpy->smapi->get_egl_image(gdpy->smapi, egl_image, &img)) + resource = img.texture; + + return resource; +} + +static const struct native_event_handler egl_g3d_native_event_handler = { + egl_g3d_invalid_surface, + egl_g3d_new_drm_screen, + egl_g3d_new_sw_screen, + egl_g3d_lookup_egl_image +}; + /** * Get the native platform. */ @@ -54,25 +105,31 @@ egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat) case _EGL_PLATFORM_WINDOWS: plat_name = "Windows"; #ifdef HAVE_GDI_BACKEND - nplat = native_get_gdi_platform(); + nplat = native_get_gdi_platform(&egl_g3d_native_event_handler); #endif break; case _EGL_PLATFORM_X11: plat_name = "X11"; #ifdef HAVE_X11_BACKEND - nplat = native_get_x11_platform(); + nplat = native_get_x11_platform(&egl_g3d_native_event_handler); +#endif + break; + case _EGL_PLATFORM_WAYLAND: + plat_name = "wayland"; +#ifdef HAVE_WAYLAND_BACKEND + nplat = native_get_wayland_platform(&egl_g3d_native_event_handler); #endif break; case _EGL_PLATFORM_DRM: plat_name = "DRM"; #ifdef HAVE_DRM_BACKEND - nplat = native_get_drm_platform(); + nplat = native_get_drm_platform(&egl_g3d_native_event_handler); #endif break; case _EGL_PLATFORM_FBDEV: plat_name = "FBDEV"; #ifdef HAVE_FBDEV_BACKEND - nplat = native_get_fbdev_platform(); + nplat = native_get_fbdev_platform(&egl_g3d_native_event_handler); #endif break; default: @@ -156,7 +213,8 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy) */ static EGLBoolean init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, - EGLint api_mask, enum pipe_format depth_stencil_format) + EGLint api_mask, enum pipe_format depth_stencil_format, + EGLBoolean preserve_buffer, EGLint max_swap_interval) { uint rgba[4], depth_stencil[2], buffer_size; EGLint surface_type; @@ -182,17 +240,21 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, } surface_type = 0x0; - if (nconf->window_bit) - surface_type |= EGL_WINDOW_BIT; - if (nconf->pixmap_bit) - surface_type |= EGL_PIXMAP_BIT; + /* pixmap surfaces should be EGL_SINGLE_BUFFER */ + if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT)) { + if (nconf->pixmap_bit) + surface_type |= EGL_PIXMAP_BIT; + } + /* the others surfaces should be EGL_BACK_BUFFER (or settable) */ + if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)) { + if (nconf->window_bit) + surface_type |= EGL_WINDOW_BIT; #ifdef EGL_MESA_screen_surface - if (nconf->scanout_bit) - surface_type |= EGL_SCREEN_BIT_MESA; + if (nconf->scanout_bit) + surface_type |= EGL_SCREEN_BIT_MESA; #endif - - if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)) surface_type |= EGL_PBUFFER_BIT; + } conf->Conformant = api_mask; conf->RenderableType = api_mask; @@ -206,6 +268,10 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, conf->DepthSize = depth_stencil[0]; conf->StencilSize = depth_stencil[1]; + /* st/vega will allocate the mask on demand */ + if (api_mask & EGL_OPENVG_BIT) + conf->AlphaMaskSize = 8; + conf->SurfaceType = surface_type; conf->NativeRenderable = EGL_TRUE; @@ -225,11 +291,6 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, } conf->Level = nconf->level; - conf->Samples = nconf->samples; - conf->SampleBuffers = 0; - - if (nconf->slow_config) - conf->ConfigCaveat = EGL_SLOW_CONFIG; if (nconf->transparent_rgb) { conf->TransparentType = EGL_TRANSPARENT_RGB; @@ -238,6 +299,11 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, conf->TransparentBlueValue = nconf->transparent_rgb_values[2]; } + conf->MinSwapInterval = 0; + conf->MaxSwapInterval = max_swap_interval; + if (preserve_buffer) + conf->SurfaceType |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + return _eglValidateConfig(conf, EGL_FALSE); } @@ -247,16 +313,13 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, static EGLBoolean egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const struct native_config *nconf, - enum pipe_format depth_stencil_format) + enum pipe_format depth_stencil_format, + int preserve_buffer, int max_swap_interval) { struct egl_g3d_config *gconf = egl_g3d_config(conf); - EGLint buffer_mask, api_mask; + EGLint buffer_mask; EGLBoolean valid; - /* skip single-buffered configs */ - if (!(nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT))) - return EGL_FALSE; - buffer_mask = 0x0; if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT)) buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; @@ -271,24 +334,15 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy, gconf->stvis.color_format = nconf->color_format; gconf->stvis.depth_stencil_format = depth_stencil_format; gconf->stvis.accum_format = PIPE_FORMAT_NONE; - gconf->stvis.samples = nconf->samples; + gconf->stvis.samples = 0; + /* will be overridden per surface */ gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ? ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT; - api_mask = dpy->ClientAPIsMask; - /* this is required by EGL, not by OpenGL ES */ - if (nconf->window_bit && - gconf->stvis.render_buffer != ST_ATTACHMENT_BACK_LEFT) - api_mask &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT); - - if (!api_mask) { - _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x", - nconf->native_visual_id); - } - valid = init_config_attributes(&gconf->base, - nconf, api_mask, depth_stencil_format); + nconf, dpy->ClientAPIs, depth_stencil_format, + preserve_buffer, max_swap_interval); if (!valid) { _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id); return EGL_FALSE; @@ -327,7 +381,7 @@ egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy, /* pick the first supported format */ for (i = 0; i < n; i++) { if (screen->is_format_supported(screen, fmt[i], - PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) { + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) { formats[count++] = fmt[i]; break; } @@ -349,6 +403,7 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) const struct native_config **native_configs; enum pipe_format depth_stencil_formats[8]; int num_formats, num_configs, i, j; + int preserve_buffer, max_swap_interval; native_configs = gdpy->native->get_configs(gdpy->native, &num_configs); if (!num_configs) { @@ -357,6 +412,11 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) return id; } + preserve_buffer = + gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER); + max_swap_interval = + gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL); + num_formats = egl_g3d_fill_depth_stencil_formats(dpy, depth_stencil_formats); @@ -368,7 +428,8 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) if (gconf) { _eglInitConfig(&gconf->base, dpy, id); if (!egl_g3d_init_config(drv, dpy, &gconf->base, - native_configs[i], depth_stencil_formats[j])) { + native_configs[i], depth_stencil_formats[j], + preserve_buffer, max_swap_interval)) { FREE(gconf); break; } @@ -383,46 +444,6 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) return id; } -static void -egl_g3d_invalid_surface(struct native_display *ndpy, - struct native_surface *nsurf, - unsigned int seq_num) -{ - /* XXX not thread safe? */ - struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data); - struct egl_g3d_context *gctx; - - /* - * Some functions such as egl_g3d_copy_buffers create a temporary native - * surface. There is no gsurf associated with it. - */ - gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL; - if (gctx) - gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi); -} - -static struct pipe_screen * -egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd) -{ - _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - return gdpy->loader->create_drm_screen(name, fd); -} - -static struct pipe_screen * -egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws) -{ - _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - return gdpy->loader->create_sw_screen(ws); -} - -static struct native_event_handler egl_g3d_native_event_handler = { - egl_g3d_invalid_surface, - egl_g3d_new_drm_screen, - egl_g3d_new_sw_screen -}; - static void egl_g3d_free_config(void *conf) { @@ -447,9 +468,6 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) _eglReleaseDisplayResources(drv, dpy); - if (gdpy->pipe) - gdpy->pipe->destroy(gdpy->pipe); - if (dpy->Configs) { _eglDestroyArray(dpy->Configs, egl_g3d_free_config); dpy->Configs = NULL; @@ -474,8 +492,7 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) } static EGLBoolean -egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, - EGLint *major, EGLint *minor) +egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy) { struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); struct egl_g3d_display *gdpy; @@ -485,6 +502,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, if (!nplat) return EGL_FALSE; + if (dpy->Options.TestOnly) + return EGL_TRUE; + gdpy = CALLOC_STRUCT(egl_g3d_display); if (!gdpy) { _eglError(EGL_BAD_ALLOC, "eglInitialize"); @@ -493,22 +513,29 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, gdpy->loader = gdrv->loader; dpy->DriverData = gdpy; - _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay); - gdpy->native = nplat->create_display(dpy->PlatformDisplay, - &egl_g3d_native_event_handler, (void *) dpy); + _eglLog(_EGL_INFO, "use %s for display %p", + nplat->name, dpy->PlatformDisplay); + gdpy->native = + nplat->create_display(dpy->PlatformDisplay, dpy->Options.UseFallback); if (!gdpy->native) { _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)"); goto fail; } + gdpy->native->user_data = (void *) dpy; + if (!gdpy->native->init_screen(gdpy->native)) { + _eglError(EGL_NOT_INITIALIZED, + "eglInitialize(failed to initialize screen)"); + goto fail; + } if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK) - dpy->ClientAPIsMask |= EGL_OPENGL_BIT; + dpy->ClientAPIs |= EGL_OPENGL_BIT; if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES1_MASK) - dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT; + dpy->ClientAPIs |= EGL_OPENGL_ES_BIT; if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES2_MASK) - dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT; + dpy->ClientAPIs |= EGL_OPENGL_ES2_BIT; if (gdpy->loader->profile_masks[ST_API_OPENVG] & ST_PROFILE_DEFAULT_MASK) - dpy->ClientAPIsMask |= EGL_OPENVG_BIT; + dpy->ClientAPIs |= EGL_OPENVG_BIT; gdpy->smapi = egl_g3d_create_st_manager(dpy); if (!gdpy->smapi) { @@ -538,16 +565,25 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, if (dpy->Platform == _EGL_PLATFORM_DRM) { dpy->Extensions.MESA_drm_display = EGL_TRUE; - dpy->Extensions.MESA_drm_image = EGL_TRUE; + if (gdpy->native->buffer) + dpy->Extensions.MESA_drm_image = EGL_TRUE; } + if (dpy->Platform == _EGL_PLATFORM_WAYLAND && gdpy->native->buffer) + dpy->Extensions.MESA_drm_image = EGL_TRUE; + +#ifdef EGL_WL_bind_wayland_display + if (gdpy->native->wayland_bufmgr) + dpy->Extensions.WL_bind_wayland_display = EGL_TRUE; +#endif + if (egl_g3d_add_configs(drv, dpy, 1) == 1) { _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)"); goto fail; } - *major = 1; - *minor = 4; + dpy->VersionMajor = 1; + dpy->VersionMinor = 4; return EGL_TRUE; @@ -572,12 +608,6 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname) stapi->get_proc_address(stapi, procname) : NULL); } -static EGLint -egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy) -{ - return (egl_g3d_get_platform(drv, dpy->Platform)) ? 90 : 0; -} - _EGLDriver * egl_g3d_create_driver(const struct egl_g3d_loader *loader) { @@ -594,8 +624,6 @@ egl_g3d_create_driver(const struct egl_g3d_loader *loader) gdrv->base.API.Terminate = egl_g3d_terminate; gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address; - gdrv->base.Probe = egl_g3d_probe; - /* to be filled by the caller */ gdrv->base.Name = NULL; gdrv->base.Unload = NULL;