diff options
Diffstat (limited to 'src/gallium/state_trackers/egl/common')
-rw-r--r-- | src/gallium/state_trackers/egl/common/egl_g3d.c | 26 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/common/egl_g3d_api.c | 74 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/common/egl_g3d_image.c | 18 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/common/egl_g3d_st.c | 3 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/common/native.h | 37 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/common/native_buffer.h | 59 |
6 files changed, 187 insertions, 30 deletions
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 30ddcd5bc14..a3750ac56fb 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -156,7 +156,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; @@ -238,6 +239,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,7 +253,8 @@ 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; @@ -288,7 +295,8 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy, } valid = init_config_attributes(&gconf->base, - nconf, api_mask, depth_stencil_format); + nconf, api_mask, 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; @@ -349,6 +357,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 +366,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 +382,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; } @@ -538,7 +553,8 @@ 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 (egl_g3d_add_configs(drv, dpy, 1) == 1) { diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c index c10245bb067..fd7dc8f8149 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c @@ -97,6 +97,70 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx, return stapi; } +static int +egl_g3d_compare_config(const _EGLConfig *conf1, const _EGLConfig *conf2, + void *priv_data) +{ + const _EGLConfig *criteria = (const _EGLConfig *) priv_data; + + /* EGL_NATIVE_VISUAL_TYPE ignored? */ + return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE); +} + +static EGLBoolean +egl_g3d_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) +{ + if (!_eglMatchConfig(conf, criteria)) + return EGL_FALSE; + + if (criteria->MatchNativePixmap != EGL_NONE && + criteria->MatchNativePixmap != EGL_DONT_CARE) { + struct egl_g3d_display *gdpy = egl_g3d_display(conf->Display); + struct egl_g3d_config *gconf = egl_g3d_config(conf); + EGLNativePixmapType pix = + (EGLNativePixmapType) criteria->MatchNativePixmap; + + if (!gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native)) + return EGL_FALSE; + } + + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs, + EGLConfig *configs, EGLint size, EGLint *num_configs) +{ + _EGLConfig **tmp_configs, criteria; + EGLint tmp_size, i; + + if (!num_configs) + return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs"); + + if (!_eglParseConfigAttribList(&criteria, dpy, attribs)) + return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); + + tmp_configs = (_EGLConfig **) _eglFilterArray(dpy->Configs, &tmp_size, + (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria); + if (!tmp_configs) + return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)"); + + /* perform sorting of configs */ + if (tmp_configs && tmp_size) { + _eglSortConfigs((const _EGLConfig **) tmp_configs, tmp_size, + egl_g3d_compare_config, (void *) &criteria); + size = MIN2(tmp_size, size); + for (i = 0; i < size; i++) + configs[i] = _eglGetConfigHandle(tmp_configs[i]); + } + + free(tmp_configs); + + *num_configs = size; + + return EGL_TRUE; +} + static _EGLContext * egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share, const EGLint *attribs) @@ -539,7 +603,10 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); } - return gsurf->native->swap_buffers(gsurf->native); + return gsurf->native->present(gsurf->native, + NATIVE_ATTACHMENT_BACK_LEFT, + gsurf->base.SwapBehavior == EGL_BUFFER_PRESERVED, + gsurf->base.SwapInterval); } /** @@ -607,8 +674,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, if (psrc) { gdpy->pipe->resource_copy_region(gdpy->pipe, ptex, subdst, 0, 0, 0, gsurf->render_texture, subsrc, 0, 0, 0, ptex->width0, ptex->height0); - - nsurf->flush_frontbuffer(nsurf); + nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0); } pipe_resource_reference(&ptex, NULL); @@ -838,6 +904,8 @@ egl_g3d_init_driver_api(_EGLDriver *drv) { _eglInitDriverFallbacks(drv); + drv->API.ChooseConfig = egl_g3d_choose_config; + drv->API.CreateContext = egl_g3d_create_context; drv->API.DestroyContext = egl_g3d_destroy_context; drv->API.CreateWindowSurface = egl_g3d_create_window_surface; diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c index be9c88e5e47..6a1f8cc697b 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c @@ -38,7 +38,7 @@ #include "egl_g3d_api.h" #include "egl_g3d_image.h" -/* move this to native display? */ +/* for struct winsys_handle */ #include "state_tracker/drm_driver.h" /** @@ -137,13 +137,11 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name, _EGLImage *img, const EGLint *attribs) { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct pipe_screen *screen = gdpy->native->screen; struct pipe_resource templ; struct winsys_handle wsh; _EGLImageAttribs attrs; EGLint format; - /* winsys_handle is in theory platform-specific */ if (dpy->Platform != _EGL_PLATFORM_DRM) return NULL; @@ -178,9 +176,10 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name, memset(&wsh, 0, sizeof(wsh)); wsh.handle = (unsigned) name; - wsh.stride = attrs.DRMBufferStrideMESA; + wsh.stride = + attrs.DRMBufferStrideMESA * util_format_get_blocksize(templ.format); - return screen->resource_from_handle(screen, &templ, &wsh); + return gdpy->native->buffer->import_buffer(gdpy->native, &templ, &wsh); } #endif /* EGL_MESA_drm_image */ @@ -302,10 +301,8 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img, { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); struct egl_g3d_image *gimg = egl_g3d_image(img); - struct pipe_screen *screen = gdpy->native->screen; struct winsys_handle wsh; - /* winsys_handle is in theory platform-specific */ if (dpy->Platform != _EGL_PLATFORM_DRM) return EGL_FALSE; @@ -313,9 +310,9 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img, if (name) { memset(&handle, 0, sizeof(handle)); wsh.type = DRM_API_HANDLE_TYPE_SHARED; - if (!screen->resource_get_handle(screen, gimg->texture, &wsh)) { + if (!gdpy->native->buffer->export_buffer(gdpy->native, + gimg->texture, &wsh)) return EGL_FALSE; - } *name = wsh.handle; } @@ -324,7 +321,8 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img, if (handle || stride) { memset(&wsh, 0, sizeof(wsh)); wsh.type = DRM_API_HANDLE_TYPE_KMS; - if (!screen->resource_get_handle(screen, gimg->texture, &wsh)) + if (!gdpy->native->buffer->export_buffer(gdpy->native, + gimg->texture, &wsh)) return EGL_FALSE; if (handle) diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c index 0affe632cfe..25e2999590c 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c @@ -192,7 +192,8 @@ egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - return gsurf->native->flush_frontbuffer(gsurf->native); + return gsurf->native->present(gsurf->native, + NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0); } static boolean diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h index 3c3f57e2670..3886ca20562 100644 --- a/src/gallium/state_trackers/egl/common/native.h +++ b/src/gallium/state_trackers/egl/common/native.h @@ -34,6 +34,11 @@ #include "pipe/p_state.h" #include "state_tracker/sw_winsys.h" +#ifdef __cplusplus +extern "C" { +#endif + +#include "native_buffer.h" #include "native_modeset.h" /** @@ -54,7 +59,17 @@ enum native_param_type { * Return TRUE if window/pixmap surfaces use the buffers of the native * types. */ - NATIVE_PARAM_USE_NATIVE_BUFFER + NATIVE_PARAM_USE_NATIVE_BUFFER, + + /** + * Return TRUE if native_surface::present can preserve the buffer. + */ + NATIVE_PARAM_PRESERVE_BUFFER, + + /** + * Return the maximum supported swap interval. + */ + NATIVE_PARAM_MAX_SWAP_INTERVAL }; struct native_surface { @@ -66,17 +81,12 @@ struct native_surface { void (*destroy)(struct native_surface *nsurf); /** - * Swap the front and back buffers so that the back buffer is visible. It - * is no-op if the surface is single-buffered. The contents of the back - * buffer after swapping may or may not be preserved. - */ - boolean (*swap_buffers)(struct native_surface *nsurf); - - /** - * Make the front buffer visible. In some native displays, changes to the - * front buffer might not be visible immediately and require manual flush. + * Present the given buffer to the native engine. */ - boolean (*flush_frontbuffer)(struct native_surface *nsurf); + boolean (*present)(struct native_surface *nsurf, + enum native_attachment natt, + boolean preserve, + uint swap_interval); /** * Validate the buffers of the surface. textures, if not NULL, points to an @@ -181,6 +191,7 @@ struct native_display { EGLNativePixmapType pix, const struct native_config *nconf); + const struct native_display_buffer *buffer; const struct native_display_modeset *modeset; }; @@ -232,4 +243,8 @@ native_get_drm_platform(void); const struct native_platform * native_get_fbdev_platform(void); +#ifdef __cplusplus +} +#endif + #endif /* _NATIVE_H_ */ diff --git a/src/gallium/state_trackers/egl/common/native_buffer.h b/src/gallium/state_trackers/egl/common/native_buffer.h new file mode 100644 index 00000000000..5c29ab97411 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native_buffer.h @@ -0,0 +1,59 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG 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 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: + * Chia-I Wu <[email protected]> + */ + +#ifndef _NATIVE_BUFFER_H_ +#define _NATIVE_BUFFER_H_ + +#include "pipe/p_compiler.h" + +struct native_display; +struct pipe_resource; + +/** + * Buffer interface of the native display. It allows native buffers to be + * imported and exported. + * + * Just like a native window or a native pixmap, a native buffer is another + * native type. Its definition depends on the native display. + * + * For DRM platform, the type of a native buffer is struct winsys_handle. + */ +struct native_display_buffer { + struct pipe_resource *(*import_buffer)(struct native_display *ndpy, + const struct pipe_resource *templ, + void *buf); + + /** + * The resource must be creatred with PIPE_BIND_SHARED. + */ + boolean (*export_buffer)(struct native_display *ndpy, + struct pipe_resource *res, + void *buf); +}; + +#endif /* _NATIVE_BUFFER_H_ */ |