diff options
Diffstat (limited to 'src/gallium/state_trackers')
28 files changed, 1204 insertions, 352 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h index 54e56c6499..b29e853383 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.h +++ b/src/gallium/state_trackers/dri/common/dri_context.h @@ -65,6 +65,8 @@ struct dri_context static INLINE struct dri_context * dri_context(__DRIcontext * driContextPriv) { + if (!driContextPriv) + return NULL; return (struct dri_context *)driContextPriv->driverPrivate; } diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript index 965dc95760..0c279d2236 100644 --- a/src/gallium/state_trackers/dri/drm/SConscript +++ b/src/gallium/state_trackers/dri/drm/SConscript @@ -22,7 +22,6 @@ if env['dri']: 'dri_drawable.c', 'dri_screen.c', 'dri1_helper.c', - 'dri1.c', 'dri2.c', ] ) diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript new file mode 100644 index 0000000000..c4d01d6b28 --- /dev/null +++ b/src/gallium/state_trackers/egl/SConscript @@ -0,0 +1,32 @@ +####################################################################### +# SConscript for egl state_tracker + +Import('*') + +if 'egl' in env['statetrackers']: + + env = env.Clone() + + env.Append(CPPPATH = [ + '#/src/egl/main', + '#/src/gallium/winsys/sw', + '.', + ]) + + common_sources = [ + 'common/egl_g3d.c', + 'common/egl_g3d_api.c', + 'common/egl_g3d_image.c', + 'common/egl_g3d_st.c', + 'common/native_helper.c', + ] + + gdi_sources = common_sources + [ + 'gdi/native_gdi.c', + ] + + st_egl_gdi = env.ConvenienceLibrary( + target = 'st_egl_gdi', + source = gdi_sources, + ) + Export('st_egl_gdi') diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index d63b81a1c5..361cc7960b 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -426,7 +426,7 @@ egl_g3d_invalid_surface(struct native_display *ndpy, } static struct native_event_handler egl_g3d_native_event_handler = { - .invalid_surface = egl_g3d_invalid_surface + egl_g3d_invalid_surface }; static EGLBoolean diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h index 5a3c80b968..d516d8fe03 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.h +++ b/src/gallium/state_trackers/egl/common/egl_g3d.h @@ -75,6 +75,9 @@ struct egl_g3d_surface { struct native_surface *native; struct pipe_resource *render_texture; + EGLenum client_buffer_type; + EGLClientBuffer client_buffer; + unsigned int sequence_number; }; 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 4615a5829a..255a1fb730 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c @@ -267,16 +267,16 @@ egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs); } -static _EGLSurface * -egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLConfig *conf, const EGLint *attribs) +static struct egl_g3d_surface * +create_pbuffer_surface(_EGLDisplay *dpy, _EGLConfig *conf, + const EGLint *attribs, const char *func) { struct egl_g3d_config *gconf = egl_g3d_config(conf); struct egl_g3d_surface *gsurf; gsurf = CALLOC_STRUCT(egl_g3d_surface); if (!gsurf) { - _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); + _eglError(EGL_BAD_ALLOC, func); return NULL; } @@ -293,6 +293,96 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, return NULL; } + return gsurf; +} + +static _EGLSurface * +egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLConfig *conf, const EGLint *attribs) +{ + struct egl_g3d_surface *gsurf; + struct pipe_resource *ptex = NULL; + + gsurf = create_pbuffer_surface(dpy, conf, attribs, + "eglCreatePbufferSurface"); + if (!gsurf) + return NULL; + + gsurf->client_buffer_type = EGL_NONE; + + if (!gsurf->stfbi->validate(gsurf->stfbi, + &gsurf->stvis.render_buffer, 1, &ptex)) { + egl_g3d_destroy_st_framebuffer(gsurf->stfbi); + FREE(gsurf); + return NULL; + } + + return &gsurf->base; +} + +static _EGLSurface * +egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy, + EGLenum buftype, + EGLClientBuffer buffer, + _EGLConfig *conf, + const EGLint *attribs) +{ + struct egl_g3d_surface *gsurf; + struct pipe_resource *ptex = NULL; + EGLint pbuffer_attribs[32]; + EGLint count, i; + + switch (buftype) { + case EGL_OPENVG_IMAGE: + break; + default: + _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer"); + return NULL; + break; + } + + /* parse the attributes first */ + count = 0; + for (i = 0; attribs && attribs[i] != EGL_NONE; i++) { + EGLint attr = attribs[i++]; + EGLint val = attribs[i]; + EGLint err = EGL_SUCCESS; + + switch (attr) { + case EGL_TEXTURE_FORMAT: + case EGL_TEXTURE_TARGET: + case EGL_MIPMAP_TEXTURE: + pbuffer_attribs[count++] = attr; + pbuffer_attribs[count++] = val; + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + /* bail out */ + if (err != EGL_SUCCESS) { + _eglError(err, "eglCreatePbufferFromClientBuffer"); + return NULL; + } + } + + pbuffer_attribs[count++] = EGL_NONE; + + gsurf = create_pbuffer_surface(dpy, conf, pbuffer_attribs, + "eglCreatePbufferFromClientBuffer"); + if (!gsurf) + return NULL; + + gsurf->client_buffer_type = buftype; + gsurf->client_buffer = buffer; + + if (!gsurf->stfbi->validate(gsurf->stfbi, + &gsurf->stvis.render_buffer, 1, &ptex)) { + egl_g3d_destroy_st_framebuffer(gsurf->stfbi); + FREE(gsurf); + return NULL; + } + return &gsurf->base; } @@ -428,7 +518,6 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, _EGLContext *ctx = _eglGetCurrentContext(); struct egl_g3d_config *gconf; struct native_surface *nsurf; - struct pipe_screen *screen = gdpy->native->screen; struct pipe_resource *ptex; if (!gsurf->render_texture) @@ -460,7 +549,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); if (ptex) { - struct pipe_surface *psrc; + struct pipe_resource *psrc = gsurf->render_texture; struct pipe_subresource subsrc, subdst; subsrc.face = 0; subsrc.level = 0; @@ -704,6 +793,7 @@ egl_g3d_init_driver_api(_EGLDriver *drv) drv->API.CreateWindowSurface = egl_g3d_create_window_surface; drv->API.CreatePixmapSurface = egl_g3d_create_pixmap_surface; drv->API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface; + drv->API.CreatePbufferFromClientBuffer = egl_g3d_create_pbuffer_from_client_buffer; drv->API.DestroySurface = egl_g3d_destroy_surface; drv->API.MakeCurrent = egl_g3d_make_current; drv->API.SwapBuffers = egl_g3d_swap_buffers; 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 cdf13140cb..e2217b3b2b 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c @@ -29,6 +29,8 @@ #include "util/u_memory.h" #include "util/u_string.h" #include "util/u_inlines.h" +#include "util/u_pointer.h" +#include "util/u_format.h" #include "util/u_dl.h" #include "egldriver.h" #include "eglimage.h" @@ -62,6 +64,11 @@ egl_g3d_search_path_callback(const char *dir, size_t len, void *callback_data) char path[1024]; int ret; + if (!len) { + stmod->lib = util_dl_open(stmod->filename); + return !(stmod->lib); + } + ret = util_snprintf(path, sizeof(path), "%.*s/%s", len, dir, stmod->filename); if (ret > 0 && ret < sizeof(path)) @@ -103,6 +110,12 @@ egl_g3d_load_st_module(struct egl_g3d_st_module *stmod, } } +#ifdef PIPE_OS_WINDOWS +#define ST_MODULE_SUFFIX ".dll" +#else +#define ST_MODULE_SUFFIX ".so" +#endif + void egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT]) { @@ -121,24 +134,24 @@ egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT]) case ST_API_OPENGL: skip_checks[api] = "glColor4d"; symbols[api] = ST_CREATE_OPENGL_SYMBOL; - filenames[api][count++] = "api_GL.so"; + filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX; break; case ST_API_OPENGL_ES1: skip_checks[api] = "glColor4x"; symbols[api] = ST_CREATE_OPENGL_ES1_SYMBOL; - filenames[api][count++] = "api_GLESv1_CM.so"; - filenames[api][count++] = "api_GL.so"; + filenames[api][count++] = "api_GLESv1_CM" ST_MODULE_SUFFIX; + filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX; break; case ST_API_OPENGL_ES2: skip_checks[api] = "glShaderBinary"; symbols[api] = ST_CREATE_OPENGL_ES2_SYMBOL; - filenames[api][count++] = "api_GLESv2.so"; - filenames[api][count++] = "api_GL.so"; + filenames[api][count++] = "api_GLESv2" ST_MODULE_SUFFIX; + filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX; break; case ST_API_OPENVG: skip_checks[api] = "vgClear"; symbols[api] = ST_CREATE_OPENVG_SYMBOL; - filenames[api][count++]= "api_OpenVG.so"; + filenames[api][count++]= "api_OpenVG" ST_MODULE_SUFFIX; break; default: assert(!"Unknown API Type\n"); @@ -206,6 +219,7 @@ egl_g3d_destroy_st_apis(void) static boolean egl_g3d_st_manager_get_egl_image(struct st_manager *smapi, + struct st_context_iface *stctx, void *egl_image, struct st_egl_image *out) { @@ -275,7 +289,34 @@ egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_framebuffer_iface *stfbi, return TRUE; } -static boolean +static void +pbuffer_reference_openvg_image(struct egl_g3d_surface *gsurf) +{ + /* TODO */ +} + +static void +pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf) +{ + struct egl_g3d_display *gdpy = + egl_g3d_display(gsurf->base.Resource.Display); + struct pipe_screen *screen = gdpy->native->screen; + struct pipe_resource templ, *ptex; + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = gsurf->base.Width; + templ.height0 = gsurf->base.Height; + templ.depth0 = 1; + templ.format = gsurf->stvis.color_format; + templ.bind = PIPE_BIND_RENDER_TARGET; + + ptex = screen->resource_create(screen, &templ); + gsurf->render_texture = ptex; +} + +static boolean egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi, const enum st_attachment_type *statts, unsigned count, @@ -283,7 +324,6 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi, { _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - struct pipe_resource templ; unsigned i; for (i = 0; i < count; i++) { @@ -293,20 +333,19 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi, continue; if (!gsurf->render_texture) { - struct egl_g3d_display *gdpy = - egl_g3d_display(gsurf->base.Resource.Display); - struct pipe_screen *screen = gdpy->native->screen; - - memset(&templ, 0, sizeof(templ)); - templ.target = PIPE_TEXTURE_2D; - templ.last_level = 0; - templ.width0 = gsurf->base.Width; - templ.height0 = gsurf->base.Height; - templ.depth0 = 1; - templ.format = gsurf->stvis.color_format; - templ.bind = PIPE_BIND_RENDER_TARGET; - - gsurf->render_texture = screen->resource_create(screen, &templ); + switch (gsurf->client_buffer_type) { + case EGL_NONE: + pbuffer_allocate_render_texture(gsurf); + break; + case EGL_OPENVG_IMAGE: + pbuffer_reference_openvg_image(gsurf); + break; + default: + break; + } + + if (!gsurf->render_texture) + return FALSE; } pipe_resource_reference(&out[i], gsurf->render_texture); diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c new file mode 100644 index 0000000000..7832b2b693 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native_helper.c @@ -0,0 +1,235 @@ +/* + * 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 <olv@lunarg.com> + */ + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" + +#include "native_helper.h" + +struct resource_surface { + struct pipe_screen *screen; + enum pipe_format format; + uint bind; + + struct pipe_resource *resources[NUM_NATIVE_ATTACHMENTS]; + struct pipe_surface *present_surfaces[NUM_NATIVE_ATTACHMENTS]; + uint resource_mask; + uint width, height; +}; + +struct resource_surface * +resource_surface_create(struct pipe_screen *screen, + enum pipe_format format, uint bind) +{ + struct resource_surface *rsurf = CALLOC_STRUCT(resource_surface); + + if (rsurf) { + rsurf->screen = screen; + rsurf->format = format; + rsurf->bind = bind; + } + + return rsurf; +} + +static void +resource_surface_free_resources(struct resource_surface *rsurf) +{ + if (rsurf->resource_mask) { + int i; + + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { + if (rsurf->present_surfaces[i]) + pipe_surface_reference(&rsurf->present_surfaces[i], NULL); + if (rsurf->resources[i]) + pipe_resource_reference(&rsurf->resources[i], NULL); + } + rsurf->resource_mask = 0x0; + } +} + +void +resource_surface_destroy(struct resource_surface *rsurf) +{ + resource_surface_free_resources(rsurf); + FREE(rsurf); +} + +boolean +resource_surface_set_size(struct resource_surface *rsurf, + uint width, uint height) +{ + boolean changed = FALSE; + + if (rsurf->width != width || rsurf->height != height) { + resource_surface_free_resources(rsurf); + rsurf->width = width; + rsurf->height = height; + changed = TRUE; + } + + return changed; +} + +void +resource_surface_get_size(struct resource_surface *rsurf, + uint *width, uint *height) +{ + if (width) + *width = rsurf->width; + if (height) + *height = rsurf->height; +} + +boolean +resource_surface_add_resources(struct resource_surface *rsurf, + uint resource_mask) +{ + struct pipe_resource templ; + int i; + + resource_mask &= ~rsurf->resource_mask; + if (!resource_mask) + return TRUE; + + if (!rsurf->width || !rsurf->height) + return FALSE; + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.format = rsurf->format; + templ.bind = rsurf->bind; + templ.width0 = rsurf->width; + templ.height0 = rsurf->height; + templ.depth0 = 1; + + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { + if (resource_mask & (1 <<i)) { + assert(!rsurf->resources[i]); + + rsurf->resources[i] = + rsurf->screen->resource_create(rsurf->screen, &templ); + if (rsurf->resources[i]) + rsurf->resource_mask |= 1 << i; + } + } + + return ((rsurf->resource_mask & resource_mask) == resource_mask); +} + + +void +resource_surface_get_resources(struct resource_surface *rsurf, + struct pipe_resource **resources, + uint resource_mask) +{ + int i; + + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { + if (resource_mask & (1 << i)) { + resources[i] = NULL; + pipe_resource_reference(&resources[i], rsurf->resources[i]); + } + } +} + +struct pipe_resource * +resource_surface_get_single_resource(struct resource_surface *rsurf, + enum native_attachment which) +{ + struct pipe_resource *pres = NULL; + pipe_resource_reference(&pres, rsurf->resources[which]); + return pres; +} + +static INLINE void +pointer_swap(const void **p1, const void **p2) +{ + const void *tmp = *p1; + *p1 = *p2; + *p2 = tmp; +} + +void +resource_surface_swap_buffers(struct resource_surface *rsurf, + enum native_attachment buf1, + enum native_attachment buf2, + boolean only_if_exist) +{ + const uint buf1_bit = 1 << buf1; + const uint buf2_bit = 1 << buf2; + uint mask; + + if (only_if_exist && !(rsurf->resources[buf1] && rsurf->resources[buf2])) + return; + + pointer_swap((const void **) &rsurf->resources[buf1], + (const void **) &rsurf->resources[buf2]); + pointer_swap((const void **) &rsurf->present_surfaces[buf1], + (const void **) &rsurf->present_surfaces[buf2]); + + /* swap mask bits */ + mask = rsurf->resource_mask & ~(buf1_bit | buf2_bit); + if (rsurf->resource_mask & buf1_bit) + mask |= buf2_bit; + if (rsurf->resource_mask & buf2_bit) + mask |= buf1_bit; + + rsurf->resource_mask = mask; +} + +boolean +resource_surface_present(struct resource_surface *rsurf, + enum native_attachment which, + void *winsys_drawable_handle) +{ + struct pipe_resource *pres = rsurf->resources[which]; + struct pipe_surface *psurf = rsurf->present_surfaces[which]; + + if (!pres) + return TRUE; + + if (!psurf) { + psurf = rsurf->screen->get_tex_surface(rsurf->screen, + pres, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET); + if (!psurf) + return FALSE; + + rsurf->present_surfaces[which] = psurf; + } + + assert(psurf->texture == pres); + + rsurf->screen->flush_frontbuffer(rsurf->screen, + psurf, winsys_drawable_handle); + + return TRUE; +} diff --git a/src/gallium/state_trackers/egl/common/native_helper.h b/src/gallium/state_trackers/egl/common/native_helper.h new file mode 100644 index 0000000000..62956d5220 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native_helper.h @@ -0,0 +1,70 @@ +/* + * 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 <olv@lunarg.com> + */ + +#include "native.h" + +struct resource_surface; + +struct resource_surface * +resource_surface_create(struct pipe_screen *screen, + enum pipe_format format, uint bind); + +void +resource_surface_destroy(struct resource_surface *rsurf); + +boolean +resource_surface_set_size(struct resource_surface *rsurf, + uint width, uint height); + +void +resource_surface_get_size(struct resource_surface *rsurf, + uint *width, uint *height); + +boolean +resource_surface_add_resources(struct resource_surface *rsurf, + uint resource_mask); + +void +resource_surface_get_resources(struct resource_surface *rsurf, + struct pipe_resource **resources, + uint resource_mask); + +struct pipe_resource * +resource_surface_get_single_resource(struct resource_surface *rsurf, + enum native_attachment which); + +void +resource_surface_swap_buffers(struct resource_surface *rsurf, + enum native_attachment buf1, + enum native_attachment buf2, + boolean only_if_exist); + +boolean +resource_surface_present(struct resource_surface *rsurf, + enum native_attachment which, + void *winsys_drawable_handle); diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c new file mode 100644 index 0000000000..29e89bcae8 --- /dev/null +++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c @@ -0,0 +1,427 @@ +/* + * 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 <olv@lunarg.com> + */ + +#include <windows.h> + +#include "pipe/p_compiler.h" +#include "util/u_memory.h" +#include "util/u_format.h" +#include "util/u_inlines.h" +#include "target-helpers/wrap_screen.h" +#include "llvmpipe/lp_public.h" +#include "softpipe/sp_public.h" +#include "gdi/gdi_sw_winsys.h" + +#include "common/native_helper.h" +#include "common/native.h" + +struct gdi_display { + struct native_display base; + + HDC hDC; + struct native_event_handler *event_handler; + + struct native_config *configs; + int num_configs; +}; + +struct gdi_surface { + struct native_surface base; + + HWND hWnd; + enum pipe_format color_format; + + struct gdi_display *gdpy; + + unsigned int server_stamp; + unsigned int client_stamp; + + struct resource_surface *rsurf; +}; + +static INLINE struct gdi_display * +gdi_display(const struct native_display *ndpy) +{ + return (struct gdi_display *) ndpy; +} + +static INLINE struct gdi_surface * +gdi_surface(const struct native_surface *nsurf) +{ + return (struct gdi_surface *) nsurf; +} + +/** + * Update the geometry of the surface. This is a slow functions. + */ +static void +gdi_surface_update_geometry(struct native_surface *nsurf) +{ + struct gdi_surface *gsurf = gdi_surface(nsurf); + RECT rect; + uint w, h; + + GetClientRect(gsurf->hWnd, &rect); + w = rect.right - rect.left; + h = rect.bottom - rect.top; + + if (resource_surface_set_size(gsurf->rsurf, w, h)) + gsurf->server_stamp++; +} + +/** + * Update the buffers of the surface. + */ +static boolean +gdi_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask) +{ + struct gdi_surface *gsurf = gdi_surface(nsurf); + + if (gsurf->client_stamp != gsurf->server_stamp) { + gdi_surface_update_geometry(&gsurf->base); + gsurf->client_stamp = gsurf->server_stamp; + } + + return resource_surface_add_resources(gsurf->rsurf, buffer_mask); +} + +/** + * Emulate an invalidate event. + */ +static void +gdi_surface_invalidate(struct native_surface *nsurf) +{ + struct gdi_surface *gsurf = gdi_surface(nsurf); + struct gdi_display *gdpy = gsurf->gdpy; + + gsurf->server_stamp++; + gdpy->event_handler->invalid_surface(&gdpy->base, + &gsurf->base, gsurf->server_stamp); +} + +static boolean +gdi_surface_flush_frontbuffer(struct native_surface *nsurf) +{ + struct gdi_surface *gsurf = gdi_surface(nsurf); + HDC hDC; + boolean ret; + + hDC = GetDC(gsurf->hWnd); + ret = resource_surface_present(gsurf->rsurf, + NATIVE_ATTACHMENT_FRONT_LEFT, (void *) hDC); + ReleaseDC(gsurf->hWnd, hDC); + + /* force buffers to be updated in next validation call */ + gdi_surface_invalidate(&gsurf->base); + + return ret; +} + +static boolean +gdi_surface_swap_buffers(struct native_surface *nsurf) +{ + struct gdi_surface *gsurf = gdi_surface(nsurf); + HDC hDC; + boolean ret; + + hDC = GetDC(gsurf->hWnd); + ret = resource_surface_present(gsurf->rsurf, + NATIVE_ATTACHMENT_BACK_LEFT, (void *) hDC); + ReleaseDC(gsurf->hWnd, hDC); + + resource_surface_swap_buffers(gsurf->rsurf, + NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE); + /* the front/back buffers have been swapped */ + gdi_surface_invalidate(&gsurf->base); + + return ret; +} + +static boolean +gdi_surface_validate(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_resource **textures, + int *width, int *height) +{ + struct gdi_surface *gsurf = gdi_surface(nsurf); + uint w, h; + + if (!gdi_surface_update_buffers(&gsurf->base, attachment_mask)) + return FALSE; + + if (seq_num) + *seq_num = gsurf->client_stamp; + + if (textures) + resource_surface_get_resources(gsurf->rsurf, textures, attachment_mask); + + resource_surface_get_size(gsurf->rsurf, &w, &h); + if (width) + *width = w; + if (height) + *height = h; + + return TRUE; +} + +static void +gdi_surface_wait(struct native_surface *nsurf) +{ + /* no-op */ +} + +static void +gdi_surface_destroy(struct native_surface *nsurf) +{ + struct gdi_surface *gsurf = gdi_surface(nsurf); + + resource_surface_destroy(gsurf->rsurf); + FREE(gsurf); +} + +static struct native_surface * +gdi_display_create_window_surface(struct native_display *ndpy, + EGLNativeWindowType win, + const struct native_config *nconf) +{ + struct gdi_display *gdpy = gdi_display(ndpy); + struct gdi_surface *gsurf; + + gsurf = CALLOC_STRUCT(gdi_surface); + if (!gsurf) + return NULL; + + gsurf->gdpy = gdpy; + gsurf->color_format = nconf->color_format; + gsurf->hWnd = (HWND) win; + + gsurf->rsurf = resource_surface_create(gdpy->base.screen, + gsurf->color_format, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT); + if (!gsurf->rsurf) { + FREE(gsurf); + return NULL; + } + + /* initialize the geometry */ + gdi_surface_update_geometry(&gsurf->base); + + gsurf->base.destroy = gdi_surface_destroy; + gsurf->base.swap_buffers = gdi_surface_swap_buffers; + gsurf->base.flush_frontbuffer = gdi_surface_flush_frontbuffer; + gsurf->base.validate = gdi_surface_validate; + gsurf->base.wait = gdi_surface_wait; + + return &gsurf->base; +} + +static int +fill_color_formats(struct native_display *ndpy, enum pipe_format formats[8]) +{ + struct pipe_screen *screen = ndpy->screen; + int i, count = 0; + + enum pipe_format candidates[] = { + /* 32-bit */ + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_A8R8G8B8_UNORM, + /* 24-bit */ + PIPE_FORMAT_B8G8R8X8_UNORM, + PIPE_FORMAT_X8R8G8B8_UNORM, + /* 16-bit */ + PIPE_FORMAT_B5G6R5_UNORM + }; + + assert(Elements(candidates) <= 8); + + for (i = 0; i < Elements(candidates); i++) { + if (screen->is_format_supported(screen, candidates[i], + PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0)) + formats[count++] = candidates[i]; + } + + return count; +} + +static const struct native_config ** +gdi_display_get_configs(struct native_display *ndpy, int *num_configs) +{ + struct gdi_display *gdpy = gdi_display(ndpy); + const struct native_config **configs; + int i; + + /* first time */ + if (!gdpy->configs) { + enum pipe_format formats[8]; + int i, count; + + count = fill_color_formats(&gdpy->base, formats); + + gdpy->configs = CALLOC(count, sizeof(*gdpy->configs)); + if (!gdpy->configs) + return NULL; + + for (i = 0; i < count; i++) { + struct native_config *nconf = &gdpy->configs[i]; + + nconf->buffer_mask = + (1 << NATIVE_ATTACHMENT_FRONT_LEFT) | + (1 << NATIVE_ATTACHMENT_BACK_LEFT); + nconf->color_format = formats[i]; + + nconf->window_bit = TRUE; + nconf->slow_config = TRUE; + } + + gdpy->num_configs = count; + } + + configs = MALLOC(gdpy->num_configs * sizeof(*configs)); + if (configs) { + for (i = 0; i < gdpy->num_configs; i++) + configs[i] = (const struct native_config *) &gdpy->configs[i]; + if (num_configs) + *num_configs = gdpy->num_configs; + } + return configs; +} + +static int +gdi_display_get_param(struct native_display *ndpy, + enum native_param_type param) +{ + int val; + + switch (param) { + case NATIVE_PARAM_USE_NATIVE_BUFFER: + /* private buffers are allocated */ + val = FALSE; + break; + default: + val = 0; + break; + } + + return val; +} + +static void +gdi_display_destroy(struct native_display *ndpy) +{ + struct gdi_display *gdpy = gdi_display(ndpy); + + if (gdpy->configs) + FREE(gdpy->configs); + + gdpy->base.screen->destroy(gdpy->base.screen); + + FREE(gdpy); +} + +static struct native_display * +gdi_create_display(HDC hDC, struct pipe_screen *screen, + struct native_event_handler *event_handler) +{ + struct gdi_display *gdpy; + + gdpy = CALLOC_STRUCT(gdi_display); + if (!gdpy) + return NULL; + + gdpy->hDC = hDC; + gdpy->event_handler = event_handler; + + gdpy->base.screen = screen; + + gdpy->base.destroy = gdi_display_destroy; + gdpy->base.get_param = gdi_display_get_param; + + gdpy->base.get_configs = gdi_display_get_configs; + gdpy->base.create_window_surface = gdi_display_create_window_surface; + + return &gdpy->base; +} + +static struct pipe_screen * +gdi_create_screen(void) +{ + struct sw_winsys *winsys; + struct pipe_screen *screen = NULL; + + winsys = gdi_create_sw_winsys(); + if (!winsys) + return NULL; + +#if defined(GALLIUM_LLVMPIPE) + if (!screen && !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE)) + screen = llvmpipe_create_screen(winsys); +#endif + if (!screen) + screen = softpipe_create_screen(winsys); + + if (!screen) { + if (winsys->destroy) + winsys->destroy(winsys); + return NULL; + } + + return gallium_wrap_screen(screen); +} + +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy) +{ + return NULL; +} + +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe) +{ + return NATIVE_PROBE_UNKNOWN; +} + +const char * +native_get_name(void) +{ + return "GDI"; +} + +struct native_display * +native_create_display(EGLNativeDisplayType dpy, + struct native_event_handler *event_handler) +{ + struct pipe_screen *screen; + + screen = gdi_create_screen(); + if (!screen) + return NULL; + + return gdi_create_display((HDC) dpy, screen, event_handler); +} diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c index d81178e559..bfb4a9d258 100644 --- a/src/gallium/state_trackers/egl/kms/native_kms.c +++ b/src/gallium/state_trackers/egl/kms/native_kms.c @@ -28,6 +28,7 @@ #include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_inlines.h" +#include "util/u_pointer.h" #include "util/u_string.h" #include "egllog.h" @@ -39,39 +40,11 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask, int *width, int *height) { struct kms_surface *ksurf = kms_surface(nsurf); - struct kms_display *kdpy = ksurf->kdpy; - struct pipe_screen *screen = kdpy->base.screen; - struct pipe_resource templ, *ptex; - int att; - - if (attachment_mask) { - memset(&templ, 0, sizeof(templ)); - templ.target = PIPE_TEXTURE_2D; - templ.last_level = 0; - templ.width0 = ksurf->width; - templ.height0 = ksurf->height; - templ.depth0 = 1; - templ.format = ksurf->color_format; - templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SCANOUT; - } - - /* create textures */ - for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { - /* delay the allocation */ - if (!native_attachment_mask_test(attachment_mask, att)) - continue; - - ptex = ksurf->textures[att]; - if (!ptex) { - ptex = screen->resource_create(screen, &templ); - ksurf->textures[att] = ptex; - } - if (textures) { - textures[att] = NULL; - pipe_resource_reference(&textures[att], ptex); - } - } + if (!resource_surface_add_resources(ksurf->rsurf, attachment_mask)) + return FALSE; + if (textures) + resource_surface_get_resources(ksurf->rsurf, textures, attachment_mask); if (seq_num) *seq_num = ksurf->sequence_number; @@ -111,11 +84,11 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back) if (!fb->texture) { /* make sure the texture has been allocated */ - kms_surface_validate(&ksurf->base, 1 << natt, NULL, NULL, NULL, NULL); - if (!ksurf->textures[natt]) + resource_surface_add_resources(ksurf->rsurf, 1 << natt); + fb->texture = + resource_surface_get_single_resource(ksurf->rsurf, natt); + if (!fb->texture) return FALSE; - - pipe_resource_reference(&fb->texture, ksurf->textures[natt]); } /* already initialized */ @@ -166,7 +139,6 @@ kms_surface_swap_buffers(struct native_surface *nsurf) struct kms_crtc *kcrtc = &ksurf->current_crtc; struct kms_display *kdpy = ksurf->kdpy; struct kms_framebuffer tmp_fb; - struct pipe_resource *tmp_texture; int err; if (!ksurf->back_fb.buffer_id) { @@ -187,11 +159,8 @@ kms_surface_swap_buffers(struct native_surface *nsurf) ksurf->front_fb = ksurf->back_fb; ksurf->back_fb = tmp_fb; - tmp_texture = ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT]; - ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT] = - ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT]; - ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT] = tmp_texture; - + resource_surface_swap_buffers(ksurf->rsurf, + NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE); /* the front/back textures are swapped */ ksurf->sequence_number++; kdpy->event_handler->invalid_surface(&kdpy->base, @@ -210,7 +179,6 @@ static void kms_surface_destroy(struct native_surface *nsurf) { struct kms_surface *ksurf = kms_surface(nsurf); - int i; if (ksurf->current_crtc.crtc) drmModeFreeCrtc(ksurf->current_crtc.crtc); @@ -223,11 +191,7 @@ kms_surface_destroy(struct native_surface *nsurf) drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id); pipe_resource_reference(&ksurf->back_fb.texture, NULL); - for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { - struct pipe_resource *ptex = ksurf->textures[i]; - pipe_resource_reference(&ptex, NULL); - } - + resource_surface_destroy(ksurf->rsurf); FREE(ksurf); } @@ -249,6 +213,19 @@ kms_display_create_surface(struct native_display *ndpy, ksurf->width = width; ksurf->height = height; + ksurf->rsurf = resource_surface_create(kdpy->base.screen, + ksurf->color_format, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT); + if (!ksurf->rsurf) { + FREE(ksurf); + return NULL; + } + + resource_surface_set_size(ksurf->rsurf, ksurf->width, ksurf->height); + ksurf->base.destroy = kms_surface_destroy; ksurf->base.swap_buffers = kms_surface_swap_buffers; ksurf->base.flush_frontbuffer = kms_surface_flush_frontbuffer; @@ -694,7 +671,27 @@ kms_display_init_screen(struct native_display *ndpy) struct kms_display *kdpy = kms_display(ndpy); int fd; - fd = drmOpen(kdpy->api->driver_name, NULL); + fd = kdpy->fd; + if (fd >= 0) { + drmVersionPtr version = drmGetVersion(fd); + if (!version || strcmp(version->name, kdpy->api->driver_name)) { + if (version) { + _eglLog(_EGL_WARNING, "unknown driver name %s", version->name); + drmFreeVersion(version); + } + else { + _eglLog(_EGL_WARNING, "invalid fd %d", fd); + } + + return FALSE; + } + + drmFreeVersion(version); + } + else { + fd = drmOpen(kdpy->api->driver_name, NULL); + } + if (fd < 0) { _eglLog(_EGL_WARNING, "failed to open DRM device"); return FALSE; @@ -707,7 +704,7 @@ kms_display_init_screen(struct native_display *ndpy) } #endif - kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, NULL); + kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd); if (!kdpy->base.screen) { _eglLog(_EGL_WARNING, "failed to create DRM screen"); drmClose(fd); @@ -727,8 +724,7 @@ static struct native_display_modeset kms_display_modeset = { }; static struct native_display * -kms_create_display(EGLNativeDisplayType dpy, - struct native_event_handler *event_handler, +kms_create_display(int fd, struct native_event_handler *event_handler, struct drm_api *api) { struct kms_display *kdpy; @@ -746,7 +742,7 @@ kms_create_display(EGLNativeDisplayType dpy, return NULL; } - kdpy->fd = -1; + kdpy->fd = fd; if (!kms_display_init_screen(&kdpy->base)) { kms_display_destroy(&kdpy->base); return NULL; @@ -818,12 +814,17 @@ native_create_display(EGLNativeDisplayType dpy, struct native_event_handler *event_handler) { struct native_display *ndpy = NULL; + int fd; if (!drm_api) drm_api = drm_api_create(); - if (drm_api) - ndpy = kms_create_display(dpy, event_handler, drm_api); + if (drm_api) { + /* well, this makes fd 0 being ignored */ + fd = (dpy != EGL_DEFAULT_DISPLAY) ? + (int) pointer_to_intptr((void *) dpy) : -1; + ndpy = kms_create_display(fd, event_handler, drm_api); + } return ndpy; } diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h index 3b08e930c5..d69c8d38c8 100644 --- a/src/gallium/state_trackers/egl/kms/native_kms.h +++ b/src/gallium/state_trackers/egl/kms/native_kms.h @@ -35,6 +35,7 @@ #include "state_tracker/drm_api.h" #include "common/native.h" +#include "common/native_helper.h" struct kms_config; struct kms_connector; @@ -73,11 +74,12 @@ struct kms_framebuffer { struct kms_surface { struct native_surface base; - enum pipe_format color_format; struct kms_display *kdpy; + + struct resource_surface *rsurf; + enum pipe_format color_format; int width, height; - struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS]; unsigned int sequence_number; struct kms_framebuffer front_fb, back_fb; diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c index 47f5423b67..3388fc61e1 100644 --- a/src/gallium/state_trackers/egl/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -37,6 +37,7 @@ #include "llvmpipe/lp_public.h" #include "egllog.h" +#include "common/native_helper.h" #include "native_x11.h" #include "x11_screen.h" @@ -59,11 +60,6 @@ struct ximage_display { int num_configs; }; -struct ximage_buffer { - struct pipe_resource *texture; - struct xlib_drawable xdraw; -}; - struct ximage_surface { struct native_surface base; Drawable drawable; @@ -74,11 +70,9 @@ struct ximage_surface { unsigned int server_stamp; unsigned int client_stamp; - int width, height; - struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS]; - uint valid_mask; - struct pipe_surface *draw_surface; + struct resource_surface *rsurf; + struct xlib_drawable xdraw; }; struct ximage_config { @@ -104,68 +98,10 @@ ximage_config(const struct native_config *nconf) return (struct ximage_config *) nconf; } -static void -ximage_surface_free_buffer(struct native_surface *nsurf, - enum native_attachment which) -{ - struct ximage_surface *xsurf = ximage_surface(nsurf); - struct ximage_buffer *xbuf = &xsurf->buffers[which]; - - pipe_resource_reference(&xbuf->texture, NULL); -} - -static boolean -ximage_surface_alloc_buffer(struct native_surface *nsurf, - enum native_attachment which) -{ - struct ximage_surface *xsurf = ximage_surface(nsurf); - struct ximage_buffer *xbuf = &xsurf->buffers[which]; - struct pipe_screen *screen = xsurf->xdpy->base.screen; - struct pipe_resource templ; - - /* free old data */ - if (xbuf->texture) - ximage_surface_free_buffer(&xsurf->base, which); - - memset(&templ, 0, sizeof(templ)); - templ.target = PIPE_TEXTURE_2D; - templ.format = xsurf->color_format; - templ.width0 = xsurf->width; - templ.height0 = xsurf->height; - templ.depth0 = 1; - templ.bind = PIPE_BIND_RENDER_TARGET; - - switch (which) { - case NATIVE_ATTACHMENT_FRONT_LEFT: - case NATIVE_ATTACHMENT_FRONT_RIGHT: - templ.bind |= PIPE_BIND_SCANOUT; - break; - case NATIVE_ATTACHMENT_BACK_LEFT: - case NATIVE_ATTACHMENT_BACK_RIGHT: - templ.bind |= PIPE_BIND_DISPLAY_TARGET; - break; - default: - break; - } - xbuf->texture = screen->resource_create(screen, &templ); - if (xbuf->texture) { - xbuf->xdraw.visual = xsurf->visual.visual; - xbuf->xdraw.depth = xsurf->visual.depth; - xbuf->xdraw.drawable = xsurf->drawable; - } - - /* clean up the buffer if allocation failed */ - if (!xbuf->texture) - ximage_surface_free_buffer(&xsurf->base, which); - - return (xbuf->texture != NULL); -} - /** - * Update the geometry of the surface. Return TRUE if the geometry has changed - * since last call. + * Update the geometry of the surface. This is a slow functions. */ -static boolean +static void ximage_surface_update_geometry(struct native_surface *nsurf) { struct ximage_surface *xsurf = ximage_surface(nsurf); @@ -173,102 +109,41 @@ ximage_surface_update_geometry(struct native_surface *nsurf) Window root; int x, y; unsigned int w, h, border, depth; - boolean updated = FALSE; ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable, &root, &x, &y, &w, &h, &border, &depth); - if (ok && (xsurf->width != w || xsurf->height != h)) { - xsurf->width = w; - xsurf->height = h; - + if (ok && resource_surface_set_size(xsurf->rsurf, w, h)) xsurf->server_stamp++; - updated = TRUE; - } - - return updated; -} - -static void -ximage_surface_notify_invalid(struct native_surface *nsurf) -{ - struct ximage_surface *xsurf = ximage_surface(nsurf); - struct ximage_display *xdpy = xsurf->xdpy; - - xdpy->event_handler->invalid_surface(&xdpy->base, - &xsurf->base, xsurf->server_stamp); } /** - * Update the buffers of the surface. It is a slow function due to the - * round-trip to the server. + * Update the buffers of the surface. */ static boolean ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask) { struct ximage_surface *xsurf = ximage_surface(nsurf); - boolean updated; - uint new_valid; - int att; - - updated = ximage_surface_update_geometry(&xsurf->base); - if (updated) { - /* all buffers become invalid */ - xsurf->valid_mask = 0x0; - } - else { - buffer_mask &= ~xsurf->valid_mask; - /* all requested buffers are valid */ - if (!buffer_mask) { - xsurf->client_stamp = xsurf->server_stamp; - return TRUE; - } - } - new_valid = 0x0; - for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { - if (native_attachment_mask_test(buffer_mask, att)) { - /* reallocate the texture */ - if (!ximage_surface_alloc_buffer(&xsurf->base, att)) - break; - - new_valid |= (1 << att); - if (buffer_mask == new_valid) - break; - } + if (xsurf->client_stamp != xsurf->server_stamp) { + ximage_surface_update_geometry(&xsurf->base); + xsurf->client_stamp = xsurf->server_stamp; } - xsurf->valid_mask |= new_valid; - xsurf->client_stamp = xsurf->server_stamp; - - return (new_valid == buffer_mask); + return resource_surface_add_resources(xsurf->rsurf, buffer_mask); } -static boolean -ximage_surface_draw_buffer(struct native_surface *nsurf, - enum native_attachment which) +/** + * Emulate an invalidate event. + */ +static void +ximage_surface_invalidate(struct native_surface *nsurf) { struct ximage_surface *xsurf = ximage_surface(nsurf); - struct ximage_buffer *xbuf = &xsurf->buffers[which]; - struct pipe_screen *screen = xsurf->xdpy->base.screen; - struct pipe_surface *psurf; - - assert(xsurf->drawable && xbuf->texture); - - psurf = xsurf->draw_surface; - if (!psurf || psurf->texture != xbuf->texture) { - pipe_surface_reference(&xsurf->draw_surface, NULL); - - psurf = screen->get_tex_surface(screen, - xbuf->texture, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET); - if (!psurf) - return FALSE; - - xsurf->draw_surface = psurf; - } - - screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw); + struct ximage_display *xdpy = xsurf->xdpy; - return TRUE; + xsurf->server_stamp++; + xdpy->event_handler->invalid_surface(&xdpy->base, + &xsurf->base, xsurf->server_stamp); } static boolean @@ -277,11 +152,10 @@ ximage_surface_flush_frontbuffer(struct native_surface *nsurf) struct ximage_surface *xsurf = ximage_surface(nsurf); boolean ret; - ret = ximage_surface_draw_buffer(&xsurf->base, - NATIVE_ATTACHMENT_FRONT_LEFT); + ret = resource_surface_present(xsurf->rsurf, + NATIVE_ATTACHMENT_FRONT_LEFT, (void *) &xsurf->xdraw); /* force buffers to be updated in next validation call */ - xsurf->server_stamp++; - ximage_surface_notify_invalid(&xsurf->base); + ximage_surface_invalidate(&xsurf->base); return ret; } @@ -290,25 +164,15 @@ static boolean ximage_surface_swap_buffers(struct native_surface *nsurf) { struct ximage_surface *xsurf = ximage_surface(nsurf); - struct ximage_buffer *xfront, *xback, xtmp; boolean ret; - /* display the back buffer first */ - ret = ximage_surface_draw_buffer(&xsurf->base, - NATIVE_ATTACHMENT_BACK_LEFT); - /* force buffers to be updated in next validation call */ - xsurf->server_stamp++; - ximage_surface_notify_invalid(&xsurf->base); + ret = resource_surface_present(xsurf->rsurf, + NATIVE_ATTACHMENT_BACK_LEFT, (void *) &xsurf->xdraw); - xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT]; - xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT]; - - /* skip swapping unless there is a front buffer */ - if (xfront->texture) { - xtmp = *xfront; - *xfront = *xback; - *xback = xtmp; - } + resource_surface_swap_buffers(xsurf->rsurf, + NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE); + /* the front/back buffers have been swapped */ + ximage_surface_invalidate(&xsurf->base); return ret; } @@ -319,32 +183,22 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask, int *width, int *height) { struct ximage_surface *xsurf = ximage_surface(nsurf); + uint w, h; - if (xsurf->client_stamp != xsurf->server_stamp || - (xsurf->valid_mask & attachment_mask) != attachment_mask) { - if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask)) - return FALSE; - } + if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask)) + return FALSE; if (seq_num) *seq_num = xsurf->client_stamp; - if (textures) { - int att; - for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { - if (native_attachment_mask_test(attachment_mask, att)) { - struct ximage_buffer *xbuf = &xsurf->buffers[att]; - - textures[att] = NULL; - pipe_resource_reference(&textures[att], xbuf->texture); - } - } - } + if (textures) + resource_surface_get_resources(xsurf->rsurf, textures, attachment_mask); + resource_surface_get_size(xsurf->rsurf, &w, &h); if (width) - *width = xsurf->width; + *width = w; if (height) - *height = xsurf->height; + *height = h; return TRUE; } @@ -361,13 +215,8 @@ static void ximage_surface_destroy(struct native_surface *nsurf) { struct ximage_surface *xsurf = ximage_surface(nsurf); - int i; - - pipe_surface_reference(&xsurf->draw_surface, NULL); - - for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) - ximage_surface_free_buffer(&xsurf->base, i); + resource_surface_destroy(xsurf->rsurf); FREE(xsurf); } @@ -390,10 +239,25 @@ ximage_display_create_surface(struct native_display *ndpy, xsurf->color_format = xconf->base.color_format; xsurf->drawable = drawable; + xsurf->rsurf = resource_surface_create(xdpy->base.screen, + xsurf->color_format, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT); + if (!xsurf->rsurf) { + FREE(xsurf); + return NULL; + } + xsurf->drawable = drawable; xsurf->visual = *xconf->visual; /* initialize the geometry */ - ximage_surface_update_buffers(&xsurf->base, 0x0); + ximage_surface_update_geometry(&xsurf->base); + + xsurf->xdraw.visual = xsurf->visual.visual; + xsurf->xdraw.depth = xsurf->visual.depth; + xsurf->xdraw.drawable = xsurf->drawable; xsurf->base.destroy = ximage_surface_destroy; xsurf->base.swap_buffers = ximage_surface_swap_buffers; diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 0294e769a6..cf0144b5dc 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -414,39 +414,21 @@ error1: * Surface functions */ - void surface_copy(struct st_surface *dst, - unsigned destx, unsigned desty, - struct st_surface *src, - unsigned srcx, unsigned srcy, - unsigned width, unsigned height) + void resource_copy_region(struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, + unsigned width, unsigned height) { -/* XXX - struct pipe_surface *_dst = NULL; - struct pipe_surface *_src = NULL; - - _dst = st_pipe_surface(dst, PIPE_BIND_BLIT_DESTINATION); - if(!_dst) - SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing"); - - _src = st_pipe_surface(src, PIPE_BIND_BLIT_SOURCE); - if(!_src) - SWIG_exception(SWIG_ValueError, "couldn't acquire source surface for reading"); - - $self->pipe->surface_copy($self->pipe, _dst, destx, desty, _src, srcx, srcy, width, height); - - fail: - pipe_surface_reference(&_src, NULL); - pipe_surface_reference(&_dst, NULL); -*/ - struct pipe_subresource subdst, subsrc; - subsrc.face = src->face; - subsrc.level = src->level; - subdst.face = dst->face; - subdst.level = dst->level; - $self->pipe->resource_copy_region($self->pipe, dst->texture, subdst, destx, desty, dst->zslice, - src->texture, subsrc, srcx, srcy, src->zslice, width, height); + $self->pipe->resource_copy_region($self->pipe, + dst, subdst, dstx, dsty, dstz, + src, subsrc, srcx, srcy, srcz, + width, height); } + void clear_render_target(struct st_surface *dst, float *rgba, unsigned x, unsigned y, diff --git a/src/gallium/state_trackers/vega/SConscript b/src/gallium/state_trackers/vega/SConscript new file mode 100644 index 0000000000..548053eb64 --- /dev/null +++ b/src/gallium/state_trackers/vega/SConscript @@ -0,0 +1,51 @@ +####################################################################### +# SConscript for vega state_tracker + +Import('*') + +if 'egl' in env['statetrackers']: + + env = env.Clone() + + env.Append(CPPPATH = [ + '#/src/mapi', + ]) + + vega_sources = [ + 'api.c', + 'api_context.c', + 'api_filters.c', + 'api_images.c', + 'api_masks.c', + 'api_misc.c', + 'api_paint.c', + 'api_params.c', + 'api_path.c', + 'api_text.c', + 'api_transform.c', + 'vgu.c', + 'vg_context.c', + 'vg_manager.c', + 'vg_state.c', + 'vg_translate.c', + 'polygon.c', + 'bezier.c', + 'path.c', + 'paint.c', + 'arc.c', + 'image.c', + 'renderer.c', + 'stroker.c', + 'mask.c', + 'shader.c', + 'shaders_cache.c', + ] + + # vgapi_header must be generated first + env.Depends(vega_sources, vgapi_header) + + st_vega = env.ConvenienceLibrary( + target = 'st_vega', + source = vega_sources, + ) + Export('st_vega') diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c index 144fb8f323..8ace985336 100644 --- a/src/gallium/state_trackers/vega/api_filters.c +++ b/src/gallium/state_trackers/vega/api_filters.c @@ -42,6 +42,7 @@ #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_sampler.h" +#include "util/u_string.h" #include "asm_filters.h" @@ -271,7 +272,7 @@ static struct vg_shader * setup_convolution(struct vg_context *ctx, void *user_d VGint num_consts = (VGint)(long)(user_data); struct vg_shader *shader; - snprintf(buffer, 1023, convolution_asm, num_consts, num_consts / 2 + 1); + util_snprintf(buffer, 1023, convolution_asm, num_consts, num_consts / 2 + 1); shader = shader_create_from_text(ctx->pipe, buffer, 200, PIPE_SHADER_FRAGMENT); @@ -299,16 +300,16 @@ static struct vg_shader * setup_lookup_single(struct vg_context *ctx, void *user switch(channel) { case VG_RED: - snprintf(buffer, 1023, lookup_single_asm, "xxxx"); + util_snprintf(buffer, 1023, lookup_single_asm, "xxxx"); break; case VG_GREEN: - snprintf(buffer, 1023, lookup_single_asm, "yyyy"); + util_snprintf(buffer, 1023, lookup_single_asm, "yyyy"); break; case VG_BLUE: - snprintf(buffer, 1023, lookup_single_asm, "zzzz"); + util_snprintf(buffer, 1023, lookup_single_asm, "zzzz"); break; case VG_ALPHA: - snprintf(buffer, 1023, lookup_single_asm, "wwww"); + util_snprintf(buffer, 1023, lookup_single_asm, "wwww"); break; default: debug_assert(!"Unknown color channel"); diff --git a/src/gallium/state_trackers/vega/arc.c b/src/gallium/state_trackers/vega/arc.c index 2d12340870..65a985fbbb 100644 --- a/src/gallium/state_trackers/vega/arc.c +++ b/src/gallium/state_trackers/vega/arc.c @@ -33,8 +33,7 @@ #include "path.h" #include "util/u_debug.h" - -#include <math.h> +#include "util/u_math.h" #ifndef M_PI #define M_PI 3.14159265358979323846 diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index fe0f166e88..c40ea8675e 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -59,7 +59,8 @@ static void setup_shaders(struct renderer *ctx) { struct pipe_context *pipe = ctx->pipe; /* fragment shader */ - ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D); + ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D, + TGSI_INTERPOLATE_LINEAR); } static struct pipe_resource * diff --git a/src/gallium/state_trackers/vega/stroker.c b/src/gallium/state_trackers/vega/stroker.c index 68a52029db..d89b6cf25c 100644 --- a/src/gallium/state_trackers/vega/stroker.c +++ b/src/gallium/state_trackers/vega/stroker.c @@ -35,7 +35,7 @@ #include "path_utils.h" #include "polygon.h" -#include "math.h" +#include "util/u_math.h" #ifndef M_2PI #define M_2PI 6.28318530717958647692528676655900576 @@ -870,7 +870,7 @@ static VGboolean vg_stroke_outline(struct stroke_iterator *it, VGboolean cap_first, VGfloat *start_tangent) { - const int MAX_OFFSET = 16; +#define MAX_OFFSET 16 struct bezier offset_curves[MAX_OFFSET]; VGPathCommand first_element; VGfloat start[2], prev[2]; @@ -1017,6 +1017,7 @@ static VGboolean vg_stroke_outline(struct stroke_iterator *it, #endif return VG_FALSE; } +#undef MAX_OFFSET } static void stroker_process_subpath(struct stroker *stroker) diff --git a/src/gallium/state_trackers/vega/util_array.h b/src/gallium/state_trackers/vega/util_array.h index 4343dfe36e..b2d22f476e 100644 --- a/src/gallium/state_trackers/vega/util_array.h +++ b/src/gallium/state_trackers/vega/util_array.h @@ -65,7 +65,7 @@ static INLINE void array_destroy(struct array *array) { if (array) free(array->data); - free(array); + FREE(array); } static INLINE void array_resize(struct array *array, int num) diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index f9022a9f93..f1a07bd863 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -146,6 +146,7 @@ crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, /* XXX: hockup */ } +#if 0 /* Implement and enable to enable rotation and reflection. */ static void * crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) { @@ -168,6 +169,8 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) /* ScrnInfoPtr pScrn = crtc->scrn; */ } +#endif + /* * Cursor functions */ @@ -362,9 +365,9 @@ static const xf86CrtcFuncsRec crtc_funcs = { .hide_cursor = crtc_hide_cursor, .load_cursor_argb = crtc_load_cursor_argb, - .shadow_create = crtc_shadow_create, - .shadow_allocate = crtc_shadow_allocate, - .shadow_destroy = crtc_shadow_destroy, + .shadow_create = NULL, + .shadow_allocate = NULL, + .shadow_destroy = NULL, .gamma_set = crtc_gamma_set, .destroy = crtc_destroy, diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index e719644d34..4e01bd1030 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -299,6 +299,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, GCPtr gc; RegionPtr copy_clip; Bool save_accel; + CustomizerPtr cust = ms->cust; /* * In driCreateBuffers we dewrap windows into the @@ -352,7 +353,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, ValidateGC(dst_draw, gc); /* If this is a full buffer swap, throttle on the previous one */ - if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) { + if (ms->swapThrottling && + dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) { BoxPtr extents = REGION_EXTENTS(pScreen, pRegion); if (extents->x1 == 0 && extents->y1 == 0 && @@ -374,6 +376,9 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, DamageRegionAppend(src_draw, pRegion); DamageRegionProcessPending(src_draw); + if (cust && cust->winsys_context_throttle) + cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_SWAP); + (*gc->ops->CopyArea)(src_draw, dst_draw, gc, 0, 0, pDraw->width, pDraw->height, 0, 0); ms->exa->accel = save_accel; @@ -381,8 +386,13 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, FreeScratchGC(gc); ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, - pDestBuffer->attachment == DRI2BufferFrontLeft ? + (pDestBuffer->attachment == DRI2BufferFrontLeft + && ms->swapThrottling) ? &dst_priv->fence : NULL); + + if (cust && cust->winsys_context_throttle) + cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER); + } Bool diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 84c0545b1b..6b6e2009fe 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -79,12 +79,16 @@ typedef enum OPTION_SW_CURSOR, OPTION_2D_ACCEL, OPTION_DEBUG_FALLBACK, + OPTION_THROTTLE_SWAP, + OPTION_THROTTLE_DIRTY } drv_option_enums; static const OptionInfoRec drv_options[] = { {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_THROTTLE_SWAP, "SwapThrottling", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_THROTTLE_DIRTY, "DirtyThrottling", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -534,23 +538,29 @@ static void drv_block_handler(int i, pointer blockData, pointer pTimeout, if (ms->ctx) { int j; - ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]); + ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, + ms->dirtyThrottling ? + &ms->fence[XORG_NR_FENCES-1] : + NULL); - if (ms->fence[0]) - ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0); + if (ms->dirtyThrottling) { + if (ms->fence[0]) + ms->ctx->screen->fence_finish(ms->ctx->screen, + ms->fence[0], 0); - /* The amount of rendering generated by a block handler can be - * quite small. Let us get a fair way ahead of hardware before - * throttling. - */ - for (j = 0; j < XORG_NR_FENCES - 1; j++) - ms->screen->fence_reference(ms->screen, - &ms->fence[j], - ms->fence[j+1]); - - ms->screen->fence_reference(ms->screen, - &ms->fence[XORG_NR_FENCES-1], - NULL); + /* The amount of rendering generated by a block handler can be + * quite small. Let us get a fair way ahead of hardware before + * throttling. + */ + for (j = 0; j < XORG_NR_FENCES - 1; j++) + ms->screen->fence_reference(ms->screen, + &ms->fence[j], + ms->fence[j+1]); + + ms->screen->fence_reference(ms->screen, + &ms->fence[XORG_NR_FENCES-1], + NULL); + } } @@ -634,6 +644,8 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) unsigned max_width, max_height; VisualPtr visual; CustomizerPtr cust = ms->cust; + MessageType from_st; + MessageType from_dt; if (!drv_init_drm(pScrn)) { FatalError("Could not init DRM"); @@ -720,6 +732,19 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE); ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d); + if (cust && cust->winsys_screen_init) + cust->winsys_screen_init(cust, ms->fd); + + ms->swapThrottling = cust ? cust->swap_throttling : TRUE; + from_st = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_SWAP, + &ms->swapThrottling) ? + X_CONFIG : X_DEFAULT; + + ms->dirtyThrottling = cust ? cust->dirty_throttling : TRUE; + from_dt = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_DIRTY, + &ms->dirtyThrottling) ? + X_CONFIG : X_DEFAULT; + if (ms->screen) { ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d); @@ -744,6 +769,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n"); #endif + xf86DrvMsg(pScrn->scrnIndex, from_st, "Swap Throttling is %s.\n", + ms->swapThrottling ? "enabled" : "disabled"); + xf86DrvMsg(pScrn->scrnIndex, from_dt, "Dirty Throttling is %s.\n", + ms->dirtyThrottling ? "enabled" : "disabled"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n"); miInitializeBackingStore(pScreen); @@ -776,9 +806,6 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); - if (cust && cust->winsys_screen_init) - cust->winsys_screen_init(cust, ms->fd); - return drv_enter_vt(scrnIndex, 1); } diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index ee40bc8ccb..bd84668300 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -46,7 +46,6 @@ #include "util/u_math.h" #include "util/u_debug.h" #include "util/u_format.h" -#include "util/u_surface.h" #define DEBUG_PRINT 0 #define ROUND_UP_TEXTURES 1 @@ -987,6 +986,7 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel) modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa; ExaDriverPtr pExa; + CustomizerPtr cust = ms->cust; exa = xcalloc(1, sizeof(struct exa_context)); if (!exa) @@ -1048,6 +1048,8 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel) /* Share context with DRI */ ms->ctx = exa->pipe; + if (cust && cust->winsys_context_throttle) + cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER); exa->renderer = renderer_create(exa->pipe); exa->accel = accel; diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index e5def3e2ed..92f1cc5065 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.c +++ b/src/gallium/state_trackers/xorg/xorg_renderer.c @@ -8,7 +8,6 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_sampler.h" -#include "util/u_surface.h" #include "util/u_inlines.h" @@ -602,7 +601,7 @@ void renderer_copy_pixmap(struct xorg_renderer *r, void renderer_draw_yuv(struct xorg_renderer *r, - int src_x, int src_y, int src_w, int src_h, + float src_x, float src_y, float src_w, float src_h, int dst_x, int dst_y, int dst_w, int dst_h, struct pipe_resource **textures) { diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h index 0454a6513d..fb09fabe15 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.h +++ b/src/gallium/state_trackers/xorg/xorg_renderer.h @@ -54,7 +54,7 @@ void renderer_set_constants(struct xorg_renderer *r, void renderer_draw_yuv(struct xorg_renderer *r, - int src_x, int src_y, int src_w, int src_h, + float src_x, float src_y, float src_w, float src_h, int dst_x, int dst_y, int dst_w, int dst_h, struct pipe_resource **textures); diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h index 65fbc3234b..25da9b1a3b 100644 --- a/src/gallium/state_trackers/xorg/xorg_tracker.h +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -67,12 +67,22 @@ typedef struct #define XORG_NR_FENCES 3 +enum xorg_throttling_reason { + THROTTLE_RENDER, + THROTTLE_SWAP +}; + typedef struct _CustomizerRec { + Bool dirty_throttling; + Bool swap_throttling; Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd); Bool (*winsys_screen_close)(struct _CustomizerRec *cust); Bool (*winsys_enter_vt)(struct _CustomizerRec *cust); Bool (*winsys_leave_vt)(struct _CustomizerRec *cust); + void (*winsys_context_throttle)(struct _CustomizerRec *cust, + struct pipe_context *pipe, + enum xorg_throttling_reason reason); } CustomizerRec, *CustomizerPtr; typedef struct _modesettingRec @@ -91,6 +101,8 @@ typedef struct _modesettingRec Bool noAccel; Bool SWCursor; CursorPtr cursor; + Bool swapThrottling; + Bool dirtyThrottling; CloseScreenProcPtr CloseScreen; /* Broken-out options. */ diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index a221594454..f98bd93901 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -413,7 +413,7 @@ setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv) static void draw_yuv(struct xorg_xv_port_priv *port, - int src_x, int src_y, int src_w, int src_h, + float src_x, float src_y, float src_w, float src_h, int dst_x, int dst_y, int dst_w, int dst_h) { struct pipe_resource **textures = port->yuv[port->current_set]; @@ -562,10 +562,10 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, int box_y2 = pbox->y2; float diff_x = (float)src_w / (float)dst_w; float diff_y = (float)src_h / (float)dst_h; - int offset_x = box_x1 - dstX + pPixmap->screen_x; - int offset_y = box_y1 - dstY + pPixmap->screen_y; - int offset_w; - int offset_h; + float offset_x = box_x1 - dstX + pPixmap->screen_x; + float offset_y = box_y1 - dstY + pPixmap->screen_y; + float offset_w; + float offset_h; x = box_x1; y = box_y1; @@ -576,8 +576,8 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, offset_h = dst_h - h; draw_yuv(pPriv, - src_x + offset_x*diff_x, src_y + offset_y*diff_y, - src_w - offset_w*diff_x, src_h - offset_h*diff_y, + (float) src_x + offset_x*diff_x, (float) src_y + offset_y*diff_y, + (float) src_w - offset_w*diff_x, (float) src_h - offset_h*diff_y, x, y, w, h); pbox++; |