diff options
author | David Reveman <davidr@novell.com> | 2005-09-14 15:57:16 +0000 |
---|---|---|
committer | David Reveman <davidr@novell.com> | 2005-09-14 15:57:16 +0000 |
commit | 5c13cb3ce423a6085da906e6356e312eeebb47a1 (patch) | |
tree | ffbd70eda23e7bb6dd8143c6f17f6b3dd0a4c6e6 /src | |
parent | e5a75e4b8433403e6ad5aab5c3a67df2f2b8cc98 (diff) |
Merge new code
Diffstat (limited to 'src')
49 files changed, 11383 insertions, 9741 deletions
diff --git a/src/agl/glitz-agl.h b/src/agl/glitz-agl.h index 7bc6031..afbdf41 100644 --- a/src/agl/glitz-agl.h +++ b/src/agl/glitz-agl.h @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -42,28 +42,28 @@ glitz_agl_init (void); void glitz_agl_fini (void); - - + + /* glitz_agl_format.c */ glitz_drawable_format_t * glitz_agl_find_drawable_format (unsigned long mask, - const glitz_drawable_format_t *templ, - int count); - + const glitz_drawable_format_t *templ, + int count); + /* glitz_agl_drawable.c */ glitz_drawable_t * glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format, - WindowRef window, - unsigned int width, - unsigned int height); + WindowRef window, + unsigned int width, + unsigned int height); glitz_drawable_t * glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format, - unsigned int width, - unsigned int height); + unsigned int width, + unsigned int height); #if defined(__cplusplus) || defined(c_plusplus) diff --git a/src/agl/glitz_agl_context.c b/src/agl/glitz_agl_context.c index f917dca..f6491d6 100644 --- a/src/agl/glitz_agl_context.c +++ b/src/agl/glitz_agl_context.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -34,439 +34,479 @@ extern glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address; static CFBundleRef _glitz_agl_get_bundle (const char *name) { - CFBundleRef bundle = 0; - FSRefParam ref_param; - unsigned char framework_name[256]; - - framework_name[0] = strlen (name); - strcpy (&framework_name[1], name); - - memset (&ref_param, 0, sizeof (ref_param)); - - if (FindFolder (kSystemDomain, - kFrameworksFolderType, - kDontCreateFolder, - &ref_param.ioVRefNum, - &ref_param.ioDirID) == noErr) { - FSRef ref; - - memset (&ref, 0, sizeof (ref)); - - ref_param.ioNamePtr = framework_name; - ref_param.newRef = &ref; - - if (PBMakeFSRefSync (&ref_param) == noErr) { - CFURLRef url; - - url = CFURLCreateFromFSRef (kCFAllocatorDefault, &ref); - if (url) { - bundle = CFBundleCreate (kCFAllocatorDefault, url); - CFRelease (url); - - if (!CFBundleLoadExecutable (bundle)) { - CFRelease (bundle); - return (CFBundleRef) 0; - } - } + CFBundleRef bundle = 0; + FSRefParam ref_param; + unsigned char framework_name[256]; + + framework_name[0] = strlen (name); + strcpy (&framework_name[1], name); + + memset (&ref_param, 0, sizeof (ref_param)); + + if (FindFolder (kSystemDomain, + kFrameworksFolderType, + kDontCreateFolder, + &ref_param.ioVRefNum, + &ref_param.ioDirID) == noErr) { + FSRef ref; + + memset (&ref, 0, sizeof (ref)); + + ref_param.ioNamePtr = framework_name; + ref_param.newRef = &ref; + + if (PBMakeFSRefSync (&ref_param) == noErr) { + CFURLRef url; + + url = CFURLCreateFromFSRef (kCFAllocatorDefault, &ref); + if (url) { + bundle = CFBundleCreate (kCFAllocatorDefault, url); + CFRelease (url); + + if (!CFBundleLoadExecutable (bundle)) { + CFRelease (bundle); + return (CFBundleRef) 0; + } + } + } } - } - - return bundle; + + return bundle; } static void _glitz_agl_release_bundle (CFBundleRef bundle) { - if (bundle) { - CFBundleUnloadExecutable (bundle); - CFRelease (bundle); - } + if (bundle) { + CFBundleUnloadExecutable (bundle); + CFRelease (bundle); + } } +static void +_glitz_agl_notify_dummy (void *abstract_drawable, + glitz_surface_t *surface) {} + static glitz_function_pointer_t _glitz_agl_get_proc_address (const char *name, void *closure) { - glitz_function_pointer_t address = NULL; - CFBundleRef bundle = (CFBundleRef) closure; - CFStringRef str; - - if (bundle) { - str = CFStringCreateWithCString (kCFAllocatorDefault, name, - kCFStringEncodingMacRoman); - - address = CFBundleGetFunctionPointerForName (bundle, str); - - CFRelease (str); - } - - return address; + glitz_function_pointer_t address = NULL; + CFBundleRef bundle = (CFBundleRef) closure; + CFStringRef str; + + if (bundle) { + str = CFStringCreateWithCString (kCFAllocatorDefault, name, + kCFStringEncodingMacRoman); + + address = CFBundleGetFunctionPointerForName (bundle, str); + + CFRelease (str); + } + + return address; } static glitz_context_t * _glitz_agl_create_context (void *abstract_drawable, - glitz_drawable_format_t *format) + glitz_drawable_format_t *format) { - glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; - glitz_agl_thread_info_t *thread_info = drawable->thread_info; - glitz_agl_context_t *context; - - context = malloc (sizeof (glitz_agl_context_t)); - if (!context) - return NULL; + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) + abstract_drawable; + glitz_agl_thread_info_t *thread_info = drawable->thread_info; + glitz_agl_context_t *context; + + context = malloc (sizeof (glitz_agl_context_t)); + if (!context) + return NULL; - context->context = - aglCreateContext (thread_info->pixel_formats[format->id], - thread_info->root_context); - - _glitz_context_init (&context->base, &drawable->base); + context->context = + aglCreateContext (thread_info->pixel_formats[format->id], + thread_info->root_context); - context->pbuffer = 0; + _glitz_context_init (&context->base, &drawable->base); - return (glitz_context_t *) context; + context->pbuffer = 0; + + return (glitz_context_t *) context; } static void _glitz_agl_context_destroy (void *abstract_context) { - glitz_agl_context_t *context = (glitz_agl_context_t *) abstract_context; - glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) - context->base.drawable; + glitz_agl_context_t *context = (glitz_agl_context_t *) abstract_context; + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) + context->base.drawable; + + if (drawable->thread_info->cctx == &context->base) + { + aglSetCurrentContext (NULL); - if (drawable->thread_info->cctx == &context->base) - { - aglSetCurrentContext (NULL); + drawable->thread_info->cctx = NULL; + } - drawable->thread_info->cctx = NULL; - } + aglDestroyContext (context->context); - aglDestroyContext (context->context); + _glitz_context_fini (&context->base); - _glitz_context_fini (&context->base); - - free (context); + free (context); } static void _glitz_agl_copy_context (void *abstract_src, - void *abstract_dst, - unsigned long mask) + void *abstract_dst, + unsigned long mask) { - glitz_agl_context_t *src = (glitz_agl_context_t *) abstract_src; - glitz_agl_context_t *dst = (glitz_agl_context_t *) abstract_dst; + glitz_agl_context_t *src = (glitz_agl_context_t *) abstract_src; + glitz_agl_context_t *dst = (glitz_agl_context_t *) abstract_dst; - aglCopyContext (src->context, dst->context, mask); + aglCopyContext (src->context, dst->context, mask); } static void -_glitz_agl_make_current (void *abstract_context, - void *abstract_drawable) +_glitz_agl_make_current (void *abstract_drawable, + void *abstract_context) { - glitz_agl_context_t *context = (glitz_agl_context_t *) abstract_context; - glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; - int update = 0; - - if (aglGetCurrentContext () != context->context) - { - update = 1; - } - else - { - if (drawable->pbuffer) - { - AGLPbuffer pbuffer; - GLuint unused; - - aglGetPBuffer (context->context, &pbuffer, - &unused, &unused, &unused); - - if (pbuffer != drawable->pbuffer) - update = 1; - - } - else if (drawable->drawable) - { - if (aglGetDrawable (context->context) != drawable->drawable) - update = 1; - } - } - - if (update) - { - if (drawable->thread_info->cctx) - { - glitz_context_t *ctx = drawable->thread_info->cctx; - - if (ctx->lose_current) - ctx->lose_current (ctx->closure); - } - - if (drawable->pbuffer) { - aglSetPBuffer (context->context, drawable->pbuffer, 0, 0, - aglGetVirtualScreen (context->context)); - context->pbuffer = 1; - } - else - { - if (context->pbuffer) { - aglSetDrawable (context->context, NULL); - context->pbuffer = 0; - } - aglSetDrawable (context->context, drawable->drawable); - } - - aglSetCurrentContext (context->context); - } - - drawable->thread_info->cctx = &context->base; + glitz_agl_context_t *context = (glitz_agl_context_t *) abstract_context; + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) + abstract_drawable; + int update = 0; + + if (drawable->base.width != drawable->width || + drawable->base.height != drawable->height) + _glitz_agl_drawable_update_size (drawable, + drawable->base.width, + drawable->base.height); + + if (aglGetCurrentContext () != context->context) + { + update = 1; + } + else + { + if (drawable->pbuffer) + { + AGLPbuffer pbuffer; + GLuint unused; + + aglGetPBuffer (context->context, &pbuffer, + &unused, &unused, &unused); + + if (pbuffer != drawable->pbuffer) + update = 1; + + } + else if (drawable->drawable) + { + if (aglGetDrawable (context->context) != drawable->drawable) + update = 1; + } + } + + if (update) + { + if (drawable->thread_info->cctx) + { + glitz_context_t *ctx = drawable->thread_info->cctx; + + if (ctx->lose_current) + ctx->lose_current (ctx->closure); + } + + if (drawable->pbuffer) { + aglSetPBuffer (context->context, drawable->pbuffer, 0, 0, + aglGetVirtualScreen (context->context)); + context->pbuffer = 1; + } + else + { + if (context->pbuffer) { + aglSetDrawable (context->context, NULL); + context->pbuffer = 0; + } + aglSetDrawable (context->context, drawable->drawable); + } + + aglSetCurrentContext (context->context); + } + + drawable->thread_info->cctx = &context->base; } static glitz_function_pointer_t _glitz_agl_context_get_proc_address (void *abstract_context, - const char *name) + const char *name) { - glitz_agl_context_t *context = (glitz_agl_context_t *) abstract_context; - glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) - context->base.drawable; - glitz_function_pointer_t func; - CFBundleRef bundle; + glitz_agl_context_t *context = (glitz_agl_context_t *) abstract_context; + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) + context->base.drawable; + glitz_function_pointer_t func; + CFBundleRef bundle; - _glitz_agl_make_current (context, drawable); + _glitz_agl_make_current (drawable, context, NULL); - bundle = _glitz_agl_get_bundle ("OpenGL.framework"); + bundle = _glitz_agl_get_bundle ("OpenGL.framework"); - func = _glitz_agl_get_proc_address (name, (void *) bundle); + func = _glitz_agl_get_proc_address (name, (void *) bundle); - _glitz_agl_release_bundle (bundle); + _glitz_agl_release_bundle (bundle); - return func; + return func; } glitz_agl_context_t * glitz_agl_context_get (glitz_agl_thread_info_t *thread_info, - glitz_drawable_format_t *format) + glitz_drawable_format_t *format) { - glitz_agl_context_t *context; - glitz_agl_context_t **contexts = thread_info->contexts; - int index, n_contexts = thread_info->n_contexts; - - for (; n_contexts; n_contexts--, contexts++) - if ((*contexts)->id == format->id) - return *contexts; - - index = thread_info->n_contexts++; - - thread_info->contexts = - realloc (thread_info->contexts, - sizeof (glitz_agl_context_t *) * thread_info->n_contexts); - if (!thread_info->contexts) - return NULL; + glitz_agl_context_t *context; + glitz_agl_context_t **contexts = thread_info->contexts; + int index, n_contexts = thread_info->n_contexts; + + for (; n_contexts; n_contexts--, contexts++) + if ((*contexts)->id == format->id) + return *contexts; + + index = thread_info->n_contexts++; + + thread_info->contexts = + realloc (thread_info->contexts, + sizeof (glitz_agl_context_t *) * thread_info->n_contexts); + if (!thread_info->contexts) + return NULL; + + context = malloc (sizeof (glitz_agl_context_t)); + if (!context) + return NULL; + + thread_info->contexts[index] = context; + + context->context = + aglCreateContext (thread_info->pixel_formats[format->id], + thread_info->root_context); + if (!context->context) { + free (context); + return NULL; + } - context = malloc (sizeof (glitz_agl_context_t)); - if (!context) - return NULL; - - thread_info->contexts[index] = context; + context->id = format->id; + context->pbuffer = 0; + + if (!thread_info->root_context) + thread_info->root_context = context->context; + + context->backend.gl = &_glitz_agl_gl_proc_address; + + context->backend.create_pbuffer = glitz_agl_create_pbuffer; + context->backend.destroy = glitz_agl_destroy; + context->backend.push_current = glitz_agl_push_current; + context->backend.pop_current = glitz_agl_pop_current; + context->backend.attach_notify = _glitz_agl_notify_dummy; + context->backend.detach_notify = _glitz_agl_notify_dummy; + context->backend.swap_buffers = glitz_agl_swap_buffers; + + context->backend.create_context = _glitz_agl_create_context; + context->backend.destroy_context = _glitz_agl_context_destroy; + context->backend.copy_context = _glitz_agl_copy_context; + context->backend.make_current = _glitz_agl_make_current; + context->backend.get_proc_address = _glitz_agl_context_get_proc_address; + + context->backend.drawable_formats = NULL; + context->backend.n_drawable_formats = 0; + + if (screen_info->n_formats) + { + int size; + + size = sizeof (glitz_int_drawable_format_t) * screen_info->n_formats; + context->backend.drawable_formats = malloc (size); + if (context->backend.drawable_formats) + { + memcpy (context->backend.drawable_formats, screen_info->formats, + size); + context->backend.n_drawable_formats = screen_info->n_formats; + } + } - context->context = - aglCreateContext (thread_info->pixel_formats[format->id], - thread_info->root_context); - if (!context->context) { - free (context); - return NULL; - } - - context->id = format->id; - context->pbuffer = 0; - - if (!thread_info->root_context) - thread_info->root_context = context->context; - - memcpy (&context->backend.gl, - &_glitz_agl_gl_proc_address, - sizeof (glitz_gl_proc_address_list_t)); - - context->backend.create_pbuffer = glitz_agl_create_pbuffer; - context->backend.destroy = glitz_agl_destroy; - context->backend.push_current = glitz_agl_push_current; - context->backend.pop_current = glitz_agl_pop_current; - context->backend.swap_buffers = glitz_agl_swap_buffers; - - context->backend.create_context = _glitz_agl_create_context; - context->backend.destroy_context = _glitz_agl_context_destroy; - context->backend.copy_context = _glitz_agl_copy_context; - context->backend.make_current = _glitz_agl_make_current; - context->backend.get_proc_address = _glitz_agl_context_get_proc_address; - - context->backend.drawable_formats = thread_info->formats; - context->backend.n_drawable_formats = thread_info->n_formats; - - context->backend.texture_formats = NULL; - context->backend.formats = NULL; - context->backend.n_formats = 0; - - context->backend.program_map = &thread_info->program_map; - context->backend.feature_mask = 0; - - context->initialized = 0; - - return context; + context->backend.texture_formats = NULL; + context->backend.formats = NULL; + context->backend.n_formats = 0; + + context->backend.program_map = &thread_info->program_map; + context->backend.feature_mask = 0; + + context->initialized = 0; + + return context; } void glitz_agl_context_destroy (glitz_agl_thread_info_t *thread_info, - glitz_agl_context_t *context) + glitz_agl_context_t *context) { - if (context->backend.formats) - free (context->backend.formats); - - if (context->backend.texture_formats) - free (context->backend.texture_formats); - - aglDestroyContext (context->context); - - free (context); + if (context->backend.drawable_formats) + free (context->backend.drawable_formats); + + if (context->backend.formats) + free (context->backend.formats); + + if (context->backend.texture_formats) + free (context->backend.texture_formats); + + aglDestroyContext (context->context); + + free (context); } static void _glitz_agl_context_initialize (glitz_agl_thread_info_t *thread_info, - glitz_agl_context_t *context) + glitz_agl_context_t *context) { - CFBundleRef bundle; - - bundle = _glitz_agl_get_bundle ("OpenGL.framework"); + CFBundleRef bundle; + + bundle = _glitz_agl_get_bundle ("OpenGL.framework"); - glitz_backend_init (&context->backend, - _glitz_agl_get_proc_address, - (void *) bundle); + glitz_backend_init (&context->backend, + _glitz_agl_get_proc_address, + (void *) bundle); - _glitz_agl_release_bundle (bundle); + _glitz_agl_release_bundle (bundle); - context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS, - context->max_viewport_dims); + glitz_initiate_state (&_glitz_agl_gl_proc_address); - glitz_initiate_state (&_glitz_agl_gl_proc_address); - - context->initialized = 1; + context->initialized = 1; } static void _glitz_agl_context_make_current (glitz_agl_drawable_t *drawable, - glitz_bool_t finish) + glitz_bool_t finish) { - if (finish) - glFinish (); - - if (drawable->thread_info->cctx) - { - glitz_context_t *ctx = drawable->thread_info->cctx; - - if (ctx->lose_current) - ctx->lose_current (ctx->closure); - - drawable->thread_info->cctx = NULL; - } - - if (drawable->pbuffer) { - aglSetPBuffer (drawable->context->context, drawable->pbuffer, 0, 0, - aglGetVirtualScreen (drawable->context->context)); - drawable->context->pbuffer = 1; - } else { - if (drawable->context->pbuffer) { - aglSetDrawable (drawable->context->context, NULL); - drawable->context->pbuffer = 0; + if (finish) + glFinish (); + + if (drawable->thread_info->cctx) + { + glitz_context_t *ctx = drawable->thread_info->cctx; + + if (ctx->lose_current) + ctx->lose_current (ctx->closure); + + drawable->thread_info->cctx = NULL; + } + + if (drawable->pbuffer) { + aglSetPBuffer (drawable->context->context, drawable->pbuffer, 0, 0, + aglGetVirtualScreen (drawable->context->context)); + drawable->context->pbuffer = 1; + } else { + if (drawable->context->pbuffer) { + aglSetDrawable (drawable->context->context, NULL); + drawable->context->pbuffer = 0; + } + + aglSetDrawable (drawable->context->context, drawable->drawable); } - - aglSetDrawable (drawable->context->context, drawable->drawable); - } - aglSetCurrentContext (drawable->context->context); + aglSetCurrentContext (drawable->context->context); + + drawable->base.update_all = 1; - drawable->base.update_all = 1; - - if (!drawable->context->initialized) - _glitz_agl_context_initialize (drawable->thread_info, drawable->context); + if (!drawable->context->initialized) + _glitz_agl_context_initialize (drawable->thread_info, + drawable->context); } static void _glitz_agl_context_update (glitz_agl_drawable_t *drawable, - glitz_constraint_t constraint) + glitz_constraint_t constraint) { - AGLContext context; - - switch (constraint) { - case GLITZ_NONE: - break; - case GLITZ_ANY_CONTEXT_CURRENT: - context = aglGetCurrentContext (); - if (context == (AGLContext) 0) - _glitz_agl_context_make_current (drawable, 0); - break; - case GLITZ_CONTEXT_CURRENT: - context = aglGetCurrentContext (); - if (context != drawable->context->context) - _glitz_agl_context_make_current (drawable, (context)? 1: 0); - break; - case GLITZ_DRAWABLE_CURRENT: - context = aglGetCurrentContext (); - if (context != drawable->context->context) { - _glitz_agl_context_make_current (drawable, (context)? 1: 0); - } else { - if (drawable->pbuffer) { - AGLPbuffer pbuffer; - GLuint unused; - - aglGetPBuffer (drawable->context->context, &pbuffer, - &unused, &unused, &unused); - - if (pbuffer != drawable->pbuffer) - _glitz_agl_context_make_current (drawable, (context)? 1: 0); - - } else if (drawable->drawable) { - if (aglGetDrawable (drawable->context->context) != drawable->drawable) - _glitz_agl_context_make_current (drawable, (context)? 1: 0); - } + AGLContext context; + + switch (constraint) { + case GLITZ_NONE: + break; + case GLITZ_ANY_CONTEXT_CURRENT: + context = aglGetCurrentContext (); + if (context == (AGLContext) 0) + _glitz_agl_context_make_current (drawable, 0); + break; + case GLITZ_CONTEXT_CURRENT: + context = aglGetCurrentContext (); + if (context != drawable->context->context) + _glitz_agl_context_make_current (drawable, (context)? 1: 0); + break; + case GLITZ_DRAWABLE_CURRENT: + if (drawable->base.width != drawable->width || + drawable->base.height != drawable->height) + _glitz_agl_drawable_update_size (drawable, + drawable->base.width, + drawable->base.height); + + context = aglGetCurrentContext (); + if (context != drawable->context->context) { + _glitz_agl_context_make_current (drawable, (context)? 1: 0); + } else { + if (drawable->pbuffer) { + AGLPbuffer pbuffer; + GLuint unused; + + aglGetPBuffer (drawable->context->context, &pbuffer, + &unused, &unused, &unused); + + if (pbuffer != drawable->pbuffer) + _glitz_agl_context_make_current (drawable, + (context)? 1: 0); + + } else if (drawable->drawable) { + if (aglGetDrawable (drawable->context->context) != + drawable->drawable) + _glitz_agl_context_make_current (drawable, + (context)? 1: 0); + } + } + break; } - break; - } } -void +glitz_bool_t glitz_agl_push_current (void *abstract_drawable, - glitz_surface_t *surface, - glitz_constraint_t constraint) + glitz_surface_t *surface, + glitz_constraint_t constraint) { - glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; - glitz_agl_context_info_t *context_info; - int index; - - index = drawable->thread_info->context_stack_size++; - - context_info = &drawable->thread_info->context_stack[index]; - context_info->drawable = drawable; - context_info->surface = surface; - context_info->constraint = constraint; - - _glitz_agl_context_update (context_info->drawable, constraint); + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) + abstract_drawable; + glitz_agl_context_info_t *context_info; + int index; + + index = drawable->thread_info->context_stack_size++; + + context_info = &drawable->thread_info->context_stack[index]; + context_info->drawable = drawable; + context_info->surface = surface; + context_info->constraint = constraint; + + _glitz_agl_context_update (context_info->drawable, constraint); + + return 1; } glitz_surface_t * glitz_agl_pop_current (void *abstract_drawable) { - glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; - glitz_agl_context_info_t *context_info = NULL; - int index; - - drawable->thread_info->context_stack_size--; - index = drawable->thread_info->context_stack_size - 1; - - context_info = &drawable->thread_info->context_stack[index]; - - if (context_info->drawable) - _glitz_agl_context_update (context_info->drawable, - context_info->constraint); - - if (context_info->constraint == GLITZ_DRAWABLE_CURRENT) - return context_info->surface; - - return NULL; + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) + abstract_drawable; + glitz_agl_context_info_t *context_info = NULL; + int index; + + drawable->thread_info->context_stack_size--; + index = drawable->thread_info->context_stack_size - 1; + + context_info = &drawable->thread_info->context_stack[index]; + + if (context_info->drawable) + _glitz_agl_context_update (context_info->drawable, + context_info->constraint); + + if (context_info->constraint == GLITZ_DRAWABLE_CURRENT) + return context_info->surface; + + return NULL; } diff --git a/src/agl/glitz_agl_drawable.c b/src/agl/glitz_agl_drawable.c index ada714a..d2fe826 100644 --- a/src/agl/glitz_agl_drawable.c +++ b/src/agl/glitz_agl_drawable.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,189 +31,222 @@ static glitz_agl_drawable_t * _glitz_agl_create_drawable (glitz_agl_thread_info_t *thread_info, - glitz_agl_context_t *context, - glitz_drawable_format_t *format, - AGLDrawable agl_drawable, - AGLPbuffer agl_pbuffer, - unsigned int width, - unsigned int height) + glitz_agl_context_t *context, + glitz_drawable_format_t *format, + AGLDrawable agl_drawable, + AGLPbuffer agl_pbuffer, + unsigned int width, + unsigned int height) { - glitz_agl_drawable_t *drawable; - - if (width <= 0 || height <= 0) - return NULL; - - drawable = (glitz_agl_drawable_t *) malloc (sizeof (glitz_agl_drawable_t)); - if (drawable == NULL) - return NULL; - - drawable->base.ref_count = 1; - drawable->thread_info = thread_info; - drawable->context = context; - drawable->drawable = agl_drawable; - drawable->pbuffer = agl_pbuffer; - drawable->base.format = format; - drawable->base.backend = &context->backend; - - glitz_drawable_update_size (&drawable->base, width, height); - - if (!context->initialized) { - glitz_agl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT); - glitz_agl_pop_current (drawable); - } - - if (width > context->max_viewport_dims[0] || - height > context->max_viewport_dims[1]) { - free (drawable); - return NULL; - } + glitz_agl_drawable_t *drawable; + + drawable = (glitz_agl_drawable_t *) malloc (sizeof (glitz_agl_drawable_t)); + if (drawable == NULL) + return NULL; + + drawable->thread_info = thread_info; + drawable->context = context; + drawable->drawable = agl_drawable; + drawable->pbuffer = agl_pbuffer; + drawable->width = width; + drawable->height = height; + + _glitz_drawable_init (&drawable->base, + format, + &context->backend, + width, height); + + if (!context->initialized) { + glitz_agl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT); + glitz_agl_pop_current (drawable); + } + + if (width > context->backend.max_viewport_dims[0] || + height > context->backend.max_viewport_dims[1]) { + free (drawable); + return NULL; + } + + thread_info->drawables++; + + return drawable; +} + +glitz_bool_t +_glitz_agl_drawable_update_size (glitz_agl_drawable_t *drawable, + int width, + int height) +{ + if (drawable->pbuffer) + { + glitz_agl_pbuffer_destroy (drawable->thread_info, drawable->pbuffer); + drawable->pbuffer = + glitz_agl_pbuffer_create (drawable->thread_info, + drawable->context->fbconfig, + (int) width, (int) height); + if (!drawable->pbuffer) + return 0; + } - thread_info->drawables++; - - return drawable; + drawable->width = width; + drawable->height = height; + + return 1; } static glitz_drawable_t * _glitz_agl_create_pbuffer_drawable (glitz_agl_thread_info_t *thread_info, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { - glitz_agl_drawable_t *drawable; - glitz_agl_context_t *context; - AGLPbuffer pbuffer; - - if (!format->types.pbuffer) - return NULL; - - context = glitz_agl_context_get (thread_info, format); - if (!context) - return NULL; - - pbuffer = glitz_agl_pbuffer_create (thread_info, (int) width, (int) height); - if (!pbuffer) - return NULL; - - drawable = _glitz_agl_create_drawable (thread_info, context, format, - (AGLDrawable) 0, pbuffer, - width, height); - if (!drawable) { - glitz_agl_pbuffer_destroy (pbuffer); - return NULL; - } - - return &drawable->base; + glitz_agl_drawable_t *drawable; + glitz_agl_context_t *context; + AGLPbuffer pbuffer; + + if (!format->types.pbuffer) + return NULL; + + context = glitz_agl_context_get (thread_info, format); + if (!context) + return NULL; + + pbuffer = glitz_agl_pbuffer_create (thread_info, + (int) width, (int) height); + if (!pbuffer) + return NULL; + + drawable = _glitz_agl_create_drawable (thread_info, context, format, + (AGLDrawable) 0, pbuffer, + width, height); + if (!drawable) { + glitz_agl_pbuffer_destroy (pbuffer); + return NULL; + } + + return &drawable->base; } glitz_drawable_t * glitz_agl_create_pbuffer (void *abstract_templ, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { - glitz_agl_drawable_t *templ = (glitz_agl_drawable_t *) abstract_templ; + glitz_agl_drawable_t *templ = (glitz_agl_drawable_t *) abstract_templ; - return _glitz_agl_create_pbuffer_drawable (templ->thread_info, format, - width, height); + return _glitz_agl_create_pbuffer_drawable (templ->thread_info, format, + width, height); } glitz_drawable_t * glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format, - WindowRef window, - unsigned int width, - unsigned int height) + WindowRef window, + unsigned int width, + unsigned int height) { - glitz_agl_drawable_t *drawable; - glitz_agl_thread_info_t *thread_info; - glitz_agl_context_t *context; - AGLDrawable agl_drawable; - - agl_drawable = (AGLDrawable) GetWindowPort (window); - if (!agl_drawable) - return NULL; - - thread_info = glitz_agl_thread_info_get (); - if (!thread_info) - return NULL; - - context = glitz_agl_context_get (thread_info, format); - if (!context) - return NULL; - - drawable = _glitz_agl_create_drawable (thread_info, context, format, - agl_drawable, (AGLPbuffer) 0, - width, height); - if (!drawable) - return NULL; - - return &drawable->base; + glitz_agl_drawable_t *drawable; + glitz_agl_thread_info_t *thread_info; + glitz_agl_context_t *context; + AGLDrawable agl_drawable; + + agl_drawable = (AGLDrawable) GetWindowPort (window); + if (!agl_drawable) + return NULL; + + thread_info = glitz_agl_thread_info_get (); + if (!thread_info) + return NULL; + + if (format->id >= screen_info->n_formats) + return NULL; + + context = glitz_agl_context_get (thread_info, format); + if (!context) + return NULL; + + drawable = _glitz_agl_create_drawable (thread_info, context, format, + agl_drawable, (AGLPbuffer) 0, + width, height); + if (!drawable) + return NULL; + + return &drawable->base; } slim_hidden_def(glitz_agl_create_drawable_for_window); glitz_drawable_t * glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + unsigned int width, + unsigned int height) { - glitz_agl_thread_info_t *thread_info; + glitz_agl_thread_info_t *thread_info; - thread_info = glitz_agl_thread_info_get (); - if (!thread_info) - return NULL; + thread_info = glitz_agl_thread_info_get (); + if (!thread_info) + return NULL; - return _glitz_agl_create_pbuffer_drawable (thread_info, format, - width, height); + if (format->id >= screen_info->n_formats) + return NULL; + + return _glitz_agl_create_pbuffer_drawable (thread_info, format, + width, height); } slim_hidden_def(glitz_agl_create_pbuffer_drawable); void glitz_agl_destroy (void *abstract_drawable) { - glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; - - drawable->thread_info->drawables--; - if (drawable->thread_info->drawables == 0) { - /* - * Last drawable? We have to destroy all fragment programs as this may - * be our last chance to have a context current. - */ - glitz_agl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT); - glitz_program_map_fini (&drawable->base.backend->gl, - &drawable->thread_info->program_map); - glitz_agl_pop_current (abstract_drawable); - } - - if (drawable->drawable || drawable->pbuffer) { - AGLContext context = aglGetCurrentContext (); - - if (context == drawable->context->context) { - if (drawable->pbuffer) { - AGLPbuffer pbuffer; - GLuint unused; - - aglGetPBuffer (context, &pbuffer, &unused, &unused, &unused); - - if (pbuffer == drawable->pbuffer) - aglSetCurrentContext (NULL); - } else { - if (aglGetDrawable (context) == drawable->drawable) - aglSetCurrentContext (NULL); - } + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) + abstract_drawable; + + drawable->thread_info->drawables--; + if (drawable->thread_info->drawables == 0) { + /* + * Last drawable? We have to destroy all fragment programs as this may + * be our last chance to have a context current. + */ + glitz_agl_push_current (abstract_drawable, NULL, + GLITZ_CONTEXT_CURRENT); + glitz_program_map_fini (&drawable->base.backend->gl, + &drawable->thread_info->program_map); + glitz_agl_pop_current (abstract_drawable); } - - if (drawable->pbuffer) - glitz_agl_pbuffer_destroy (drawable->pbuffer); - } - - free (drawable); + + if (drawable->drawable || drawable->pbuffer) { + AGLContext context = aglGetCurrentContext (); + + if (context == drawable->context->context) { + if (drawable->pbuffer) { + AGLPbuffer pbuffer; + GLuint unused; + + aglGetPBuffer (context, &pbuffer, &unused, &unused, &unused); + + if (pbuffer == drawable->pbuffer) + aglSetCurrentContext (NULL); + } else { + if (aglGetDrawable (context) == drawable->drawable) + aglSetCurrentContext (NULL); + } + } + + if (drawable->pbuffer) + glitz_agl_pbuffer_destroy (drawable->pbuffer); + } + + free (drawable); } -void +glitz_bool_t glitz_agl_swap_buffers (void *abstract_drawable) { - glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) + abstract_drawable; + + glitz_agl_push_current (abstract_drawable, NULL, GLITZ_DRAWABLE_CURRENT); + aglSwapBuffers (drawable->context->context); + glitz_agl_pop_current (abstract_drawable); - glitz_agl_push_current (abstract_drawable, NULL, GLITZ_DRAWABLE_CURRENT); - aglSwapBuffers (drawable->context->context); - glitz_agl_pop_current (abstract_drawable); + return 1; } diff --git a/src/agl/glitz_agl_extension.c b/src/agl/glitz_agl_extension.c index c564be8..0456ee1 100644 --- a/src/agl/glitz_agl_extension.c +++ b/src/agl/glitz_agl_extension.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -30,63 +30,65 @@ #include "glitz_aglint.h" static glitz_extension_map agl_extensions[] = { - { 0.0, "GL_APPLE_pixel_buffer", GLITZ_AGL_FEATURE_PBUFFER_MASK }, - { 0.0, "GL_ARB_multisample", GLITZ_AGL_FEATURE_MULTISAMPLE_MASK }, - { 0.0, "GL_ARB_texture_rectangle", - GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_EXT_texture_rectangle", - GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_NV_texture_rectangle", GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, NULL, 0 } + { 0.0, "GL_APPLE_pixel_buffer", GLITZ_AGL_FEATURE_PBUFFER_MASK }, + { 0.0, "GL_ARB_multisample", GLITZ_AGL_FEATURE_MULTISAMPLE_MASK }, + { 0.0, "GL_ARB_texture_rectangle", + GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_EXT_texture_rectangle", + GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_NV_texture_rectangle", + GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, NULL, 0 } }; glitz_status_t glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info) { - GLint attrib[] = { - AGL_RGBA, - AGL_NO_RECOVERY, - AGL_NONE - }; - AGLPixelFormat pf; - AGLContext context; - - thread_info->agl_feature_mask = 0; - - pf = aglChoosePixelFormat (NULL, 0, attrib); - context = aglCreateContext (pf, NULL); - - if (context) { - const char *gl_extensions_string; - - aglSetCurrentContext (context); - - gl_extensions_string = (const char *) glGetString (GL_EXTENSIONS); - - thread_info->agl_feature_mask = - glitz_extensions_query (0.0, - gl_extensions_string, - agl_extensions); - - if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK) { - const char *vendor; - - vendor = glGetString (GL_VENDOR); - - if (vendor) { - - /* NVIDIA's driver seem to support multisample with pbuffers */ - if (!strncmp ("NVIDIA", vendor, 6)) - thread_info->agl_feature_mask |= - GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK; - } - } + GLint attrib[] = { + AGL_RGBA, + AGL_NO_RECOVERY, + AGL_NONE + }; + AGLPixelFormat pf; + AGLContext context; + + thread_info->agl_feature_mask = 0; + + pf = aglChoosePixelFormat (NULL, 0, attrib); + context = aglCreateContext (pf, NULL); + + if (context) { + const char *gl_extensions_string; + + aglSetCurrentContext (context); + + gl_extensions_string = (const char *) glGetString (GL_EXTENSIONS); - aglSetCurrentContext (NULL); - aglDestroyContext (context); - } + thread_info->agl_feature_mask = + glitz_extensions_query (0.0, + gl_extensions_string, + agl_extensions); + + if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK) + { + const char *vendor; + + vendor = glGetString (GL_VENDOR); + + if (vendor) { + + /* NVIDIA's driver seem to support multisample with pbuffers */ + if (!strncmp ("NVIDIA", vendor, 6)) + thread_info->agl_feature_mask |= + GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK; + } + } + + aglSetCurrentContext (NULL); + aglDestroyContext (context); + } - aglDestroyPixelFormat (pf); + aglDestroyPixelFormat (pf); - return GLITZ_STATUS_SUCCESS; + return GLITZ_STATUS_SUCCESS; } diff --git a/src/agl/glitz_agl_format.c b/src/agl/glitz_agl_format.c index 3a10c11..e66c8fb 100644 --- a/src/agl/glitz_agl_format.c +++ b/src/agl/glitz_agl_format.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -33,301 +33,303 @@ #include <string.h> static GLint _attribs[] = { - AGL_RGBA, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_NONE + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_NONE }; static GLint _db_attribs[] = { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_NONE + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_NONE }; static GLint _stencil_attribs[] = { - AGL_RGBA, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_DEPTH_SIZE, 8, - AGL_STENCIL_SIZE, 8, - AGL_NONE + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_DEPTH_SIZE, 8, + AGL_STENCIL_SIZE, 8, + AGL_NONE }; static GLint _db_stencil_attribs[] = { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_STENCIL_SIZE, 8, - AGL_NONE + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_NONE }; static GLint _ms2_attribs[] = { - AGL_RGBA, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_STENCIL_SIZE, 8, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 2, - AGL_NONE + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 2, + AGL_NONE }; static GLint _db_ms2_attribs[] = { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_STENCIL_SIZE, 8, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 2, - AGL_NONE + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 2, + AGL_NONE }; static GLint _ms4_attribs[] = { - AGL_RGBA, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_STENCIL_SIZE, 8, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 4, - AGL_NONE + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 4, + AGL_NONE }; static GLint _db_ms4_attribs[] = { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_STENCIL_SIZE, 8, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 4, - AGL_NONE + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 4, + AGL_NONE }; static GLint _ms6_attribs[] = { - AGL_RGBA, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_STENCIL_SIZE, 8, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 6, - AGL_NONE + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 6, + AGL_NONE }; static GLint _db_ms6_attribs[] = { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_ALPHA_SIZE, 16, - AGL_RED_SIZE, 16, - AGL_STENCIL_SIZE, 8, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 6, - AGL_NONE + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 6, + AGL_NONE }; static GLint *_attribs_list[] = { - _attribs, - _db_attribs, - _stencil_attribs, - _db_stencil_attribs, - _ms2_attribs, - _db_ms2_attribs, - _ms4_attribs, - _db_ms4_attribs, - _ms6_attribs, - _db_ms6_attribs + _attribs, + _db_attribs, + _stencil_attribs, + _db_stencil_attribs, + _ms2_attribs, + _db_ms2_attribs, + _ms4_attribs, + _db_ms4_attribs, + _ms6_attribs, + _db_ms6_attribs }; static int _glitz_agl_format_compare (const void *elem1, - const void *elem2) + const void *elem2) { - int i, score[2]; - glitz_drawable_format_t *format[2]; - - format[0] = (glitz_drawable_format_t *) elem1; - format[1] = (glitz_drawable_format_t *) elem2; - i = score[0] = score[1] = 0; - - for (; i < 2; i++) { - if (format[i]->color.red_size) { - if (format[i]->color.red_size == 8) - score[i] += 5; - score[i] += 10; - } + int i, score[2]; + glitz_drawable_format_t *format[2]; - if (format[i]->color.green_size) { - if (format[i]->color.green_size == 8) - score[i] += 5; - score[i] += 10; - } - - if (format[i]->color.alpha_size) { - if (format[i]->color.alpha_size == 8) - score[i] += 5; - score[i] += 10; + format[0] = (glitz_drawable_format_t *) elem1; + format[1] = (glitz_drawable_format_t *) elem2; + i = score[0] = score[1] = 0; + + for (; i < 2; i++) { + if (format[i]->color.red_size) { + if (format[i]->color.red_size == 8) + score[i] += 5; + score[i] += 10; + } + + if (format[i]->color.green_size) { + if (format[i]->color.green_size == 8) + score[i] += 5; + score[i] += 10; + } + + if (format[i]->color.alpha_size) { + if (format[i]->color.alpha_size == 8) + score[i] += 5; + score[i] += 10; + } + + if (format[i]->stencil_size) + score[i] += 5; + + if (format[i]->depth_size) + score[i] += 5; + + if (format[i]->doublebuffer) + score[i] += 10; + + if (format[i]->types.window) + score[i] += 10; + + if (format[i]->types.pbuffer) + score[i] += 10; + + if (format[i]->samples > 1) + score[i] -= (20 - format[i]->samples); } - if (format[i]->stencil_size) - score[i] += 5; - - if (format[i]->depth_size) - score[i] += 5; - - if (format[i]->doublebuffer) - score[i] += 10; - - if (format[i]->types.window) - score[i] += 10; - - if (format[i]->types.pbuffer) - score[i] += 10; - - if (format[i]->samples > 1) - score[i] -= (20 - format[i]->samples); - } - - return score[1] - score[0]; + return score[1] - score[0]; } static void _glitz_add_format (glitz_agl_thread_info_t *thread_info, - glitz_drawable_format_t *format, - AGLPixelFormat pixel_format) + glitz_drawable_format_t *format, + AGLPixelFormat pixel_format) { - if (!glitz_drawable_format_find (thread_info->formats, - thread_info->n_formats, - GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK, - format, 0)) { - int n = thread_info->n_formats; - - thread_info->formats = - realloc (thread_info->formats, - sizeof (glitz_drawable_format_t) * (n + 1)); - thread_info->pixel_formats = - realloc (thread_info->pixel_formats, - sizeof (AGLPixelFormat) * (n + 1)); - - if (thread_info->formats && thread_info->pixel_formats) { - thread_info->formats[n] = *format; - thread_info->formats[n].id = n; - thread_info->pixel_formats[n] = pixel_format; - thread_info->n_formats++; + if (!glitz_drawable_format_find (thread_info->formats, + thread_info->n_formats, + GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK, + format, 0)) { + int n = thread_info->n_formats; + + thread_info->formats = + realloc (thread_info->formats, + sizeof (glitz_drawable_format_t) * (n + 1)); + thread_info->pixel_formats = + realloc (thread_info->pixel_formats, + sizeof (AGLPixelFormat) * (n + 1)); + + if (thread_info->formats && thread_info->pixel_formats) { + thread_info->formats[n] = *format; + thread_info->formats[n].id = n; + thread_info->pixel_formats[n] = pixel_format; + thread_info->n_formats++; + } } - } } void glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info) { - glitz_drawable_format_t format; - AGLPixelFormat pixel_format, *new_pfs; - int n_attribs_list, i; + glitz_drawable_format_t format; + AGLPixelFormat pixel_format, *new_pfs; + int n_attribs_list, i; + + format.types.window = 1; + format.id = 0; + + n_attribs_list = sizeof (_attribs_list) / sizeof (GLint *); + + for (i = 0; i < n_attribs_list; i++) { + GLint value; + + pixel_format = aglChoosePixelFormat (NULL, 0, _attribs_list[i]); + + /* Stereo is not supported yet */ + if (!(aglDescribePixelFormat (pixel_format, AGL_STEREO, &value)) || + value) { + aglDestroyPixelFormat (pixel_format); + continue; + } + + aglDescribePixelFormat (pixel_format, AGL_DOUBLEBUFFER, &value); + format.doublebuffer = (value)? 1: 0; + + aglDescribePixelFormat (pixel_format, AGL_RED_SIZE, &value); + format.color.red_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_GREEN_SIZE, &value); + format.color.green_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_BLUE_SIZE, &value); + format.color.blue_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_ALPHA_SIZE, &value); + format.color.alpha_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_DEPTH_SIZE, &value); + format.depth_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_STENCIL_SIZE, &value); + format.stencil_size = (unsigned short) value; + + if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK) + { + aglDescribePixelFormat (pixel_format, AGL_SAMPLE_BUFFERS_ARB, + &value); + if (value) { + aglDescribePixelFormat (pixel_format, AGL_SAMPLES_ARB, &value); + format.samples = (unsigned short) (value > 1)? value: 1; + } else + format.samples = 1; + } else + format.samples = 1; + + if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_PBUFFER_MASK) { + if (format.color.red_size && format.color.green_size && + format.color.blue_size && format.color.alpha_size && + format.doublebuffer == 0 && format.stencil_size == 0 && + format.depth_size == 0) { + + if (thread_info->agl_feature_mask & + GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK) + format.types.pbuffer = 1; + else if (format.samples == 1) + format.types.pbuffer = 1; + else + format.types.pbuffer = 0; + } else + format.types.pbuffer = 0; + } else + format.types.pbuffer = 0; + + if (format.color.red_size || + format.color.green_size || + format.color.blue_size || + format.color.alpha_size) + _glitz_add_format (thread_info, &format, pixel_format); + } - format.types.window = 1; - format.id = 0; + if (!thread_info->n_formats) + return; - n_attribs_list = sizeof (_attribs_list) / sizeof (GLint *); + qsort (thread_info->formats, thread_info->n_formats, + sizeof (glitz_drawable_format_t), _glitz_agl_format_compare); - for (i = 0; i < n_attribs_list; i++) { - GLint value; - - pixel_format = aglChoosePixelFormat (NULL, 0, _attribs_list[i]); + /* + * Update AGLPixelFormat list so that it matches the sorted format list. + */ + new_pfs = malloc (sizeof (AGLPixelFormat) * thread_info->n_formats); + if (!new_pfs) { + thread_info->n_formats = 0; + return; + } - /* Stereo is not supported yet */ - if (!(aglDescribePixelFormat (pixel_format, AGL_STEREO, &value)) || - value) { - aglDestroyPixelFormat (pixel_format); - continue; + for (i = 0; i < thread_info->n_formats; i++) { + new_pfs[i] = thread_info->pixel_formats[thread_info->formats[i].id]; + thread_info->formats[i].id = i; } - - aglDescribePixelFormat (pixel_format, AGL_DOUBLEBUFFER, &value); - format.doublebuffer = (value)? 1: 0; - - aglDescribePixelFormat (pixel_format, AGL_RED_SIZE, &value); - format.color.red_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_GREEN_SIZE, &value); - format.color.green_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_BLUE_SIZE, &value); - format.color.blue_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_ALPHA_SIZE, &value); - format.color.alpha_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_DEPTH_SIZE, &value); - format.depth_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_STENCIL_SIZE, &value); - format.stencil_size = (unsigned short) value; - - if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK) { - aglDescribePixelFormat (pixel_format, AGL_SAMPLE_BUFFERS_ARB, &value); - if (value) { - aglDescribePixelFormat (pixel_format, AGL_SAMPLES_ARB, &value); - format.samples = (unsigned short) (value > 1)? value: 1; - } else - format.samples = 1; - } else - format.samples = 1; - - if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_PBUFFER_MASK) { - if (format.color.red_size && format.color.green_size && - format.color.blue_size && format.color.alpha_size && - format.doublebuffer == 0 && format.stencil_size == 0 && - format.depth_size == 0) { - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK) - format.types.pbuffer = 1; - else if (format.samples == 1) - format.types.pbuffer = 1; - else - format.types.pbuffer = 0; - } else - format.types.pbuffer = 0; - } else - format.types.pbuffer = 0; - - if (format.color.red_size || - format.color.green_size || - format.color.blue_size || - format.color.alpha_size) - _glitz_add_format (thread_info, &format, pixel_format); - } - - if (!thread_info->n_formats) - return; - - qsort (thread_info->formats, thread_info->n_formats, - sizeof (glitz_drawable_format_t), _glitz_agl_format_compare); - - /* - * Update AGLPixelFormat list so that it matches the sorted format list. - */ - new_pfs = malloc (sizeof (AGLPixelFormat) * thread_info->n_formats); - if (!new_pfs) { - thread_info->n_formats = 0; - return; - } - - for (i = 0; i < thread_info->n_formats; i++) { - new_pfs[i] = thread_info->pixel_formats[thread_info->formats[i].id]; - thread_info->formats[i].id = i; - } - - free (thread_info->pixel_formats); - thread_info->pixel_formats = new_pfs; + + free (thread_info->pixel_formats); + thread_info->pixel_formats = new_pfs; } glitz_drawable_format_t * glitz_agl_find_drawable_format (unsigned long mask, - const glitz_drawable_format_t *templ, - int count) + const glitz_drawable_format_t *templ, + int count) { - glitz_agl_thread_info_t *thread_info = glitz_agl_thread_info_get (); + glitz_agl_thread_info_t *thread_info = glitz_agl_thread_info_get (); - return glitz_drawable_format_find (thread_info->formats, - thread_info->n_formats, - mask, templ, count); + return glitz_drawable_format_find (thread_info->formats, + thread_info->n_formats, + mask, templ, count); } slim_hidden_def(glitz_agl_find_drawable_format); diff --git a/src/agl/glitz_agl_info.c b/src/agl/glitz_agl_info.c index d921c57..7438bd1 100644 --- a/src/agl/glitz_agl_info.c +++ b/src/agl/glitz_agl_info.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -33,85 +33,97 @@ glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address = { - /* core */ - (glitz_gl_enable_t) glEnable, - (glitz_gl_disable_t) glDisable, - (glitz_gl_get_error_t) glGetError, - (glitz_gl_get_string_t) glGetString, - (glitz_gl_enable_client_state_t) glEnableClientState, - (glitz_gl_disable_client_state_t) glDisableClientState, - (glitz_gl_vertex_pointer_t) glVertexPointer, - (glitz_gl_tex_coord_pointer_t) glTexCoordPointer, - (glitz_gl_draw_arrays_t) glDrawArrays, - (glitz_gl_tex_env_f_t) glTexEnvf, - (glitz_gl_tex_env_fv_t) glTexEnvfv, - (glitz_gl_tex_gen_i_t) glTexGeni, - (glitz_gl_tex_gen_fv_t) glTexGenfv, - (glitz_gl_color_4us_t) glColor4us, - (glitz_gl_color_4f_t) glColor4f, - (glitz_gl_scissor_t) glScissor, - (glitz_gl_blend_func_t) glBlendFunc, - (glitz_gl_clear_t) glClear, - (glitz_gl_clear_color_t) glClearColor, - (glitz_gl_clear_stencil_t) glClearStencil, - (glitz_gl_stencil_func_t) glStencilFunc, - (glitz_gl_stencil_op_t) glStencilOp, - (glitz_gl_push_attrib_t) glPushAttrib, - (glitz_gl_pop_attrib_t) glPopAttrib, - (glitz_gl_matrix_mode_t) glMatrixMode, - (glitz_gl_push_matrix_t) glPushMatrix, - (glitz_gl_pop_matrix_t) glPopMatrix, - (glitz_gl_load_identity_t) glLoadIdentity, - (glitz_gl_load_matrix_f_t) glLoadMatrixf, - (glitz_gl_depth_range_t) glDepthRange, - (glitz_gl_viewport_t) glViewport, - (glitz_gl_raster_pos_2f_t) glRasterPos2f, - (glitz_gl_bitmap_t) glBitmap, - (glitz_gl_read_buffer_t) glReadBuffer, - (glitz_gl_draw_buffer_t) glDrawBuffer, - (glitz_gl_copy_pixels_t) glCopyPixels, - (glitz_gl_flush_t) glFlush, - (glitz_gl_finish_t) glFinish, - (glitz_gl_pixel_store_i_t) glPixelStorei, - (glitz_gl_ortho_t) glOrtho, - (glitz_gl_scale_f_t) glScalef, - (glitz_gl_translate_f_t) glTranslatef, - (glitz_gl_hint_t) glHint, - (glitz_gl_depth_mask_t) glDepthMask, - (glitz_gl_polygon_mode_t) glPolygonMode, - (glitz_gl_shade_model_t) glShadeModel, - (glitz_gl_color_mask_t) glColorMask, - (glitz_gl_read_pixels_t) glReadPixels, - (glitz_gl_get_tex_image_t) glGetTexImage, - (glitz_gl_tex_sub_image_2d_t) glTexSubImage2D, - (glitz_gl_gen_textures_t) glGenTextures, - (glitz_gl_delete_textures_t) glDeleteTextures, - (glitz_gl_bind_texture_t) glBindTexture, - (glitz_gl_tex_image_2d_t) glTexImage2D, - (glitz_gl_tex_parameter_i_t) glTexParameteri, - (glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv, - (glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D, - (glitz_gl_get_integer_v_t) glGetIntegerv, - - /* extensions */ - (glitz_gl_blend_color_t) 0, - (glitz_gl_active_texture_t) 0, - (glitz_gl_client_active_texture_t) 0, - (glitz_gl_multi_draw_arrays_t) 0, - (glitz_gl_gen_programs_t) 0, - (glitz_gl_delete_programs_t) 0, - (glitz_gl_program_string_t) 0, - (glitz_gl_bind_program_t) 0, - (glitz_gl_program_local_param_4fv_t) 0, - (glitz_gl_get_program_iv_t) 0, - (glitz_gl_gen_buffers_t) 0, - (glitz_gl_delete_buffers_t) 0, - (glitz_gl_bind_buffer_t) 0, - (glitz_gl_buffer_data_t) 0, - (glitz_gl_buffer_sub_data_t) 0, - (glitz_gl_get_buffer_sub_data_t) 0, - (glitz_gl_map_buffer_t) 0, - (glitz_gl_unmap_buffer_t) 0 + /* core */ + (glitz_gl_enable_t) glEnable, + (glitz_gl_disable_t) glDisable, + (glitz_gl_get_error_t) glGetError, + (glitz_gl_get_string_t) glGetString, + (glitz_gl_enable_client_state_t) glEnableClientState, + (glitz_gl_disable_client_state_t) glDisableClientState, + (glitz_gl_vertex_pointer_t) glVertexPointer, + (glitz_gl_tex_coord_pointer_t) glTexCoordPointer, + (glitz_gl_draw_arrays_t) glDrawArrays, + (glitz_gl_tex_env_f_t) glTexEnvf, + (glitz_gl_tex_env_fv_t) glTexEnvfv, + (glitz_gl_tex_gen_i_t) glTexGeni, + (glitz_gl_tex_gen_fv_t) glTexGenfv, + (glitz_gl_color_4us_t) glColor4us, + (glitz_gl_color_4f_t) glColor4f, + (glitz_gl_scissor_t) glScissor, + (glitz_gl_blend_func_t) glBlendFunc, + (glitz_gl_clear_t) glClear, + (glitz_gl_clear_color_t) glClearColor, + (glitz_gl_clear_stencil_t) glClearStencil, + (glitz_gl_stencil_func_t) glStencilFunc, + (glitz_gl_stencil_op_t) glStencilOp, + (glitz_gl_push_attrib_t) glPushAttrib, + (glitz_gl_pop_attrib_t) glPopAttrib, + (glitz_gl_matrix_mode_t) glMatrixMode, + (glitz_gl_push_matrix_t) glPushMatrix, + (glitz_gl_pop_matrix_t) glPopMatrix, + (glitz_gl_load_identity_t) glLoadIdentity, + (glitz_gl_load_matrix_f_t) glLoadMatrixf, + (glitz_gl_depth_range_t) glDepthRange, + (glitz_gl_viewport_t) glViewport, + (glitz_gl_raster_pos_2f_t) glRasterPos2f, + (glitz_gl_bitmap_t) glBitmap, + (glitz_gl_read_buffer_t) glReadBuffer, + (glitz_gl_draw_buffer_t) glDrawBuffer, + (glitz_gl_copy_pixels_t) glCopyPixels, + (glitz_gl_flush_t) glFlush, + (glitz_gl_finish_t) glFinish, + (glitz_gl_pixel_store_i_t) glPixelStorei, + (glitz_gl_ortho_t) glOrtho, + (glitz_gl_scale_f_t) glScalef, + (glitz_gl_translate_f_t) glTranslatef, + (glitz_gl_hint_t) glHint, + (glitz_gl_depth_mask_t) glDepthMask, + (glitz_gl_polygon_mode_t) glPolygonMode, + (glitz_gl_shade_model_t) glShadeModel, + (glitz_gl_color_mask_t) glColorMask, + (glitz_gl_read_pixels_t) glReadPixels, + (glitz_gl_get_tex_image_t) glGetTexImage, + (glitz_gl_tex_sub_image_2d_t) glTexSubImage2D, + (glitz_gl_gen_textures_t) glGenTextures, + (glitz_gl_delete_textures_t) glDeleteTextures, + (glitz_gl_bind_texture_t) glBindTexture, + (glitz_gl_tex_image_2d_t) glTexImage2D, + (glitz_gl_tex_parameter_i_t) glTexParameteri, + (glitz_gl_tex_parameter_fv_t) glTexParameterfv, + (glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv, + (glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D, + (glitz_gl_get_integer_v_t) glGetIntegerv, + + /* extensions */ + (glitz_gl_blend_color_t) 0, + (glitz_gl_active_texture_t) 0, + (glitz_gl_client_active_texture_t) 0, + (glitz_gl_multi_draw_arrays_t) 0, + (glitz_gl_gen_programs_t) 0, + (glitz_gl_delete_programs_t) 0, + (glitz_gl_program_string_t) 0, + (glitz_gl_bind_program_t) 0, + (glitz_gl_program_local_param_4fv_t) 0, + (glitz_gl_get_program_iv_t) 0, + (glitz_gl_gen_buffers_t) 0, + (glitz_gl_delete_buffers_t) 0, + (glitz_gl_bind_buffer_t) 0, + (glitz_gl_buffer_data_t) 0, + (glitz_gl_buffer_sub_data_t) 0, + (glitz_gl_get_buffer_sub_data_t) 0, + (glitz_gl_map_buffer_t) 0, + (glitz_gl_unmap_buffer_t) 0, + (glitz_gl_gen_framebuffers_t) 0, + (glitz_gl_delete_framebuffers_t) 0, + (glitz_gl_bind_framebuffer_t) 0, + (glitz_gl_framebuffer_renderbuffer_t) 0, + (glitz_gl_framebuffer_texture_2d_t) 0, + (glitz_gl_check_framebuffer_status_t) 0, + (glitz_gl_gen_renderbuffers_t) 0, + (glitz_gl_delete_renderbuffers_t) 0, + (glitz_gl_bind_renderbuffer_t) 0, + (glitz_gl_renderbuffer_storage_t) 0, + (glitz_gl_get_renderbuffer_parameter_iv_t) 0 }; static void @@ -132,79 +144,79 @@ static pthread_key_t info_tsd; static void glitz_agl_thread_info_destroy (glitz_agl_thread_info_t *thread_info) { - pthread_setspecific (info_tsd, NULL); - - if (thread_info) { - glitz_agl_thread_info_fini (thread_info); - free (thread_info); - } + pthread_setspecific (info_tsd, NULL); + + if (thread_info) { + glitz_agl_thread_info_fini (thread_info); + free (thread_info); + } } static void _tsd_destroy (void *p) { - if (p) { - glitz_agl_thread_info_fini ((glitz_agl_thread_info_t *) p); - free (p); - } + if (p) { + glitz_agl_thread_info_fini ((glitz_agl_thread_info_t *) p); + free (p); + } } glitz_agl_thread_info_t * glitz_agl_thread_info_get (void) { - glitz_agl_thread_info_t *thread_info; - void *p; - - if (!tsd_initialized) { - pthread_key_create (&info_tsd, _tsd_destroy); - tsd_initialized = 1; - } - - p = pthread_getspecific (info_tsd); - - if (p == NULL) { - thread_info = malloc (sizeof (glitz_agl_thread_info_t)); - glitz_agl_thread_info_init (thread_info); - - pthread_setspecific (info_tsd, thread_info); - } else - thread_info = (glitz_agl_thread_info_t *) p; - - return thread_info; + glitz_agl_thread_info_t *thread_info; + void *p; + + if (!tsd_initialized) { + pthread_key_create (&info_tsd, _tsd_destroy); + tsd_initialized = 1; + } + + p = pthread_getspecific (info_tsd); + + if (p == NULL) { + thread_info = malloc (sizeof (glitz_agl_thread_info_t)); + glitz_agl_thread_info_init (thread_info); + + pthread_setspecific (info_tsd, thread_info); + } else + thread_info = (glitz_agl_thread_info_t *) p; + + return thread_info; } #else /* not thread safe */ static glitz_agl_thread_info_t _thread_info = { - 0, - NULL, - NULL, - 0, - NULL, - 0, - { 0 }, - 0, - NULL, - 0, - NULL, - { 0 } + 0, + NULL, + NULL, + 0, + NULL, + 0, + { 0 }, + 0, + NULL, + 0, + NULL, + { 0 } }; static void glitz_agl_thread_info_destroy (glitz_agl_thread_info_t *thread_info) { - if (thread_info) - glitz_agl_thread_info_fini (thread_info); + if (thread_info) + glitz_agl_thread_info_fini (thread_info); } glitz_agl_thread_info_t * glitz_agl_thread_info_get (void) { - if (_thread_info.context_stack_size == 0) - glitz_agl_thread_info_init (&_thread_info); - - return &_thread_info; + if (_thread_info.context_stack_size == 0) + glitz_agl_thread_info_init (&_thread_info); + + return &_thread_info; } #endif @@ -212,58 +224,58 @@ glitz_agl_thread_info_get (void) static void glitz_agl_thread_info_init (glitz_agl_thread_info_t *thread_info) { - thread_info->formats = NULL; - thread_info->pixel_formats = (AGLPixelFormat *) 0; - thread_info->n_formats = 0; - thread_info->contexts = NULL; - thread_info->n_contexts = 0; + thread_info->formats = NULL; + thread_info->pixel_formats = (AGLPixelFormat *) 0; + thread_info->n_formats = 0; + thread_info->contexts = NULL; + thread_info->n_contexts = 0; - thread_info->context_stack_size = 1; - thread_info->context_stack->surface = NULL; - thread_info->context_stack->constraint = GLITZ_NONE; + thread_info->context_stack_size = 1; + thread_info->context_stack->surface = NULL; + thread_info->context_stack->constraint = GLITZ_NONE; - thread_info->root_context = NULL; + thread_info->root_context = NULL; - thread_info->agl_feature_mask = 0; + thread_info->agl_feature_mask = 0; - thread_info->cctx = NULL; + thread_info->cctx = NULL; - glitz_program_map_init (&thread_info->program_map); + glitz_program_map_init (&thread_info->program_map); - if (!glitz_agl_query_extensions (thread_info)) - glitz_agl_query_formats (thread_info); + if (!glitz_agl_query_extensions (thread_info)) + glitz_agl_query_formats (thread_info); } static void glitz_agl_thread_info_fini (glitz_agl_thread_info_t *thread_info) { - int i; - - for (i = 0; i < thread_info->n_contexts; i++) - glitz_agl_context_destroy (thread_info, thread_info->contexts[i]); - - for (i = 0; i < thread_info->n_formats; i++) - aglDestroyPixelFormat (thread_info->pixel_formats[i]); - - if (thread_info->formats) - free (thread_info->formats); - - if (thread_info->pixel_formats) - free (thread_info->pixel_formats); + int i; + + for (i = 0; i < thread_info->n_contexts; i++) + glitz_agl_context_destroy (thread_info, thread_info->contexts[i]); + + for (i = 0; i < thread_info->n_formats; i++) + aglDestroyPixelFormat (thread_info->pixel_formats[i]); + + if (thread_info->formats) + free (thread_info->formats); + + if (thread_info->pixel_formats) + free (thread_info->pixel_formats); } void glitz_agl_init (void) { - glitz_agl_thread_info_get (); + glitz_agl_thread_info_get (); } slim_hidden_def(glitz_agl_init); void glitz_agl_fini (void) { - glitz_agl_thread_info_t *info = glitz_agl_thread_info_get (); + glitz_agl_thread_info_t *info = glitz_agl_thread_info_get (); - glitz_agl_thread_info_destroy (info); + glitz_agl_thread_info_destroy (info); } slim_hidden_def(glitz_agl_fini); diff --git a/src/agl/glitz_agl_pbuffer.c b/src/agl/glitz_agl_pbuffer.c index 65ed9eb..687bb2d 100644 --- a/src/agl/glitz_agl_pbuffer.c +++ b/src/agl/glitz_agl_pbuffer.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,28 +31,28 @@ AGLPbuffer glitz_agl_pbuffer_create (glitz_agl_thread_info_t *thread_info, - int width, - int height) + int width, + int height) { - AGLPbuffer pbuffer; - glitz_gl_enum_t target; + AGLPbuffer pbuffer; + glitz_gl_enum_t target; - if (!POWER_OF_TWO (width) || !POWER_OF_TWO (height)) { - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK) - target = GLITZ_GL_TEXTURE_RECTANGLE; - else - return (AGLPbuffer) 0; - } else - target = GLITZ_GL_TEXTURE_2D; + if (!POWER_OF_TWO (width) || !POWER_OF_TWO (height)) { + if (thread_info->agl_feature_mask & + GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK) + target = GLITZ_GL_TEXTURE_RECTANGLE; + else + return (AGLPbuffer) 0; + } else + target = GLITZ_GL_TEXTURE_2D; - aglCreatePBuffer (width, height, target, GLITZ_GL_RGBA, 0, &pbuffer); + aglCreatePBuffer (width, height, target, GLITZ_GL_RGBA, 0, &pbuffer); - return pbuffer; + return pbuffer; } -void +void glitz_agl_pbuffer_destroy (AGLPbuffer pbuffer) { - aglDestroyPBuffer (pbuffer); + aglDestroyPBuffer (pbuffer); } diff --git a/src/agl/glitz_aglint.h b/src/agl/glitz_aglint.h index d8d5d7c..0060319 100644 --- a/src/agl/glitz_aglint.h +++ b/src/agl/glitz_aglint.h @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -43,47 +43,46 @@ typedef struct _glitz_agl_drawable glitz_agl_drawable_t; typedef struct _glitz_agl_context_info_t { - glitz_agl_drawable_t *drawable; - glitz_surface_t *surface; - glitz_constraint_t constraint; + glitz_agl_drawable_t *drawable; + glitz_surface_t *surface; + glitz_constraint_t constraint; } glitz_agl_context_info_t; typedef struct _glitz_agl_context_t { - glitz_context_t base; - AGLContext context; - glitz_format_id_t id; - AGLPixelFormat pixel_format; - glitz_bool_t pbuffer; - glitz_backend_t backend; - glitz_gl_int_t max_viewport_dims[2]; - glitz_gl_int_t max_texture_2d_size; - glitz_gl_int_t max_texture_rect_size; - glitz_bool_t initialized; + glitz_context_t base; + AGLContext context; + glitz_format_id_t id; + AGLPixelFormat pixel_format; + glitz_bool_t pbuffer; + glitz_backend_t backend; + glitz_bool_t initialized; } glitz_agl_context_t; typedef struct _glitz_agl_thread_info_t { - int drawables; - glitz_drawable_format_t *formats; - AGLPixelFormat *pixel_formats; - int n_formats; - glitz_agl_context_t **contexts; - int n_contexts; - glitz_agl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; - int context_stack_size; - AGLContext root_context; - unsigned long agl_feature_mask; - glitz_context_t *cctx; - glitz_program_map_t program_map; + int drawables; + glitz_int_drawable_format_t *formats; + AGLPixelFormat *pixel_formats; + int n_formats; + glitz_agl_context_t **contexts; + int n_contexts; + glitz_agl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; + int context_stack_size; + AGLContext root_context; + unsigned long agl_feature_mask; + glitz_context_t *cctx; + glitz_program_map_t program_map; } glitz_agl_thread_info_t; struct _glitz_agl_drawable { - glitz_drawable_t base; - - glitz_agl_thread_info_t *thread_info; - glitz_agl_context_t *context; - AGLDrawable drawable; - AGLPbuffer pbuffer; - WindowRef window; + glitz_drawable_t base; + + glitz_agl_thread_info_t *thread_info; + glitz_agl_context_t *context; + AGLDrawable drawable; + AGLPbuffer pbuffer; + WindowRef window; + int width; + int height; }; extern glitz_status_t __internal_linkage @@ -94,33 +93,33 @@ glitz_agl_thread_info_get (void); extern glitz_agl_context_t __internal_linkage * glitz_agl_context_get (glitz_agl_thread_info_t *thread_info, - glitz_drawable_format_t *format); + glitz_drawable_format_t *format); extern void __internal_linkage glitz_agl_context_destroy (glitz_agl_thread_info_t *thread_info, - glitz_agl_context_t *context); + glitz_agl_context_t *context); extern void __internal_linkage glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info); extern AGLPbuffer __internal_linkage glitz_agl_pbuffer_create (glitz_agl_thread_info_t *thread_info, - int width, - int height); + int width, + int height); extern void __internal_linkage glitz_agl_pbuffer_destroy (AGLPbuffer pbuffer); extern glitz_drawable_t __internal_linkage * glitz_agl_create_pbuffer (void *abstract_templ, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height); + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); -extern void __internal_linkage +extern glitz_bool_t __internal_linkage glitz_agl_push_current (void *abstract_drawable, - glitz_surface_t *surface, - glitz_constraint_t constraint); + glitz_surface_t *surface, + glitz_constraint_t constraint); extern glitz_surface_t __internal_linkage * glitz_agl_pop_current (void *abstract_drawable); @@ -128,7 +127,7 @@ glitz_agl_pop_current (void *abstract_drawable); extern void __internal_linkage glitz_agl_destroy (void *abstract_drawable); -extern void __internal_linkage +extern glitz_bool_t __internal_linkage glitz_agl_swap_buffers (void *abstract_drawable); /* Avoid unnecessary PLT entries. */ diff --git a/src/egl/Makefile.am b/src/egl/Makefile.am index 547bb84..ee6ef72 100644 --- a/src/egl/Makefile.am +++ b/src/egl/Makefile.am @@ -15,7 +15,6 @@ libglitz_egl_la_SOURCES = \ glitz_egl_extension.c \ glitz_egl_context.c \ glitz_egl_pbuffer.c \ - glitz_eglext.h \ glitz_eglint.h libglitz_egl_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined @@ -34,7 +33,6 @@ EXTRA_DIST = \ glitz_egl_extension.c \ glitz_egl_context.c \ glitz_egl_pbuffer.c \ - glitz_eglext.h \ glitz_eglint.h \ glitz-egl.pc.in \ glitz-egl.man diff --git a/src/egl/glitz-egl.h b/src/egl/glitz-egl.h index 1b6bf8d..802c05f 100644 --- a/src/egl/glitz-egl.h +++ b/src/egl/glitz-egl.h @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -42,33 +42,41 @@ glitz_egl_init (const char *gl_library); void glitz_egl_fini (void); - - + + /* glitz_egl_config.c */ glitz_drawable_format_t * -glitz_egl_find_config (EGLDisplay egl_display, - EGLScreenMESA egl_screen, - unsigned long mask, - const glitz_drawable_format_t *templ, - int count); +glitz_egl_find_window_config (EGLDisplay egl_display, + EGLScreenMESA egl_screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count); + +glitz_drawable_format_t * +glitz_egl_find_pbuffer_config (EGLDisplay egl_display, + EGLScreenMESA egl_screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count); + /* glitz_egl_surface.c */ glitz_drawable_t * glitz_egl_create_surface (EGLDisplay egl_display, - EGLScreenMESA egl_screen, - glitz_drawable_format_t *format, - EGLSurface egl_surface, - unsigned int width, - unsigned int height); + EGLScreenMESA egl_screen, + glitz_drawable_format_t *format, + EGLSurface egl_surface, + unsigned int width, + unsigned int height); glitz_drawable_t * glitz_egl_create_pbuffer_surface (EGLDisplay egl_display, - EGLScreenMESA egl_screen, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height); + EGLScreenMESA egl_screen, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); #if defined(__cplusplus) || defined(c_plusplus) diff --git a/src/egl/glitz_egl_config.c b/src/egl/glitz_egl_config.c index 671c6d9..729269f 100644 --- a/src/egl/glitz_egl_config.c +++ b/src/egl/glitz_egl_config.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -34,188 +34,210 @@ static int _glitz_egl_format_compare (const void *elem1, - const void *elem2) + const void *elem2) { - int i, score[2]; - glitz_drawable_format_t *format[2]; - - format[0] = (glitz_drawable_format_t *) elem1; - format[1] = (glitz_drawable_format_t *) elem2; - i = score[0] = score[1] = 0; - - for (; i < 2; i++) { - if (format[i]->color.red_size) { - if (format[i]->color.red_size == 8) - score[i] += 5; - score[i] += 10; - } + glitz_int_drawable_format_t *format[2]; + int i, score[2]; - if (format[i]->color.green_size) { - if (format[i]->color.green_size == 8) - score[i] += 5; - score[i] += 10; - } - - if (format[i]->color.alpha_size) { - if (format[i]->color.alpha_size == 8) - score[i] += 5; - score[i] += 10; + format[0] = (glitz_int_drawable_format_t *) elem1; + format[1] = (glitz_int_drawable_format_t *) elem2; + i = score[0] = score[1] = 0; + + for (; i < 2; i++) + { + if (format[i]->d.color.red_size) + { + if (format[i]->d.color.red_size >= 8) + score[i] += 5; + + score[i] += 10; + } + + if (format[i]->d.color.alpha_size) + { + if (format[i]->d.color.alpha_size >= 8) + score[i] += 5; + + score[i] += 10; + } + + if (format[i]->d.stencil_size) + score[i] += 5; + + if (format[i]->d.depth_size) + score[i] += 5; + + if (format[i]->d.doublebuffer) + score[i] += 10; + + if (format[i]->d.samples > 1) + score[i] -= (20 - format[i]->d.samples); + + if (format[i]->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK) + score[i] += 10; + + if (format[i]->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK) + score[i] += 10; + + if (format[i]->caveat) + score[i] -= 1000; } - if (format[i]->stencil_size) - score[i] += 5; - - if (format[i]->depth_size) - score[i] += 5; - - if (format[i]->doublebuffer) - score[i] += 10; - - if (format[i]->types.window) - score[i] += 10; - - if (format[i]->types.pbuffer) - score[i] += 10; - - if (format[i]->samples > 1) - score[i] -= (20 - format[i]->samples); - } - - return score[1] - score[0]; + return score[1] - score[0]; } static void -_glitz_add_format (glitz_egl_screen_info_t *screen_info, - glitz_drawable_format_t *format, - EGLConfig egl_id) +_glitz_add_format (glitz_egl_screen_info_t *screen_info, + glitz_int_drawable_format_t *format) { - if (!glitz_drawable_format_find (screen_info->formats, - screen_info->n_formats, - GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK, - format, 0)) { int n = screen_info->n_formats; - + screen_info->formats = - realloc (screen_info->formats, - sizeof (glitz_drawable_format_t) * (n + 1)); - screen_info->egl_config_ids = - realloc (screen_info->egl_config_ids, sizeof (EGLConfig) * (n + 1)); - - if (screen_info->formats && screen_info->egl_config_ids) { - screen_info->formats[n] = *format; - screen_info->formats[n].id = n; - screen_info->egl_config_ids[n] = egl_id; - screen_info->n_formats++; + realloc (screen_info->formats, + sizeof (glitz_int_drawable_format_t) * (n + 1)); + if (screen_info->formats) + { + screen_info->formats[n] = *format; + screen_info->formats[n].d.id = n; + screen_info->n_formats++; } - } } -static glitz_status_t +static void _glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info) { - EGLDisplay egl_display; - glitz_drawable_format_t format; - EGLConfig *egl_configs; - int i, num_configs; - EGLConfig egl_id; - - egl_display = screen_info->display_info->egl_display; - - eglGetConfigs(egl_display, NULL, 0, &num_configs); - egl_configs = malloc(sizeof(*egl_configs) * num_configs); - eglGetConfigs(egl_display, egl_configs, num_configs, &num_configs); - - for (i = 0; i < num_configs; i++) { - int value; - - eglGetConfigAttrib(egl_display, egl_configs[i], - EGL_SURFACE_TYPE, &value); - if (!((value & EGL_WINDOW_BIT) || (value & EGL_PBUFFER_BIT))) - continue; - - format.types.window = (value & EGL_WINDOW_BIT)? 1: 0; - format.types.pbuffer = (value & EGL_PBUFFER_BIT)? 1: 0; - format.id = 0; - - eglGetConfigAttrib(egl_display, egl_configs[i], EGL_CONFIG_ID, &value); - egl_id = (EGLConfig) value; - - eglGetConfigAttrib(egl_display, egl_configs[i], EGL_RED_SIZE, &value); - format.color.red_size = (unsigned short) value; - eglGetConfigAttrib(egl_display, egl_configs[i], EGL_GREEN_SIZE, &value); - format.color.green_size = (unsigned short) value; - eglGetConfigAttrib(egl_display, egl_configs[i], EGL_BLUE_SIZE, &value); - format.color.blue_size = (unsigned short) value; - eglGetConfigAttrib(egl_display, egl_configs[i], EGL_ALPHA_SIZE, &value); - format.color.alpha_size = (unsigned short) value; - eglGetConfigAttrib(egl_display, egl_configs[i], EGL_DEPTH_SIZE, &value); - format.depth_size = (unsigned short) value; - eglGetConfigAttrib(egl_display, egl_configs[i], EGL_STENCIL_SIZE, &value); - format.stencil_size = (unsigned short) value; - - format.doublebuffer = 1; - - eglGetConfigAttrib(egl_display, egl_configs[i], EGL_SAMPLE_BUFFERS, &value); - if (value) { - eglGetConfigAttrib(egl_display, egl_configs[i], EGL_SAMPLES, &value); - format.samples = (unsigned short) (value > 1)? value: 1; - if (format.samples > 1) - format.types.pbuffer = 0; - } else - format.samples = 1; - - _glitz_add_format (screen_info, &format, egl_id); - } - - free(egl_configs); - - return GLITZ_STATUS_SUCCESS; + glitz_int_drawable_format_t format; + EGLDisplay egl_display; + EGLConfig *egl_configs; + int i, num_configs; + + egl_display = screen_info->display_info->egl_display; + + eglGetConfigs (egl_display, NULL, 0, &num_configs); + egl_configs = malloc (sizeof (EGLConfig) * num_configs); + if (!egl_configs) + return; + + format.d.id = 0; + format.d.doublebuffer = 1; + + eglGetConfigs (egl_display, egl_configs, num_configs, &num_configs); + + for (i = 0; i < num_configs; i++) + { + int value; + + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_SURFACE_TYPE, + &value); + if (!((value & EGL_WINDOW_BIT) || (value & EGL_PBUFFER_BIT))) + continue; + + format.types = 0; + if (value & EGL_WINDOW_BIT) + format.types |= GLITZ_DRAWABLE_TYPE_WINDOW_MASK; + + if (value & EGL_PBUFFER_BIT) + format.types |= GLITZ_DRAWABLE_TYPE_PBUFFER_MASK; + + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_CONFIG_ID, + &value); + format.u.uval = value; + + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_RED_SIZE, &value); + format.d.color.red_size = (unsigned short) value; + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_GREEN_SIZE, + &value); + format.d.color.green_size = (unsigned short) value; + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_BLUE_SIZE, + &value); + format.d.color.blue_size = (unsigned short) value; + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_ALPHA_SIZE, + &value); + format.d.color.alpha_size = (unsigned short) value; + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_DEPTH_SIZE, + &value); + format.d.depth_size = (unsigned short) value; + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_STENCIL_SIZE, + &value); + format.d.stencil_size = (unsigned short) value; + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_CONFIG_CAVEAT, + &value); + format.caveat = (unsigned short) value; + + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_SAMPLE_BUFFERS, + &value); + if (value) + { + eglGetConfigAttrib (egl_display, egl_configs[i], EGL_SAMPLES, + &value); + format.d.samples = (unsigned short) (value > 1)? value: 1; + } + else + format.d.samples = 1; + + _glitz_add_format (screen_info, &format); + } + + free (egl_configs); } void glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info) { - EGLConfig *egl_new_ids; - int i; - - _glitz_egl_query_configs (screen_info); - - if (!screen_info->n_formats) - return; - - qsort (screen_info->formats, screen_info->n_formats, - sizeof (glitz_drawable_format_t), _glitz_egl_format_compare); - - /* - * Update XID list so that it matches the sorted format list. - */ - egl_new_ids = malloc (sizeof (EGLConfig) * screen_info->n_formats); - if (!egl_new_ids) { - screen_info->n_formats = 0; - return; - } - - for (i = 0; i < screen_info->n_formats; i++) { - egl_new_ids[i] = screen_info->egl_config_ids[screen_info->formats[i].id]; - screen_info->formats[i].id = i; - } - - free (screen_info->egl_config_ids); - screen_info->egl_config_ids = egl_new_ids; + int i; + + _glitz_egl_query_configs (screen_info); + + if (!screen_info->n_formats) + return; + + qsort (screen_info->formats, screen_info->n_formats, + sizeof (glitz_int_drawable_format_t), _glitz_egl_format_compare); + + for (i = 0; i < screen_info->n_formats; i++) + screen_info->formats[i].d.id = i; } glitz_drawable_format_t * -glitz_egl_find_config (EGLDisplay egl_display, - EGLScreenMESA egl_screen, - unsigned long mask, - const glitz_drawable_format_t *templ, - int count) +glitz_egl_find_window_config (EGLDisplay egl_display, + EGLScreenMESA egl_screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count) { - glitz_egl_screen_info_t *screen_info = - glitz_egl_screen_info_get (egl_display, egl_screen); + glitz_int_drawable_format_t itempl; + glitz_egl_screen_info_t *screen_info = + glitz_egl_screen_info_get (egl_display, egl_screen); + + glitz_drawable_format_copy (templ, &itempl.d, mask); + + itempl.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK; + mask |= GLITZ_INT_FORMAT_WINDOW_MASK; + + return glitz_drawable_format_find (screen_info->formats, + screen_info->n_formats, + mask, &itempl, count); +} +slim_hidden_def(glitz_egl_find_window_config); + +glitz_drawable_format_t * +glitz_egl_find_pbuffer_config (EGLDisplay egl_display, + EGLScreenMESA egl_screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count) +{ + glitz_int_drawable_format_t itempl; + glitz_egl_screen_info_t *screen_info = + glitz_egl_screen_info_get (egl_display, egl_screen); + + glitz_drawable_format_copy (templ, &itempl.d, mask); + + itempl.types = GLITZ_DRAWABLE_TYPE_PBUFFER_MASK; + mask |= GLITZ_INT_FORMAT_PBUFFER_MASK; - return glitz_drawable_format_find (screen_info->formats, - screen_info->n_formats, - mask, templ, count); + return glitz_drawable_format_find (screen_info->formats, + screen_info->n_formats, + mask, &itempl, count); } -slim_hidden_def(glitz_egl_find_config); +slim_hidden_def(glitz_egl_find_pbuffer_config); diff --git a/src/egl/glitz_egl_context.c b/src/egl/glitz_egl_context.c index 89d77d3..f64e8f7 100644 --- a/src/egl/glitz_egl_context.c +++ b/src/egl/glitz_egl_context.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -35,323 +35,368 @@ extern glitz_gl_proc_address_list_t _glitz_egl_gl_proc_address; static void _glitz_egl_context_create (glitz_egl_screen_info_t *screen_info, - EGLConfig egl_config, - EGLContext egl_share_list, - glitz_egl_context_t *context) + EGLConfig egl_config, + EGLContext egl_share_list, + glitz_egl_context_t *context) { - context->id = egl_config; - context->egl_context = eglCreateContext (screen_info->display_info->egl_display, - egl_config, egl_share_list, NULL); + context->id = egl_config; + context->egl_context = + eglCreateContext (screen_info->display_info->egl_display, + egl_config, egl_share_list, NULL); } static glitz_context_t * _glitz_egl_create_context (void *abstract_drawable, - glitz_drawable_format_t *format) + glitz_drawable_format_t *format) { - glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable; - glitz_egl_screen_info_t *screen_info = drawable->screen_info; - int format_id = screen_info->egl_config_ids[format->id]; - glitz_egl_context_t *context; - - context = malloc (sizeof (glitz_egl_context_t)); - if (!context) - return NULL; + glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable; + glitz_egl_screen_info_t *screen_info = drawable->screen_info; + int format_id = screen_info->formats[format->id].u.uval; + glitz_egl_context_t *context; + + context = malloc (sizeof (glitz_egl_context_t)); + if (!context) + return NULL; - _glitz_context_init (&context->base, &drawable->base); - - _glitz_egl_context_create (screen_info, - format_id, - screen_info->egl_root_context, - context); + _glitz_context_init (&context->base, &drawable->base); - return (glitz_context_t *) context; + _glitz_egl_context_create (screen_info, + format_id, + screen_info->egl_root_context, + context); + + return (glitz_context_t *) context; } static void _glitz_egl_context_destroy (void *abstract_context) { - glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context; - glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) - context->base.drawable; - - if (drawable->screen_info->display_info->thread_info->cctx == &context->base) - { - eglMakeCurrent (drawable->screen_info->display_info->egl_display, - EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - drawable->screen_info->display_info->thread_info->cctx = NULL; - } - - eglDestroyContext (drawable->screen_info->display_info->egl_display, - context->egl_context); - - _glitz_context_fini (&context->base); - - free (context); + glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context; + glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) + context->base.drawable; + + if (drawable->screen_info->display_info->thread_info->cctx == + &context->base) + { + eglMakeCurrent (drawable->screen_info->display_info->egl_display, + EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + drawable->screen_info->display_info->thread_info->cctx = NULL; + } + + eglDestroyContext (drawable->screen_info->display_info->egl_display, + context->egl_context); + + _glitz_context_fini (&context->base); + + free (context); } static void _glitz_egl_copy_context (void *abstract_src, - void *abstract_dst, - unsigned long mask) + void *abstract_dst, + unsigned long mask) { - glitz_egl_context_t *src = (glitz_egl_context_t *) abstract_src; - glitz_egl_context_t *dst = (glitz_egl_context_t *) abstract_dst; - glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) - src->base.drawable; + glitz_egl_context_t *src = (glitz_egl_context_t *) abstract_src; + glitz_egl_context_t *dst = (glitz_egl_context_t *) abstract_dst; + glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) + src->base.drawable; - eglCopyContextMESA (drawable->screen_info->display_info->egl_display, - src->egl_context, dst->egl_context, mask); + eglCopyContextMESA (drawable->screen_info->display_info->egl_display, + src->egl_context, dst->egl_context, mask); } static void -_glitz_egl_make_current (void *abstract_context, - void *abstract_drawable) +_glitz_egl_make_current (void *abstract_drawable, + void *abstract_context) { - glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context; - glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable; - glitz_egl_display_info_t *display_info = drawable->screen_info->display_info; - - if ((eglGetCurrentContext () != context->egl_context) || - (eglGetCurrentSurface ( 0 ) != drawable->egl_surface)) - eglMakeCurrent (display_info->egl_display, drawable->egl_surface, - drawable->egl_surface, context->egl_context); - - display_info->thread_info->cctx = &context->base; + glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context; + glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable; + glitz_egl_display_info_t *display_info = + drawable->screen_info->display_info; + + if (drawable->base.width != drawable->width || + drawable->base.height != drawable->height) + _glitz_egl_drawable_update_size (drawable, + drawable->base.width, + drawable->base.height); + + if ((eglGetCurrentContext () != context->egl_context) || + (eglGetCurrentSurface ( 0 ) != drawable->egl_surface)) + { + if (display_info->thread_info->cctx) + { + glitz_context_t *ctx = display_info->thread_info->cctx; + + if (ctx->lose_current) + ctx->lose_current (ctx->closure); + } + + eglMakeCurrent (display_info->egl_display, drawable->egl_surface, + drawable->egl_surface, context->egl_context); + } + + display_info->thread_info->cctx = &context->base; } +static void +_glitz_egl_notify_dummy (void *abstract_drawable, + glitz_surface_t *surface) {} + static glitz_function_pointer_t _glitz_egl_context_get_proc_address (void *abstract_context, - const char *name) + const char *name) { - glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context; - glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) - context->base.drawable; + glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context; + glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) + context->base.drawable; + + _glitz_egl_make_current (drawable, context); - _glitz_egl_make_current (context, drawable); - - return glitz_egl_get_proc_address (name, drawable->screen_info); + return glitz_egl_get_proc_address (name, drawable->screen_info); } glitz_egl_context_t * glitz_egl_context_get (glitz_egl_screen_info_t *screen_info, - glitz_drawable_format_t *format) + glitz_drawable_format_t *format) { - glitz_egl_context_t *context; - glitz_egl_context_t **contexts = screen_info->contexts; - int index, n_contexts = screen_info->n_contexts; - EGLConfig egl_config_id; + glitz_egl_context_t *context; + glitz_egl_context_t **contexts = screen_info->contexts; + int index, n_contexts = screen_info->n_contexts; - for (; n_contexts; n_contexts--, contexts++) - if ((*contexts)->id == screen_info->egl_config_ids[format->id]) - return *contexts; + for (; n_contexts; n_contexts--, contexts++) + if ((*contexts)->id == screen_info->formats[format->id].u.uval) + return *contexts; - index = screen_info->n_contexts++; + index = screen_info->n_contexts++; - screen_info->contexts = - realloc (screen_info->contexts, - sizeof (glitz_egl_context_t *) * screen_info->n_contexts); - if (!screen_info->contexts) - return NULL; + screen_info->contexts = + realloc (screen_info->contexts, + sizeof (glitz_egl_context_t *) * screen_info->n_contexts); + if (!screen_info->contexts) + return NULL; - context = malloc (sizeof (glitz_egl_context_t)); - if (!context) - return NULL; - - screen_info->contexts[index] = context; - - egl_config_id = screen_info->egl_config_ids[format->id]; - - _glitz_egl_context_create (screen_info, - egl_config_id, - screen_info->egl_root_context, - context); - - if (!screen_info->egl_root_context) - screen_info->egl_root_context = context->egl_context; - - memcpy (&context->backend.gl, - &_glitz_egl_gl_proc_address, - sizeof (glitz_gl_proc_address_list_t)); - - context->backend.create_pbuffer = glitz_egl_create_pbuffer; - context->backend.destroy = glitz_egl_destroy; - context->backend.push_current = glitz_egl_push_current; - context->backend.pop_current = glitz_egl_pop_current; - context->backend.swap_buffers = glitz_egl_swap_buffers; - - context->backend.create_context = _glitz_egl_create_context; - context->backend.destroy_context = _glitz_egl_context_destroy; - context->backend.copy_context = _glitz_egl_copy_context; - context->backend.make_current = _glitz_egl_make_current; - context->backend.get_proc_address = _glitz_egl_context_get_proc_address; - - context->backend.drawable_formats = screen_info->formats; - context->backend.n_drawable_formats = screen_info->n_formats; - - context->backend.texture_formats = NULL; - context->backend.formats = NULL; - context->backend.n_formats = 0; - - context->backend.program_map = &screen_info->program_map; - context->backend.feature_mask = 0; - - context->initialized = 0; - - return context; + context = malloc (sizeof (glitz_egl_context_t)); + if (!context) + return NULL; + + screen_info->contexts[index] = context; + + _glitz_egl_context_create (screen_info, + screen_info->formats[format->id].u.uval, + screen_info->egl_root_context, + context); + + if (!screen_info->egl_root_context) + screen_info->egl_root_context = context->egl_context; + + context->backend.gl = &_glitz_egl_gl_proc_address; + + context->backend.create_pbuffer = glitz_egl_create_pbuffer; + context->backend.destroy = glitz_egl_destroy; + context->backend.push_current = glitz_egl_push_current; + context->backend.pop_current = glitz_egl_pop_current; + context->backend.attach_notify = _glitz_egl_notify_dummy; + context->backend.detach_notify = _glitz_egl_notify_dummy; + context->backend.swap_buffers = glitz_egl_swap_buffers; + + context->backend.create_context = _glitz_egl_create_context; + context->backend.destroy_context = _glitz_egl_context_destroy; + context->backend.copy_context = _glitz_egl_copy_context; + context->backend.make_current = _glitz_egl_make_current; + context->backend.get_proc_address = _glitz_egl_context_get_proc_address; + + context->backend.drawable_formats = NULL; + context->backend.n_drawable_formats = 0; + + if (screen_info->n_formats) + { + int size; + + size = sizeof (glitz_int_drawable_format_t) * screen_info->n_formats; + context->backend.drawable_formats = malloc (size); + if (context->backend.drawable_formats) + { + memcpy (context->backend.drawable_formats, screen_info->formats, + size); + context->backend.n_drawable_formats = screen_info->n_formats; + } + } + + context->backend.texture_formats = NULL; + context->backend.formats = NULL; + context->backend.n_formats = 0; + + context->backend.program_map = &screen_info->program_map; + context->backend.feature_mask = 0; + + context->initialized = 0; + + return context; } void glitz_egl_context_destroy (glitz_egl_screen_info_t *screen_info, - glitz_egl_context_t *context) + glitz_egl_context_t *context) { - if (context->backend.formats) - free (context->backend.formats); - - if (context->backend.texture_formats) - free (context->backend.texture_formats); - - eglDestroyContext (screen_info->display_info->egl_display, - context->egl_context); - free (context); + if (context->backend.drawable_formats) + free (context->backend.drawable_formats); + + if (context->backend.formats) + free (context->backend.formats); + + if (context->backend.texture_formats) + free (context->backend.texture_formats); + + eglDestroyContext (screen_info->display_info->egl_display, + context->egl_context); + free (context); } static void _glitz_egl_context_initialize (glitz_egl_screen_info_t *screen_info, - glitz_egl_context_t *context) + glitz_egl_context_t *context) { - const char *version; - - glitz_backend_init (&context->backend, - glitz_egl_get_proc_address, - (void *) screen_info); - - context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS, - context->max_viewport_dims); - - glitz_initiate_state (&_glitz_egl_gl_proc_address); - - version = (const char *) context->backend.gl.get_string (GLITZ_GL_VERSION); - if (version) - { - /* Having trouble with TexSubImage2D to NPOT GL_TEXTURE_2D textures when - using nvidia's binary driver. Seems like a driver issue, but I'm not - sure yet. Turning of NPOT GL_TEXTURE_2D textures until this have been - solved. */ - if (strstr (version, "NVIDIA 61.11") || - strstr (version, "NVIDIA 66.29")) + const char *version; + + glitz_backend_init (&context->backend, + glitz_egl_get_proc_address, + (void *) screen_info); + + glitz_initiate_state (&_glitz_egl_gl_proc_address); + + version = (const char *) + context->backend.gl->get_string (GLITZ_GL_VERSION); + if (version) { - context->backend.feature_mask &= - ~GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK; + /* Having trouble with TexSubImage2D to NPOT GL_TEXTURE_2D textures + when using nvidia's binary driver. Seems like a driver issue, but + I'm not sure yet. Turning of NPOT GL_TEXTURE_2D textures until + this have been solved. */ + if (strstr (version, "NVIDIA 61.11") || + strstr (version, "NVIDIA 66.29")) + { + context->backend.feature_mask &= + ~GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK; + } } - } - - context->initialized = 1; + + context->initialized = 1; } static void _glitz_egl_context_make_current (glitz_egl_surface_t *drawable, - glitz_bool_t finish) + glitz_bool_t finish) { - glitz_egl_display_info_t *display_info = drawable->screen_info->display_info; - - if (finish) - glFinish (); - - if (display_info->thread_info->cctx) - { - glitz_context_t *ctx = display_info->thread_info->cctx; - - if (ctx->lose_current) - ctx->lose_current (ctx->closure); - - display_info->thread_info->cctx = NULL; - } - - eglMakeCurrent (display_info->egl_display, - drawable->egl_surface, drawable->egl_surface, - drawable->context->egl_context); - - drawable->base.update_all = 1; - - if (!drawable->context->initialized) - _glitz_egl_context_initialize (drawable->screen_info, drawable->context); + glitz_egl_display_info_t *display_info = + drawable->screen_info->display_info; + + if (finish) + glFinish (); + + if (display_info->thread_info->cctx) + { + glitz_context_t *ctx = display_info->thread_info->cctx; + + if (ctx->lose_current) + ctx->lose_current (ctx->closure); + + display_info->thread_info->cctx = NULL; + } + + eglMakeCurrent (display_info->egl_display, + drawable->egl_surface, drawable->egl_surface, + drawable->context->egl_context); + + drawable->base.update_all = 1; + + if (!drawable->context->initialized) + _glitz_egl_context_initialize (drawable->screen_info, + drawable->context); } static void _glitz_egl_context_update (glitz_egl_surface_t *drawable, - glitz_constraint_t constraint) + glitz_constraint_t constraint) { - EGLContext egl_context; - - switch (constraint) { - case GLITZ_NONE: - break; - case GLITZ_ANY_CONTEXT_CURRENT: { - glitz_egl_display_info_t *dinfo = drawable->screen_info->display_info; - - if (dinfo->thread_info->cctx) - { - _glitz_egl_context_make_current (drawable, 0); - } - else - { - egl_context = eglGetCurrentContext (); - if (egl_context == (EGLContext) 0) - _glitz_egl_context_make_current (drawable, 0); - } + EGLContext egl_context; + + switch (constraint) { + case GLITZ_NONE: + break; + case GLITZ_ANY_CONTEXT_CURRENT: { + glitz_egl_display_info_t *dinfo = drawable->screen_info->display_info; + + if (dinfo->thread_info->cctx) + { + _glitz_egl_context_make_current (drawable, 0); + } + else + { + egl_context = eglGetCurrentContext (); + if (egl_context == (EGLContext) 0) + _glitz_egl_context_make_current (drawable, 0); + } } break; - case GLITZ_CONTEXT_CURRENT: - egl_context = eglGetCurrentContext (); - if (egl_context != drawable->context->egl_context) - _glitz_egl_context_make_current (drawable, (egl_context)? 1: 0); - break; - case GLITZ_DRAWABLE_CURRENT: - egl_context = eglGetCurrentContext (); - if ((egl_context != drawable->context->egl_context) || - (eglGetCurrentSurface ( 0 ) != drawable->egl_surface)) - _glitz_egl_context_make_current (drawable, (egl_context)? 1: 0); - break; - } + case GLITZ_CONTEXT_CURRENT: + egl_context = eglGetCurrentContext (); + if (egl_context != drawable->context->egl_context) + _glitz_egl_context_make_current (drawable, (egl_context)? 1: 0); + break; + case GLITZ_DRAWABLE_CURRENT: + if (drawable->base.width != drawable->width || + drawable->base.height != drawable->height) + _glitz_egl_drawable_update_size (drawable, + drawable->base.width, + drawable->base.height); + + egl_context = eglGetCurrentContext (); + if ((egl_context != drawable->context->egl_context) || + (eglGetCurrentSurface ( 0 ) != drawable->egl_surface)) + _glitz_egl_context_make_current (drawable, (egl_context)? 1: 0); + break; + } } -void +glitz_bool_t glitz_egl_push_current (void *abstract_drawable, - glitz_surface_t *surface, - glitz_constraint_t constraint) + glitz_surface_t *surface, + glitz_constraint_t constraint) { - glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable; - glitz_egl_context_info_t *context_info; - int index; - - index = drawable->screen_info->context_stack_size++; - - context_info = &drawable->screen_info->context_stack[index]; - context_info->drawable = drawable; - context_info->surface = surface; - context_info->constraint = constraint; - - _glitz_egl_context_update (context_info->drawable, constraint); + glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable; + glitz_egl_context_info_t *context_info; + int index; + + index = drawable->screen_info->context_stack_size++; + + context_info = &drawable->screen_info->context_stack[index]; + context_info->drawable = drawable; + context_info->surface = surface; + context_info->constraint = constraint; + + _glitz_egl_context_update (context_info->drawable, constraint); + + return 1; } glitz_surface_t * glitz_egl_pop_current (void *abstract_drawable) { - glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable; - glitz_egl_context_info_t *context_info = NULL; - int index; - - drawable->screen_info->context_stack_size--; - index = drawable->screen_info->context_stack_size - 1; - - context_info = &drawable->screen_info->context_stack[index]; - - if (context_info->drawable) - _glitz_egl_context_update (context_info->drawable, - context_info->constraint); - - if (context_info->constraint == GLITZ_DRAWABLE_CURRENT) - return context_info->surface; - - return NULL; + glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable; + glitz_egl_context_info_t *context_info = NULL; + int index; + + drawable->screen_info->context_stack_size--; + index = drawable->screen_info->context_stack_size - 1; + + context_info = &drawable->screen_info->context_stack[index]; + + if (context_info->drawable) + _glitz_egl_context_update (context_info->drawable, + context_info->constraint); + + if (context_info->constraint == GLITZ_DRAWABLE_CURRENT) + return context_info->surface; + + return NULL; } diff --git a/src/egl/glitz_egl_info.c b/src/egl/glitz_egl_info.c index f8627b4..c195558 100644 --- a/src/egl/glitz_egl_info.c +++ b/src/egl/glitz_egl_info.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -35,111 +35,124 @@ glitz_gl_proc_address_list_t _glitz_egl_gl_proc_address = { - /* core */ - (glitz_gl_enable_t) glEnable, - (glitz_gl_disable_t) glDisable, - (glitz_gl_get_error_t) glGetError, - (glitz_gl_get_string_t) glGetString, - (glitz_gl_enable_client_state_t) glEnableClientState, - (glitz_gl_disable_client_state_t) glDisableClientState, - (glitz_gl_vertex_pointer_t) glVertexPointer, - (glitz_gl_tex_coord_pointer_t) glTexCoordPointer, - (glitz_gl_draw_arrays_t) glDrawArrays, - (glitz_gl_tex_env_f_t) glTexEnvf, - (glitz_gl_tex_env_fv_t) glTexEnvfv, - (glitz_gl_tex_gen_i_t) glTexGeni, - (glitz_gl_tex_gen_fv_t) glTexGenfv, - (glitz_gl_color_4us_t) glColor4us, - (glitz_gl_color_4f_t) glColor4f, - (glitz_gl_scissor_t) glScissor, - (glitz_gl_blend_func_t) glBlendFunc, - (glitz_gl_clear_t) glClear, - (glitz_gl_clear_color_t) glClearColor, - (glitz_gl_clear_stencil_t) glClearStencil, - (glitz_gl_stencil_func_t) glStencilFunc, - (glitz_gl_stencil_op_t) glStencilOp, - (glitz_gl_push_attrib_t) glPushAttrib, - (glitz_gl_pop_attrib_t) glPopAttrib, - (glitz_gl_matrix_mode_t) glMatrixMode, - (glitz_gl_push_matrix_t) glPushMatrix, - (glitz_gl_pop_matrix_t) glPopMatrix, - (glitz_gl_load_identity_t) glLoadIdentity, - (glitz_gl_load_matrix_f_t) glLoadMatrixf, - (glitz_gl_depth_range_t) glDepthRange, - (glitz_gl_viewport_t) glViewport, - (glitz_gl_raster_pos_2f_t) glRasterPos2f, - (glitz_gl_bitmap_t) glBitmap, - (glitz_gl_read_buffer_t) glReadBuffer, - (glitz_gl_draw_buffer_t) glDrawBuffer, - (glitz_gl_copy_pixels_t) glCopyPixels, - (glitz_gl_flush_t) glFlush, - (glitz_gl_finish_t) glFinish, - (glitz_gl_pixel_store_i_t) glPixelStorei, - (glitz_gl_ortho_t) glOrtho, - (glitz_gl_scale_f_t) glScalef, - (glitz_gl_translate_f_t) glTranslatef, - (glitz_gl_hint_t) glHint, - (glitz_gl_depth_mask_t) glDepthMask, - (glitz_gl_polygon_mode_t) glPolygonMode, - (glitz_gl_shade_model_t) glShadeModel, - (glitz_gl_color_mask_t) glColorMask, - (glitz_gl_read_pixels_t) glReadPixels, - (glitz_gl_get_tex_image_t) glGetTexImage, - (glitz_gl_tex_sub_image_2d_t) glTexSubImage2D, - (glitz_gl_gen_textures_t) glGenTextures, - (glitz_gl_delete_textures_t) glDeleteTextures, - (glitz_gl_bind_texture_t) glBindTexture, - (glitz_gl_tex_image_2d_t) glTexImage2D, - (glitz_gl_tex_parameter_i_t) glTexParameteri, - (glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv, - (glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D, - (glitz_gl_get_integer_v_t) glGetIntegerv, - - /* extensions */ - (glitz_gl_blend_color_t) 0, - (glitz_gl_active_texture_t) 0, - (glitz_gl_client_active_texture_t) 0, - (glitz_gl_multi_draw_arrays_t) 0, - (glitz_gl_gen_programs_t) 0, - (glitz_gl_delete_programs_t) 0, - (glitz_gl_program_string_t) 0, - (glitz_gl_bind_program_t) 0, - (glitz_gl_program_local_param_4fv_t) 0, - (glitz_gl_get_program_iv_t) 0, - (glitz_gl_gen_buffers_t) 0, - (glitz_gl_delete_buffers_t) 0, - (glitz_gl_bind_buffer_t) 0, - (glitz_gl_buffer_data_t) 0, - (glitz_gl_buffer_sub_data_t) 0, - (glitz_gl_get_buffer_sub_data_t) 0, - (glitz_gl_map_buffer_t) 0, - (glitz_gl_unmap_buffer_t) 0 + /* core */ + (glitz_gl_enable_t) glEnable, + (glitz_gl_disable_t) glDisable, + (glitz_gl_get_error_t) glGetError, + (glitz_gl_get_string_t) glGetString, + (glitz_gl_enable_client_state_t) glEnableClientState, + (glitz_gl_disable_client_state_t) glDisableClientState, + (glitz_gl_vertex_pointer_t) glVertexPointer, + (glitz_gl_tex_coord_pointer_t) glTexCoordPointer, + (glitz_gl_draw_arrays_t) glDrawArrays, + (glitz_gl_tex_env_f_t) glTexEnvf, + (glitz_gl_tex_env_fv_t) glTexEnvfv, + (glitz_gl_tex_gen_i_t) glTexGeni, + (glitz_gl_tex_gen_fv_t) glTexGenfv, + (glitz_gl_color_4us_t) glColor4us, + (glitz_gl_color_4f_t) glColor4f, + (glitz_gl_scissor_t) glScissor, + (glitz_gl_blend_func_t) glBlendFunc, + (glitz_gl_clear_t) glClear, + (glitz_gl_clear_color_t) glClearColor, + (glitz_gl_clear_stencil_t) glClearStencil, + (glitz_gl_stencil_func_t) glStencilFunc, + (glitz_gl_stencil_op_t) glStencilOp, + (glitz_gl_push_attrib_t) glPushAttrib, + (glitz_gl_pop_attrib_t) glPopAttrib, + (glitz_gl_matrix_mode_t) glMatrixMode, + (glitz_gl_push_matrix_t) glPushMatrix, + (glitz_gl_pop_matrix_t) glPopMatrix, + (glitz_gl_load_identity_t) glLoadIdentity, + (glitz_gl_load_matrix_f_t) glLoadMatrixf, + (glitz_gl_depth_range_t) glDepthRange, + (glitz_gl_viewport_t) glViewport, + (glitz_gl_raster_pos_2f_t) glRasterPos2f, + (glitz_gl_bitmap_t) glBitmap, + (glitz_gl_read_buffer_t) glReadBuffer, + (glitz_gl_draw_buffer_t) glDrawBuffer, + (glitz_gl_copy_pixels_t) glCopyPixels, + (glitz_gl_flush_t) glFlush, + (glitz_gl_finish_t) glFinish, + (glitz_gl_pixel_store_i_t) glPixelStorei, + (glitz_gl_ortho_t) glOrtho, + (glitz_gl_scale_f_t) glScalef, + (glitz_gl_translate_f_t) glTranslatef, + (glitz_gl_hint_t) glHint, + (glitz_gl_depth_mask_t) glDepthMask, + (glitz_gl_polygon_mode_t) glPolygonMode, + (glitz_gl_shade_model_t) glShadeModel, + (glitz_gl_color_mask_t) glColorMask, + (glitz_gl_read_pixels_t) glReadPixels, + (glitz_gl_get_tex_image_t) glGetTexImage, + (glitz_gl_tex_sub_image_2d_t) glTexSubImage2D, + (glitz_gl_gen_textures_t) glGenTextures, + (glitz_gl_delete_textures_t) glDeleteTextures, + (glitz_gl_bind_texture_t) glBindTexture, + (glitz_gl_tex_image_2d_t) glTexImage2D, + (glitz_gl_tex_parameter_i_t) glTexParameteri, + (glitz_gl_tex_parameter_fv_t) glTexParameterfv, + (glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv, + (glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D, + (glitz_gl_get_integer_v_t) glGetIntegerv, + + /* extensions */ + (glitz_gl_blend_color_t) 0, + (glitz_gl_active_texture_t) 0, + (glitz_gl_client_active_texture_t) 0, + (glitz_gl_multi_draw_arrays_t) 0, + (glitz_gl_gen_programs_t) 0, + (glitz_gl_delete_programs_t) 0, + (glitz_gl_program_string_t) 0, + (glitz_gl_bind_program_t) 0, + (glitz_gl_program_local_param_4fv_t) 0, + (glitz_gl_get_program_iv_t) 0, + (glitz_gl_gen_buffers_t) 0, + (glitz_gl_delete_buffers_t) 0, + (glitz_gl_bind_buffer_t) 0, + (glitz_gl_buffer_data_t) 0, + (glitz_gl_buffer_sub_data_t) 0, + (glitz_gl_get_buffer_sub_data_t) 0, + (glitz_gl_map_buffer_t) 0, + (glitz_gl_unmap_buffer_t) 0, + (glitz_gl_gen_framebuffers_t) 0, + (glitz_gl_delete_framebuffers_t) 0, + (glitz_gl_bind_framebuffer_t) 0, + (glitz_gl_framebuffer_renderbuffer_t) 0, + (glitz_gl_framebuffer_texture_2d_t) 0, + (glitz_gl_check_framebuffer_status_t) 0, + (glitz_gl_gen_renderbuffers_t) 0, + (glitz_gl_delete_renderbuffers_t) 0, + (glitz_gl_bind_renderbuffer_t) 0, + (glitz_gl_renderbuffer_storage_t) 0, + (glitz_gl_get_renderbuffer_parameter_iv_t) 0 }; glitz_function_pointer_t glitz_egl_get_proc_address (const char *name, - void *closure) + void *closure) { - glitz_egl_screen_info_t *screen_info = (glitz_egl_screen_info_t *) closure; - glitz_egl_thread_info_t *info = screen_info->display_info->thread_info; - glitz_function_pointer_t address = NULL; - - if (screen_info->egl_feature_mask & GLITZ_EGL_FEATURE_GET_PROC_ADDRESS_MASK) - address = eglGetProcAddress ((char *) name); - - if (!address) { - if (!info->dlhand) - info->dlhand = dlopen (info->gl_library, RTLD_LAZY); - - if (info->dlhand) { - dlerror (); - address = (glitz_function_pointer_t) dlsym (info->dlhand, name); - if (dlerror () != NULL) - address = NULL; + glitz_egl_screen_info_t *screen_info = (glitz_egl_screen_info_t *) closure; + glitz_egl_thread_info_t *info = screen_info->display_info->thread_info; + glitz_function_pointer_t address = NULL; + + if (screen_info->egl_feature_mask & + GLITZ_EGL_FEATURE_GET_PROC_ADDRESS_MASK) + address = eglGetProcAddress ((char *) name); + + if (!address) { + if (!info->dlhand) + info->dlhand = dlopen (info->gl_library, RTLD_LAZY); + + if (info->dlhand) { + dlerror (); + address = (glitz_function_pointer_t) dlsym (info->dlhand, name); + if (dlerror () != NULL) + address = NULL; + } } - } - - return address; + + return address; } static void @@ -151,27 +164,27 @@ _glitz_egl_screen_destroy (glitz_egl_screen_info_t *screen_info); static void _glitz_egl_thread_info_fini (glitz_egl_thread_info_t *thread_info) { - int i; - - for (i = 0; i < thread_info->n_displays; i++) - _glitz_egl_display_destroy (thread_info->displays[i]); - - free (thread_info->displays); - - thread_info->displays = NULL; - thread_info->n_displays = 0; - - if (thread_info->gl_library) { - free (thread_info->gl_library); - thread_info->gl_library = NULL; - } + int i; - if (thread_info->dlhand) { - dlclose (thread_info->dlhand); - thread_info->dlhand = NULL; - } - - thread_info->cctx = NULL; + for (i = 0; i < thread_info->n_displays; i++) + _glitz_egl_display_destroy (thread_info->displays[i]); + + free (thread_info->displays); + + thread_info->displays = NULL; + thread_info->n_displays = 0; + + if (thread_info->gl_library) { + free (thread_info->gl_library); + thread_info->gl_library = NULL; + } + + if (thread_info->dlhand) { + dlclose (thread_info->dlhand); + thread_info->dlhand = NULL; + } + + thread_info->cctx = NULL; } #ifdef PTHREADS @@ -183,108 +196,108 @@ static pthread_key_t info_tsd; static void _glitz_egl_thread_info_init (glitz_egl_thread_info_t *thread_info) { - thread_info->displays = NULL; - thread_info->n_displays = 0; - thread_info->gl_library = NULL; - thread_info->dlhand = NULL; - thread_info->cctx = NULL; + thread_info->displays = NULL; + thread_info->n_displays = 0; + thread_info->gl_library = NULL; + thread_info->dlhand = NULL; + thread_info->cctx = NULL; } static void _glitz_egl_thread_info_destroy (glitz_egl_thread_info_t *thread_info) { - pthread_setspecific (info_tsd, NULL); - - if (thread_info) { - _glitz_egl_thread_info_fini (thread_info); - free (thread_info); - } + pthread_setspecific (info_tsd, NULL); + + if (thread_info) { + _glitz_egl_thread_info_fini (thread_info); + free (thread_info); + } } static void _tsd_destroy (void *p) { - if (p) { - _glitz_egl_thread_info_fini ((glitz_egl_thread_info_t *) p); - free (p); - } + if (p) { + _glitz_egl_thread_info_fini ((glitz_egl_thread_info_t *) p); + free (p); + } } static glitz_egl_thread_info_t * _glitz_egl_thread_info_get (const char *gl_library) { - glitz_egl_thread_info_t *thread_info; - void *p; - - if (!tsd_initialized) { - pthread_key_create (&info_tsd, _tsd_destroy); - tsd_initialized = 1; - } - - p = pthread_getspecific (info_tsd); - - if (p == NULL) { - thread_info = malloc (sizeof (glitz_egl_thread_info_t)); - _glitz_egl_thread_info_init (thread_info); - - pthread_setspecific (info_tsd, thread_info); - } else - thread_info = (glitz_egl_thread_info_t *) p; - - if (gl_library) { - int len = strlen (gl_library); + glitz_egl_thread_info_t *thread_info; + void *p; - if (thread_info->gl_library) { - free (thread_info->gl_library); - thread_info->gl_library = NULL; + if (!tsd_initialized) { + pthread_key_create (&info_tsd, _tsd_destroy); + tsd_initialized = 1; } - - thread_info->gl_library = malloc (len + 1); - if (thread_info->gl_library) { - memcpy (thread_info->gl_library, gl_library, len); - thread_info->gl_library[len] = '\0'; + + p = pthread_getspecific (info_tsd); + + if (p == NULL) { + thread_info = malloc (sizeof (glitz_egl_thread_info_t)); + _glitz_egl_thread_info_init (thread_info); + + pthread_setspecific (info_tsd, thread_info); + } else + thread_info = (glitz_egl_thread_info_t *) p; + + if (gl_library) { + int len = strlen (gl_library); + + if (thread_info->gl_library) { + free (thread_info->gl_library); + thread_info->gl_library = NULL; + } + + thread_info->gl_library = malloc (len + 1); + if (thread_info->gl_library) { + memcpy (thread_info->gl_library, gl_library, len); + thread_info->gl_library[len] = '\0'; + } } - } - return thread_info; + return thread_info; } #else /* not thread safe */ static glitz_egl_thread_info_t thread_info = { - NULL, - 0, - NULL, - NULL + NULL, + 0, + NULL, + NULL }; static void _glitz_egl_thread_info_destroy (glitz_egl_thread_info_t *thread_info) { - if (thread_info) - _glitz_egl_thread_info_fini (thread_info); + if (thread_info) + _glitz_egl_thread_info_fini (thread_info); } static glitz_egl_thread_info_t * _glitz_egl_thread_info_get (const char *gl_library) { - if (gl_library) { - int len = strlen (gl_library); - - if (thread_info.gl_library) { - free (thread_info.gl_library); - thread_info.gl_library = NULL; - } - - thread_info.gl_library = malloc (len + 1); - if (thread_info.gl_library) { - memcpy (thread_info.gl_library, gl_library, len); - thread_info.gl_library[len] = '\0'; + if (gl_library) { + int len = strlen (gl_library); + + if (thread_info.gl_library) { + free (thread_info.gl_library); + thread_info.gl_library = NULL; + } + + thread_info.gl_library = malloc (len + 1); + if (thread_info.gl_library) { + memcpy (thread_info.gl_library, gl_library, len); + thread_info.gl_library[len] = '\0'; + } } - } - - return &thread_info; + + return &thread_info; } #endif @@ -292,141 +305,145 @@ _glitz_egl_thread_info_get (const char *gl_library) static glitz_egl_display_info_t * _glitz_egl_display_info_get (EGLDisplay egl_display) { - glitz_egl_display_info_t *display_info; - glitz_egl_thread_info_t *thread_info = _glitz_egl_thread_info_get (NULL); - glitz_egl_display_info_t **displays = thread_info->displays; - int index, n_displays = thread_info->n_displays; - - for (; n_displays; n_displays--, displays++) - if ((*displays)->egl_display == egl_display) - return *displays; - - index = thread_info->n_displays++; - - thread_info->displays = - realloc (thread_info->displays, - sizeof (glitz_egl_display_info_t *) * thread_info->n_displays); - - display_info = malloc (sizeof (glitz_egl_display_info_t)); - thread_info->displays[index] = display_info; - - display_info->thread_info = thread_info; - display_info->egl_display = egl_display; - display_info->screens = NULL; - display_info->n_screens = 0; - - return display_info; + glitz_egl_display_info_t *display_info; + glitz_egl_thread_info_t *thread_info = _glitz_egl_thread_info_get (NULL); + glitz_egl_display_info_t **displays = thread_info->displays; + int index, n_displays = thread_info->n_displays; + + for (; n_displays; n_displays--, displays++) + if ((*displays)->egl_display == egl_display) + return *displays; + + index = thread_info->n_displays++; + + thread_info->displays = + realloc (thread_info->displays, + sizeof (glitz_egl_display_info_t *) * + thread_info->n_displays); + + display_info = malloc (sizeof (glitz_egl_display_info_t)); + thread_info->displays[index] = display_info; + + display_info->thread_info = thread_info; + display_info->egl_display = egl_display; + display_info->screens = NULL; + display_info->n_screens = 0; + + return display_info; } static void _glitz_egl_display_destroy (glitz_egl_display_info_t *display_info) { - int i; - - for (i = 0; i < display_info->n_screens; i++) - _glitz_egl_screen_destroy (display_info->screens[i]); - - if (display_info->screens) - free (display_info->screens); - - free (display_info); + int i; + + for (i = 0; i < display_info->n_screens; i++) + _glitz_egl_screen_destroy (display_info->screens[i]); + + if (display_info->screens) + free (display_info->screens); + + free (display_info); } glitz_egl_screen_info_t * glitz_egl_screen_info_get (EGLDisplay display, - EGLScreenMESA screen) + EGLScreenMESA screen) { - glitz_egl_screen_info_t *screen_info; - glitz_egl_display_info_t *display_info = - _glitz_egl_display_info_get (display); - glitz_egl_screen_info_t **screens = display_info->screens; - int index, n_screens = display_info->n_screens; + glitz_egl_screen_info_t *screen_info; + glitz_egl_display_info_t *display_info = + _glitz_egl_display_info_get (display); + glitz_egl_screen_info_t **screens = display_info->screens; + int index, n_screens = display_info->n_screens; + #if 0 - int error_base, event_base; -#endif - - for (; n_screens; n_screens--, screens++) - if ((*screens)->screen == screen) - return *screens; - - index = display_info->n_screens++; - - display_info->screens = - realloc (display_info->screens, - sizeof (glitz_egl_screen_info_t *) * display_info->n_screens); - - screen_info = malloc (sizeof (glitz_egl_screen_info_t)); - display_info->screens[index] = screen_info; - - screen_info->display_info = display_info; - screen_info->screen = screen; - screen_info->drawables = 0; - screen_info->formats = NULL; - screen_info->egl_config_ids = NULL; - screen_info->n_formats = 0; - - screen_info->contexts = NULL; - screen_info->n_contexts = 0; - - glitz_program_map_init (&screen_info->program_map); - - screen_info->egl_root_context = (EGLContext) 0; - screen_info->egl_feature_mask = 0; + int error_base, event_base; +#endif + + for (; n_screens; n_screens--, screens++) + if ((*screens)->screen == screen) + return *screens; + + index = display_info->n_screens++; + + display_info->screens = + realloc (display_info->screens, + sizeof (glitz_egl_screen_info_t *) * display_info->n_screens); + + screen_info = malloc (sizeof (glitz_egl_screen_info_t)); + display_info->screens[index] = screen_info; + + screen_info->display_info = display_info; + screen_info->screen = screen; + screen_info->drawables = 0; + screen_info->formats = NULL; + screen_info->n_formats = 0; + + screen_info->contexts = NULL; + screen_info->n_contexts = 0; + + glitz_program_map_init (&screen_info->program_map); + + screen_info->egl_root_context = (EGLContext) 0; + screen_info->egl_feature_mask = 0; + #if 0 - if (eglQueryExtension (display, &error_base, &event_base)) { - int major, minor; - - if (eglQueryVersion (display, &major, &minor)) { - screen_info->egl_version = major + minor / 10.0f; - if (major > 1 || (major > 0 || minor >= 2)) { - glitz_egl_query_extensions (screen_info, screen_info->egl_version); - _glitz_egl_proc_address_lookup (screen_info); - glitz_egl_query_formats (screen_info); - } + if (eglQueryExtension (display, &error_base, &event_base)) { + int major, minor; + + if (eglQueryVersion (display, &major, &minor)) { + screen_info->egl_version = major + minor / 10.0f; + if (major > 1 || (major > 0 || minor >= 2)) { + glitz_egl_query_extensions (screen_info, + screen_info->egl_version); + _glitz_egl_proc_address_lookup (screen_info); + glitz_egl_query_formats (screen_info); + } + } } - } #endif - glitz_egl_query_extensions (screen_info, screen_info->egl_version); - glitz_egl_query_configs (screen_info); - - screen_info->context_stack_size = 1; - screen_info->context_stack->drawable = NULL; - screen_info->context_stack->surface = NULL; - screen_info->context_stack->constraint = GLITZ_NONE; - - return screen_info; + + glitz_egl_query_extensions (screen_info, screen_info->egl_version); + glitz_egl_query_configs (screen_info); + + screen_info->context_stack_size = 1; + screen_info->context_stack->drawable = NULL; + screen_info->context_stack->surface = NULL; + screen_info->context_stack->constraint = GLITZ_NONE; + + return screen_info; } static void _glitz_egl_screen_destroy (glitz_egl_screen_info_t *screen_info) { - EGLDisplay egl_display = screen_info->display_info->egl_display; - int i; - - if (screen_info->egl_root_context) - eglMakeCurrent (egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - for (i = 0; i < screen_info->n_contexts; i++) - glitz_egl_context_destroy (screen_info, screen_info->contexts[i]); - - free (screen_info->contexts); - free (screen_info->formats); - free (screen_info->egl_config_ids); - free (screen_info); + EGLDisplay egl_display = screen_info->display_info->egl_display; + int i; + + if (screen_info->egl_root_context) + eglMakeCurrent (egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + + for (i = 0; i < screen_info->n_contexts; i++) + glitz_egl_context_destroy (screen_info, screen_info->contexts[i]); + + free (screen_info->contexts); + free (screen_info->formats); + free (screen_info); } void glitz_egl_init (const char *gl_library) { - _glitz_egl_thread_info_get (gl_library); + _glitz_egl_thread_info_get (gl_library); } slim_hidden_def(glitz_egl_init); void glitz_egl_fini (void) { - glitz_egl_thread_info_t *info = _glitz_egl_thread_info_get (NULL); + glitz_egl_thread_info_t *info = _glitz_egl_thread_info_get (NULL); - _glitz_egl_thread_info_destroy (info); + _glitz_egl_thread_info_destroy (info); } slim_hidden_def(glitz_egl_fini); diff --git a/src/egl/glitz_egl_pbuffer.c b/src/egl/glitz_egl_pbuffer.c index cfe147a..0bf1e2b 100644 --- a/src/egl/glitz_egl_pbuffer.c +++ b/src/egl/glitz_egl_pbuffer.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,37 +31,39 @@ EGLSurface glitz_egl_pbuffer_create (glitz_egl_screen_info_t *screen_info, - EGLConfig egl_config, - int width, - int height) + EGLConfig egl_config, + int width, + int height) { - if (egl_config) { - int attributes[9]; + if (egl_config) { + int attributes[9]; + + attributes[0] = EGL_WIDTH; + attributes[1] = width; - attributes[0] = EGL_WIDTH; - attributes[1] = width; + attributes[2] = EGL_HEIGHT; + attributes[3] = height; - attributes[2] = EGL_HEIGHT; - attributes[3] = height; -#if 0 - attributes[4] = EGL_LARGEST_PBUFFER; - attributes[5] = 0; +#if 0 + attributes[4] = EGL_LARGEST_PBUFFER; + attributes[5] = 0; - attributes[6] = EGL_PRESERVED_CONTENTS; - attributes[7] = 1; - attributes[8] = 0; + attributes[6] = EGL_PRESERVED_CONTENTS; + attributes[7] = 1; + attributes[8] = 0; #endif - return - eglCreatePbufferSurface(screen_info->display_info->egl_display, - egl_config, attributes); - } else - return (EGLSurface) 0; + + return + eglCreatePbufferSurface (screen_info->display_info->egl_display, + egl_config, attributes); + } else + return (EGLSurface) 0; } -void +void glitz_egl_pbuffer_destroy (glitz_egl_screen_info_t *screen_info, - EGLSurface egl_pbuffer) + EGLSurface egl_pbuffer) { - eglDestroySurface(screen_info->display_info->egl_display, - egl_pbuffer); + eglDestroySurface (screen_info->display_info->egl_display, + egl_pbuffer); } diff --git a/src/egl/glitz_egl_surface.c b/src/egl/glitz_egl_surface.c index 0aa93a5..d98be64 100644 --- a/src/egl/glitz_egl_surface.c +++ b/src/egl/glitz_egl_surface.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,173 +31,213 @@ static glitz_egl_surface_t * _glitz_egl_create_surface (glitz_egl_screen_info_t *screen_info, - glitz_egl_context_t *context, - glitz_drawable_format_t *format, - EGLSurface egl_surface, - int width, - int height) + glitz_egl_context_t *context, + glitz_drawable_format_t *format, + EGLSurface egl_surface, + int width, + int height) { - glitz_egl_surface_t *surface; - - if (width <= 0 || height <= 0) - return NULL; - - surface = (glitz_egl_surface_t *) malloc (sizeof (glitz_egl_surface_t)); - if (surface == NULL) - return NULL; - - surface->base.ref_count = 1; - surface->screen_info = screen_info; - surface->context = context; - surface->egl_surface = egl_surface; - surface->base.format = format; - surface->base.backend = &context->backend; - - glitz_drawable_update_size (&surface->base, width, height); - - if (!context->initialized) { - glitz_egl_push_current (surface, NULL, GLITZ_CONTEXT_CURRENT); - glitz_egl_pop_current (surface); - } - - if (width > context->max_viewport_dims[0] || - height > context->max_viewport_dims[1]) { - free (surface); - return NULL; - } - - screen_info->drawables++; - - return surface; + glitz_egl_surface_t *surface; + + surface = (glitz_egl_surface_t *) malloc (sizeof (glitz_egl_surface_t)); + if (surface == NULL) + return NULL; + + surface->screen_info = screen_info; + surface->context = context; + surface->egl_surface = egl_surface; + surface->width = width; + surface->height = height; + + _glitz_drawable_init (&surface->base, + &screen_info->formats[format->id], + &context->backend, + width, height); + + if (!context->initialized) { + glitz_egl_push_current (surface, NULL, GLITZ_CONTEXT_CURRENT); + glitz_egl_pop_current (surface); + } + + if (width > context->backend.max_viewport_dims[0] || + height > context->backend.max_viewport_dims[1]) { + free (surface); + return NULL; + } + + screen_info->drawables++; + + return surface; +} + +glitz_bool_t +_glitz_egl_drawable_update_size (glitz_egl_surface_t *drawable, + int width, + int height) +{ + if (drawable->egl_surface) + { + glitz_egl_pbuffer_destroy (drawable->screen_info, + drawable->egl_surface); + drawable->egl_surface = + glitz_egl_pbuffer_create (drawable->screen_info, + drawable->context->egl_config, + (int) width, (int) height); + if (!drawable->egl_surface) + return 0; + } + + drawable->width = width; + drawable->height = height; + + return 1; } static glitz_drawable_t * _glitz_egl_create_pbuffer_surface (glitz_egl_screen_info_t *screen_info, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { - glitz_egl_surface_t *surface; - glitz_egl_context_t *context; - EGLSurface egl_pbuffer; - - if (!format->types.pbuffer) - return NULL; - - context = glitz_egl_context_get (screen_info, format); - if (!context) - return NULL; - - egl_pbuffer = glitz_egl_pbuffer_create (screen_info, context->egl_config, - (int) width, (int) height); - if (!egl_pbuffer) - return NULL; - - surface = _glitz_egl_create_surface (screen_info, context, format, - egl_pbuffer, - width, height); - if (!surface) { - glitz_egl_pbuffer_destroy (screen_info, egl_pbuffer); - return NULL; - } - - return &surface->base; + glitz_egl_surface_t *surface; + glitz_egl_context_t *context; + EGLSurface egl_pbuffer; + + context = glitz_egl_context_get (screen_info, format); + if (!context) + return NULL; + + egl_pbuffer = glitz_egl_pbuffer_create (screen_info, context->egl_config, + (int) width, (int) height); + if (!egl_pbuffer) + return NULL; + + surface = _glitz_egl_create_surface (screen_info, context, format, + egl_pbuffer, + width, height); + if (!surface) + { + glitz_egl_pbuffer_destroy (screen_info, egl_pbuffer); + return NULL; + } + + return &surface->base; } glitz_drawable_t * glitz_egl_create_pbuffer (void *abstract_templ, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { - glitz_egl_surface_t *templ = (glitz_egl_surface_t *) abstract_templ; + glitz_egl_surface_t *templ = (glitz_egl_surface_t *) abstract_templ; - return _glitz_egl_create_pbuffer_surface (templ->screen_info, format, - width, height); + return _glitz_egl_create_pbuffer_surface (templ->screen_info, format, + width, height); } glitz_drawable_t * glitz_egl_create_surface (EGLDisplay egl_display, - EGLScreenMESA egl_screen, - glitz_drawable_format_t *format, - EGLSurface egl_surface, - unsigned int width, - unsigned int height) + EGLScreenMESA egl_screen, + glitz_drawable_format_t *format, + EGLSurface egl_surface, + unsigned int width, + unsigned int height) { - glitz_egl_surface_t *surface; - glitz_egl_screen_info_t *screen_info; - glitz_egl_context_t *context; - - screen_info = glitz_egl_screen_info_get (egl_display, egl_screen); - if (!screen_info) - return NULL; - - context = glitz_egl_context_get (screen_info, format); - if (!context) - return NULL; - - surface = _glitz_egl_create_surface (screen_info, context, format, - egl_surface, - width, height); - if (!surface) - return NULL; - - return &surface->base; + glitz_egl_surface_t *surface; + glitz_egl_screen_info_t *screen_info; + glitz_egl_context_t *context; + glitz_int_drawable_format_t *iformat; + + screen_info = glitz_egl_screen_info_get (egl_display, egl_screen); + if (!screen_info) + return NULL; + + if (format->id >= screen_info->n_formats) + return NULL; + + iformat = &screen_info->formats[format->id]; + if (!(iformat->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK)) + return NULL; + + context = glitz_egl_context_get (screen_info, format); + if (!context) + return NULL; + + surface = _glitz_egl_create_surface (screen_info, context, format, + egl_surface, width, height); + if (!surface) + return NULL; + + return &surface->base; } slim_hidden_def(glitz_egl_create_surface); glitz_drawable_t * glitz_egl_create_pbuffer_surface (EGLDisplay display, - EGLScreenMESA screen, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + EGLScreenMESA screen, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { - glitz_egl_screen_info_t *screen_info; + glitz_egl_screen_info_t *screen_info; + glitz_int_drawable_format_t *iformat; - screen_info = glitz_egl_screen_info_get (display, screen); - if (!screen_info) - return NULL; + screen_info = glitz_egl_screen_info_get (display, screen); + if (!screen_info) + return NULL; - return _glitz_egl_create_pbuffer_surface (screen_info, format, - width, height); + if (format->id >= screen_info->n_formats) + return NULL; + + iformat = &screen_info->formats[format->id]; + if (!(iformat->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK)) + return NULL; + + return _glitz_egl_create_pbuffer_surface (screen_info, format, + width, height); } slim_hidden_def(glitz_egl_create_pbuffer_surface); void glitz_egl_destroy (void *abstract_drawable) { - EGLint value; - glitz_egl_surface_t *surface = (glitz_egl_surface_t *) abstract_drawable; - - surface->screen_info->drawables--; - if (surface->screen_info->drawables == 0) { - /* - * Last drawable? We have to destroy all fragment programs as this may - * be our last chance to have a context current. - */ - glitz_egl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT); - glitz_program_map_fini (&surface->base.backend->gl, - &surface->screen_info->program_map); - glitz_egl_pop_current (abstract_drawable); - } - - if (eglGetCurrentSurface ( 0 ) == surface->egl_surface) - eglMakeCurrent (surface->screen_info->display_info->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - eglQuerySurface (surface->screen_info->display_info->egl_display, surface->egl_surface, - EGL_SURFACE_TYPE, &value); - if (value == EGL_PBUFFER_BIT) - glitz_egl_pbuffer_destroy (surface->screen_info, surface->egl_surface); - - free (surface); + EGLint value; + glitz_egl_surface_t *surface = (glitz_egl_surface_t *) abstract_drawable; + + surface->screen_info->drawables--; + if (surface->screen_info->drawables == 0) { + /* + * Last drawable? We have to destroy all fragment programs as this may + * be our last chance to have a context current. + */ + glitz_egl_push_current (abstract_drawable, NULL, + GLITZ_CONTEXT_CURRENT); + glitz_program_map_fini (surface->base.backend->gl, + &surface->screen_info->program_map); + glitz_egl_pop_current (abstract_drawable); + } + + if (eglGetCurrentSurface (0) == surface->egl_surface) + eglMakeCurrent (surface->screen_info->display_info->egl_display, + EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + eglQuerySurface (surface->screen_info->display_info->egl_display, + surface->egl_surface, + EGL_SURFACE_TYPE, &value); + if (value == EGL_PBUFFER_BIT) + glitz_egl_pbuffer_destroy (surface->screen_info, surface->egl_surface); + + free (surface); } -void +glitz_bool_t glitz_egl_swap_buffers (void *abstract_drawable) { - glitz_egl_surface_t *surface = (glitz_egl_surface_t *) abstract_drawable; + glitz_egl_surface_t *surface = (glitz_egl_surface_t *) abstract_drawable; + + eglSwapBuffers (surface->screen_info->display_info->egl_display, + surface->egl_surface); - eglSwapBuffers (surface->screen_info->display_info->egl_display, - surface->egl_surface); + return 1; } diff --git a/src/egl/glitz_eglext.h b/src/egl/glitz_eglext.h deleted file mode 100644 index e31dd99..0000000 --- a/src/egl/glitz_eglext.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA - * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - * Authors: David Reveman <davidr@novell.com> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifndef GLITZ_EGLEXT_H_INCLUDED -#define GLITZ_EGLEXT_H_INCLUDED - - - -#endif /* GLITZ_EGLEXT_H_INCLUDED */ diff --git a/src/egl/glitz_eglint.h b/src/egl/glitz_eglint.h index dc81b17..f97896f 100644 --- a/src/egl/glitz_eglint.h +++ b/src/egl/glitz_eglint.h @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,8 +31,6 @@ #include "glitz-egl.h" -#include "glitz_eglext.h" - #define GLITZ_EGL_FEATURE_MAKE_CURRENT_READ_MASK (1L << 2) #define GLITZ_EGL_FEATURE_GET_PROC_ADDRESS_MASK (1L << 3) #define GLITZ_EGL_FEATURE_MULTISAMPLE_MASK (1L << 4) @@ -43,113 +41,116 @@ typedef struct _glitz_egl_screen_info_t glitz_egl_screen_info_t; typedef struct _glitz_egl_display_info_t glitz_egl_display_info_t; typedef struct _glitz_egl_thread_info_t { - glitz_egl_display_info_t **displays; - int n_displays; - char *gl_library; - void *dlhand; - glitz_context_t *cctx; + glitz_egl_display_info_t **displays; + int n_displays; + char *gl_library; + void *dlhand; + glitz_context_t *cctx; } glitz_egl_thread_info_t; struct _glitz_egl_display_info_t { - glitz_egl_thread_info_t *thread_info; - EGLDisplay egl_display; - glitz_egl_screen_info_t **screens; - int n_screens; + glitz_egl_thread_info_t *thread_info; + EGLDisplay egl_display; + glitz_egl_screen_info_t **screens; + int n_screens; }; typedef struct _glitz_egl_context_info_t { - glitz_egl_surface_t *drawable; - glitz_surface_t *surface; - glitz_constraint_t constraint; + glitz_egl_surface_t *drawable; + glitz_surface_t *surface; + glitz_constraint_t constraint; } glitz_egl_context_info_t; typedef struct _glitz_egl_context_t { - glitz_context_t base; - EGLContext egl_context; - glitz_format_id_t id; - EGLConfig egl_config; - glitz_backend_t backend; - glitz_gl_int_t max_viewport_dims[2]; - glitz_gl_int_t max_texture_2d_size; - glitz_gl_int_t max_texture_rect_size; - glitz_bool_t initialized; + glitz_context_t base; + EGLContext egl_context; + glitz_format_id_t id; + EGLConfig egl_config; + glitz_backend_t backend; + glitz_bool_t initialized; } glitz_egl_context_t; struct _glitz_egl_screen_info_t { - glitz_egl_display_info_t *display_info; - int screen; - int drawables; - glitz_drawable_format_t *formats; - EGLConfig *egl_config_ids; - int n_formats; - glitz_egl_context_t **contexts; - int n_contexts; - glitz_egl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; - int context_stack_size; - EGLContext egl_root_context; - unsigned long egl_feature_mask; - glitz_gl_float_t egl_version; - glitz_program_map_t program_map; + glitz_egl_display_info_t *display_info; + int screen; + int drawables; + glitz_int_drawable_format_t *formats; + int n_formats; + glitz_egl_context_t **contexts; + int n_contexts; + glitz_egl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; + int context_stack_size; + EGLContext egl_root_context; + unsigned long egl_feature_mask; + glitz_gl_float_t egl_version; + glitz_program_map_t program_map; }; struct _glitz_egl_surface { - glitz_drawable_t base; - - glitz_egl_screen_info_t *screen_info; - glitz_egl_context_t *context; - EGLSurface egl_surface; + glitz_drawable_t base; + + glitz_egl_screen_info_t *screen_info; + glitz_egl_context_t *context; + EGLSurface egl_surface; + int width; + int height; }; extern void __internal_linkage glitz_egl_query_extensions (glitz_egl_screen_info_t *screen_info, - glitz_gl_float_t egl_version); + glitz_gl_float_t egl_version); extern glitz_egl_screen_info_t __internal_linkage * glitz_egl_screen_info_get (EGLDisplay egl_display, - EGLScreenMESA egl_screen); + EGLScreenMESA egl_screen); extern glitz_function_pointer_t __internal_linkage glitz_egl_get_proc_address (const char *name, - void *closure); + void *closure); extern glitz_egl_context_t __internal_linkage * glitz_egl_context_get (glitz_egl_screen_info_t *screen_info, - glitz_drawable_format_t *format); + glitz_drawable_format_t *format); extern void __internal_linkage glitz_egl_context_destroy (glitz_egl_screen_info_t *screen_info, - glitz_egl_context_t *context); + glitz_egl_context_t *context); extern void __internal_linkage glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info); +extern glitz_bool_t __internal_linkage +_glitz_egl_drawable_update_size (glitz_egl_surface_t *drawable, + int width, + int height); + extern EGLSurface __internal_linkage glitz_egl_pbuffer_create (glitz_egl_screen_info_t *screen_info, - EGLConfig egl_config, - int width, - int height); + EGLConfig egl_config, + int width, + int height); extern void __internal_linkage glitz_egl_pbuffer_destroy (glitz_egl_screen_info_t *screen_info, - EGLSurface egl_pbuffer); + EGLSurface egl_pbuffer); extern glitz_drawable_t __internal_linkage * glitz_egl_create_pbuffer (void *abstract_templ, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height); + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); -extern void __internal_linkage +extern glitz_bool_t __internal_linkage glitz_egl_push_current (void *abstract_drawable, - glitz_surface_t *surface, - glitz_constraint_t constraint); + glitz_surface_t *surface, + glitz_constraint_t constraint); extern glitz_surface_t __internal_linkage * glitz_egl_pop_current (void *abstract_drawable); void glitz_egl_make_current (void *abstract_drawable, - glitz_constraint_t constraint); + glitz_constraint_t constraint); extern glitz_status_t __internal_linkage glitz_egl_make_current_read (void *abstract_surface); @@ -157,14 +158,15 @@ glitz_egl_make_current_read (void *abstract_surface); extern void __internal_linkage glitz_egl_destroy (void *abstract_drawable); -extern void __internal_linkage +extern glitz_bool_t __internal_linkage glitz_egl_swap_buffers (void *abstract_drawable); -/* Avoid unnecessary PLT entries. */ +/* Avoid unnecessary PLT entries. */ slim_hidden_proto(glitz_egl_init) slim_hidden_proto(glitz_egl_fini) -slim_hidden_proto(glitz_egl_find_config) +slim_hidden_proto(glitz_egl_find_window_config) +slim_hidden_proto(glitz_egl_find_pbuffer_config) slim_hidden_proto(glitz_egl_create_surface) slim_hidden_proto(glitz_egl_create_pbuffer_surface) diff --git a/src/glitz.c b/src/glitz.c index 7bdaade..dbe2ba2 100644 --- a/src/glitz.c +++ b/src/glitz.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -43,25 +43,26 @@ typedef struct _glitz_texture_unit_t { void glitz_composite (glitz_operator_t op, - glitz_surface_t *src, - glitz_surface_t *mask, - glitz_surface_t *dst, - int x_src, - int y_src, - int x_mask, - int y_mask, - int x_dst, - int y_dst, - int width, - int height) + glitz_surface_t *src, + glitz_surface_t *mask, + glitz_surface_t *dst, + int x_src, + int y_src, + int x_mask, + int y_mask, + int x_dst, + int y_dst, + int width, + int height) { - glitz_composite_op_t comp_op; - int i, texture_nr = -1; - glitz_texture_t *stexture, *mtexture; - glitz_texture_unit_t textures[3]; - glitz_box_t bounds; - glitz_bool_t no_border_clamp; - unsigned long flags; + glitz_composite_op_t comp_op; + int i, texture_nr = -1; + glitz_texture_t *stexture, *mtexture; + glitz_texture_unit_t textures[3]; + glitz_texture_parameters_t param; + glitz_box_t bounds; + glitz_bool_t no_border_clamp; + unsigned long flags; GLITZ_GL_SURFACE (dst); @@ -69,279 +70,286 @@ glitz_composite (glitz_operator_t op, bounds.y1 = MAX (y_dst, 0); bounds.x2 = x_dst + width; bounds.y2 = y_dst + height; - + if (bounds.x2 > dst->box.x2) - bounds.x2 = dst->box.x2; + bounds.x2 = dst->box.x2; if (bounds.y2 > dst->box.y2) - bounds.y2 = dst->box.y2; + bounds.y2 = dst->box.y2; if (bounds.x1 >= bounds.x2 || bounds.y1 >= bounds.y2) - return; + return; if (dst->geometry.buffer && (!dst->geometry.count)) - return; - + return; + glitz_composite_op_init (&comp_op, op, src, mask, dst); if (comp_op.type == GLITZ_COMBINE_TYPE_NA) { - glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK); - return; + glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK); + return; } src = comp_op.src; mask = comp_op.mask; + param.border_color.red = param.border_color.green = + param.border_color.blue = param.border_color.alpha = 0; + if (src) { - stexture = glitz_surface_get_texture (src, 0); - if (!stexture) - return; + stexture = glitz_surface_get_texture (src, 0); + if (!stexture) + return; } else - stexture = NULL; + stexture = NULL; if (mask) { - mtexture = glitz_surface_get_texture (mask, 0); - if (!mtexture) - return; + mtexture = glitz_surface_get_texture (mask, 0); + if (!mtexture) + return; } else - mtexture = NULL; + mtexture = NULL; if (!glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) { - glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK); - glitz_surface_pop_current (dst); - return; + glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK); + glitz_surface_pop_current (dst); + return; } - + no_border_clamp = !(dst->drawable->backend->feature_mask & - GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK); + GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK); if (mtexture) { - textures[0].texture = mtexture; - textures[0].unit = _texture_units[0]; - textures[0].transform = 0; - texture_nr = 0; - - glitz_texture_bind (gl, mtexture); - - flags = mask->flags | GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK; - if (dst->geometry.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) - { - flags &= ~GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK; - - if (dst->geometry.u.v.mask.size == 2) - flags &= ~GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK; - } - - glitz_texture_set_tex_gen (gl, - mtexture, - &dst->geometry, - x_dst - x_mask, - y_dst - y_mask, - flags, - &dst->geometry.u.v.mask); - - if (mask->transform) - { - textures[0].transform = 1; - gl->matrix_mode (GLITZ_GL_TEXTURE); - gl->load_matrix_f (SURFACE_EYE_COORDS (mask)? - mask->transform->m: mask->transform->t); - gl->matrix_mode (GLITZ_GL_MODELVIEW); - - if (SURFACE_LINEAR_TRANSFORM_FILTER (mask)) - glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_LINEAR); - else - glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_NEAREST); - } - else - { - if ((dst->geometry.attributes & - GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) && - SURFACE_LINEAR_TRANSFORM_FILTER (mask)) - glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_LINEAR); - else - glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_NEAREST); - } - - if (SURFACE_REPEAT (mask)) - { - if (SURFACE_MIRRORED (mask)) - glitz_texture_ensure_wrap (gl, mtexture, - GLITZ_GL_MIRRORED_REPEAT); - else - glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_REPEAT); - } - else - { - if (no_border_clamp || SURFACE_PAD (mask)) - glitz_texture_ensure_wrap (gl, mtexture, - GLITZ_GL_CLAMP_TO_EDGE); - else - glitz_texture_ensure_wrap (gl, mtexture, - GLITZ_GL_CLAMP_TO_BORDER); - } + textures[0].texture = mtexture; + textures[0].unit = _texture_units[0]; + textures[0].transform = 0; + texture_nr = 0; + + glitz_texture_bind (gl, mtexture); + + flags = mask->flags | GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK; + if (dst->geometry.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) + { + flags &= ~GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK; + + if (dst->geometry.u.v.mask.size == 2) + flags &= ~GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK; + } + + glitz_texture_set_tex_gen (gl, + mtexture, + &dst->geometry, + x_dst - x_mask, + y_dst - y_mask, + flags, + &dst->geometry.u.v.mask); + + if (mask->transform) + { + textures[0].transform = 1; + gl->matrix_mode (GLITZ_GL_TEXTURE); + gl->load_matrix_f (SURFACE_EYE_COORDS (mask)? + mask->transform->m: mask->transform->t); + gl->matrix_mode (GLITZ_GL_MODELVIEW); + + if (SURFACE_LINEAR_TRANSFORM_FILTER (mask)) + param.filter[0] = GLITZ_GL_LINEAR; + else + param.filter[0] = GLITZ_GL_NEAREST; + } + else + { + if ((dst->geometry.attributes & + GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) && + SURFACE_LINEAR_TRANSFORM_FILTER (mask)) + param.filter[0] = GLITZ_GL_LINEAR; + else + param.filter[0] = GLITZ_GL_NEAREST; + } + + if (SURFACE_REPEAT (mask)) + { + if (SURFACE_MIRRORED (mask)) + param.wrap[0] = GLITZ_GL_MIRRORED_REPEAT; + else + param.wrap[0] = GLITZ_GL_REPEAT; + } + else + { + if (no_border_clamp || SURFACE_PAD (mask)) + param.wrap[0] = GLITZ_GL_CLAMP_TO_EDGE; + else + param.wrap[0] = GLITZ_GL_CLAMP_TO_BORDER; + } + + param.filter[1] = param.filter[0]; + param.wrap[1] = param.wrap[0]; + + glitz_texture_ensure_parameters (gl, mtexture, ¶m); } - + if (stexture) { - int last_texture_nr = comp_op.combine->texture_units - 1; - - while (texture_nr < last_texture_nr) - { - textures[++texture_nr].texture = stexture; - textures[texture_nr].unit = _texture_units[texture_nr]; - textures[texture_nr].transform = 0; - if (texture_nr > 0) - { - gl->active_texture (textures[texture_nr].unit); - gl->client_active_texture (textures[texture_nr].unit); - } - glitz_texture_bind (gl, stexture); - } - - flags = src->flags | GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK; - if (dst->geometry.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) - { - flags &= ~GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK; - - if (dst->geometry.u.v.src.size == 2) - flags &= ~GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK; - } - - glitz_texture_set_tex_gen (gl, - stexture, - &dst->geometry, - x_dst - x_src, - y_dst - y_src, - flags, - &dst->geometry.u.v.src); - - if (src->transform) - { - textures[texture_nr].transform = 1; - gl->matrix_mode (GLITZ_GL_TEXTURE); - gl->load_matrix_f (SURFACE_EYE_COORDS (src)? - src->transform->m: src->transform->t); - gl->matrix_mode (GLITZ_GL_MODELVIEW); - - if (SURFACE_LINEAR_TRANSFORM_FILTER (src)) - glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_LINEAR); - else - glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_NEAREST); - } - else - { - if ((dst->geometry.attributes & - GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) && - SURFACE_LINEAR_TRANSFORM_FILTER (src)) - glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_LINEAR); - else - glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_NEAREST); - } - - if (SURFACE_REPEAT (src)) - { - if (SURFACE_MIRRORED (src)) - glitz_texture_ensure_wrap (gl, stexture, - GLITZ_GL_MIRRORED_REPEAT); - else - glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_REPEAT); - } - else - { - if (no_border_clamp || SURFACE_PAD (src)) - glitz_texture_ensure_wrap (gl, stexture, - GLITZ_GL_CLAMP_TO_EDGE); - else - glitz_texture_ensure_wrap (gl, stexture, - GLITZ_GL_CLAMP_TO_BORDER); - } + int last_texture_nr = comp_op.combine->texture_units - 1; + + while (texture_nr < last_texture_nr) + { + textures[++texture_nr].texture = stexture; + textures[texture_nr].unit = _texture_units[texture_nr]; + textures[texture_nr].transform = 0; + if (texture_nr > 0) + { + gl->active_texture (textures[texture_nr].unit); + gl->client_active_texture (textures[texture_nr].unit); + } + glitz_texture_bind (gl, stexture); + } + + flags = src->flags | GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK; + if (dst->geometry.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) + { + flags &= ~GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK; + + if (dst->geometry.u.v.src.size == 2) + flags &= ~GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK; + } + + glitz_texture_set_tex_gen (gl, + stexture, + &dst->geometry, + x_dst - x_src, + y_dst - y_src, + flags, + &dst->geometry.u.v.src); + + if (src->transform) + { + textures[texture_nr].transform = 1; + gl->matrix_mode (GLITZ_GL_TEXTURE); + gl->load_matrix_f (SURFACE_EYE_COORDS (src)? + src->transform->m: src->transform->t); + gl->matrix_mode (GLITZ_GL_MODELVIEW); + + if (SURFACE_LINEAR_TRANSFORM_FILTER (src)) + param.filter[0] = GLITZ_GL_LINEAR; + else + param.filter[0] = GLITZ_GL_NEAREST; + } + else + { + if ((dst->geometry.attributes & + GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) && + SURFACE_LINEAR_TRANSFORM_FILTER (src)) + param.filter[0] = GLITZ_GL_LINEAR; + else + param.filter[0] = GLITZ_GL_NEAREST; + } + + if (SURFACE_REPEAT (src)) + { + if (SURFACE_MIRRORED (src)) + param.wrap[0] = GLITZ_GL_MIRRORED_REPEAT; + else + param.wrap[0] = GLITZ_GL_REPEAT; + } + else + { + if (no_border_clamp || SURFACE_PAD (src)) + param.wrap[0] = GLITZ_GL_CLAMP_TO_EDGE; + else + param.wrap[0] = GLITZ_GL_CLAMP_TO_BORDER; + } + + param.filter[1] = param.filter[0]; + param.wrap[1] = param.wrap[0]; + + glitz_texture_ensure_parameters (gl, stexture, ¶m); } glitz_geometry_enable (gl, dst, &bounds); if (comp_op.per_component) { - static unsigned short alpha_map[4][4] = { - { 0, 0, 0, 1 }, - { 0, 0, 1, 0 }, - { 0, 1, 0, 0 }, - { 1, 0, 0, 0 } - }; - static int damage[4] = { - GLITZ_DAMAGE_TEXTURE_MASK | GLITZ_DAMAGE_SOLID_MASK, - 0, - 0, - 0 - }; - glitz_color_t alpha = comp_op.alpha_mask; - int component = 4; - int cmask = 1; - - while (component--) - { - comp_op.alpha_mask.red = alpha_map[component][0] * alpha.red; - comp_op.alpha_mask.green = alpha_map[component][1] * alpha.green; - comp_op.alpha_mask.blue = alpha_map[component][2] * alpha.blue; - comp_op.alpha_mask.alpha = alpha_map[component][3] * alpha.alpha; - - gl->color_mask ((cmask & 1) , - (cmask & 2) >> 1, - (cmask & 4) >> 2, - (cmask & 8) >> 3); - - glitz_composite_enable (&comp_op); - glitz_geometry_draw_arrays (gl, dst, - dst->geometry.type, &bounds, - damage[component]); - cmask <<= 1; - } - - gl->color_mask (1, 1, 1, 1); + static unsigned short alpha_map[4][4] = { + { 0, 0, 0, 1 }, + { 0, 0, 1, 0 }, + { 0, 1, 0, 0 }, + { 1, 0, 0, 0 } + }; + static int damage[4] = { + GLITZ_DAMAGE_TEXTURE_MASK | GLITZ_DAMAGE_SOLID_MASK, + 0, + 0, + 0 + }; + glitz_color_t alpha = comp_op.alpha_mask; + int component = 4; + int cmask = 1; + + while (component--) + { + comp_op.alpha_mask.red = alpha_map[component][0] * alpha.red; + comp_op.alpha_mask.green = alpha_map[component][1] * alpha.green; + comp_op.alpha_mask.blue = alpha_map[component][2] * alpha.blue; + comp_op.alpha_mask.alpha = alpha_map[component][3] * alpha.alpha; + + gl->color_mask ((cmask & 1) , + (cmask & 2) >> 1, + (cmask & 4) >> 2, + (cmask & 8) >> 3); + + glitz_composite_enable (&comp_op); + glitz_geometry_draw_arrays (gl, dst, + dst->geometry.type, &bounds, + damage[component]); + cmask <<= 1; + } + + gl->color_mask (1, 1, 1, 1); } else { - glitz_composite_enable (&comp_op); - glitz_geometry_draw_arrays (gl, dst, dst->geometry.type, &bounds, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_SOLID_MASK); + glitz_composite_enable (&comp_op); + glitz_geometry_draw_arrays (gl, dst, dst->geometry.type, &bounds, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); } - + glitz_composite_disable (&comp_op); glitz_geometry_disable (dst); for (i = texture_nr; i >= 0; i--) { - glitz_texture_unbind (gl, textures[i].texture); - if (textures[i].transform) - { - gl->matrix_mode (GLITZ_GL_TEXTURE); - gl->load_identity (); - gl->matrix_mode (GLITZ_GL_MODELVIEW); - } - - if (i > 0) - { - gl->client_active_texture (textures[i - 1].unit); - gl->active_texture (textures[i - 1].unit); - } + glitz_texture_unbind (gl, textures[i].texture); + if (textures[i].transform) + { + gl->matrix_mode (GLITZ_GL_TEXTURE); + gl->load_identity (); + gl->matrix_mode (GLITZ_GL_MODELVIEW); + } + + if (i > 0) + { + gl->client_active_texture (textures[i - 1].unit); + gl->active_texture (textures[i - 1].unit); + } } - + glitz_surface_pop_current (dst); } void glitz_copy_area (glitz_surface_t *src, - glitz_surface_t *dst, - int x_src, - int y_src, - int width, - int height, - int x_dst, - int y_dst) + glitz_surface_t *dst, + int x_src, + int y_src, + int width, + int height, + int x_dst, + int y_dst) { glitz_status_t status; glitz_box_t bounds; @@ -352,289 +360,302 @@ glitz_copy_area (glitz_surface_t *src, if (x_src < 0) { - bounds.x1 = x_dst - x_src; - width += x_src; + bounds.x1 = x_dst - x_src; + width += x_src; } else { - bounds.x1 = x_dst; - src_width -= x_src; + bounds.x1 = x_dst; + src_width -= x_src; } - + if (y_src < 0) { - bounds.y1 = y_dst - y_src; - height += y_src; + bounds.y1 = y_dst - y_src; + height += y_src; } else { - bounds.y1 = y_dst; - src_height -= y_src; + bounds.y1 = y_dst; + src_height -= y_src; } - + if (width > src_width) - bounds.x2 = bounds.x1 + src_width; + bounds.x2 = bounds.x1 + src_width; else - bounds.x2 = bounds.x1 + width; - + bounds.x2 = bounds.x1 + width; + if (height > src_height) - bounds.y2 = bounds.y1 + src_height; + bounds.y2 = bounds.y1 + src_height; else - bounds.y2 = bounds.y1 + height; + bounds.y2 = bounds.y1 + height; if (bounds.x1 < 0) - bounds.x1 = 0; + bounds.x1 = 0; if (bounds.y1 < 0) - bounds.y1 = 0; + bounds.y1 = 0; if (bounds.x2 > dst->box.x2) - bounds.x2 = dst->box.x2; + bounds.x2 = dst->box.x2; if (bounds.y2 > dst->box.y2) - bounds.y2 = dst->box.y2; + bounds.y2 = dst->box.y2; if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) - return; - + return; + status = GLITZ_STATUS_NOT_SUPPORTED; - if (glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) + if ((!src->attached) || + (src->attached == dst->attached) || + (dst->box.x2 * dst->box.y2 >= src->box.x2 * src->box.y2)) { - int target_height = SURFACE_DRAWABLE_HEIGHT (dst); - int source_height = SURFACE_DRAWABLE_HEIGHT (src); - - if (src == dst || (dst->attached && src->attached == dst->attached)) - { - glitz_box_t box, *clip = dst->clip; - int n_clip = dst->n_clip; - - if (REGION_NOTEMPTY (&src->drawable_damage)) - { - glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT); - glitz_surface_pop_current (src); - } - - gl->read_buffer (src->buffer); - gl->draw_buffer (dst->buffer); - - glitz_set_operator (gl, GLITZ_OPERATOR_SRC); - - x_src += src->x; - y_src += src->y; - - while (n_clip--) - { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (bounds.x1 > box.x1) - box.x1 = bounds.x1; - if (bounds.y1 > box.y1) - box.y1 = bounds.y1; - if (bounds.x2 < box.x2) - box.x2 = bounds.x2; - if (bounds.y2 < box.y2) - box.y2 = bounds.y2; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - glitz_set_raster_pos (gl, - dst->x + box.x1, - target_height - (dst->y + box.y2)); - - gl->scissor (dst->x + box.x1, - target_height - (dst->y + box.y2), - box.x2 - box.x1, - box.y2 - box.y1); - - gl->copy_pixels (x_src + (box.x1 - x_dst), - source_height - - (y_src + (box.y2 - y_dst)), - box.x2 - box.x1, box.y2 - box.y1, - GLITZ_GL_COLOR); - - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_SOLID_MASK); - } - - clip++; - } - } - else - { - glitz_texture_t *texture; - - texture = glitz_surface_get_texture (src, 0); - if (texture) - { - glitz_texture_bind (gl, texture); - - glitz_texture_set_tex_gen (gl, texture, NULL, - x_dst - x_src, - y_dst - y_src, - GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK, - NULL); - - gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); - gl->color_4us (0x0, 0x0, 0x0, 0xffff); - - glitz_texture_ensure_wrap (gl, texture, - GLITZ_GL_CLAMP_TO_EDGE); - glitz_texture_ensure_filter (gl, texture, GLITZ_GL_NEAREST); - - glitz_set_operator (gl, GLITZ_OPERATOR_SRC); - - if (dst->n_clip > 1) - { - glitz_float_t *data; - void *ptr; - int vertices = 0; - glitz_box_t box, *clip = dst->clip; - int n_clip = dst->n_clip; - - ptr = malloc (n_clip * 8 * sizeof (glitz_float_t)); - if (!ptr) { - glitz_surface_pop_current (dst); - glitz_surface_status_add (dst, - GLITZ_STATUS_NO_MEMORY_MASK); - return; - } - - data = (glitz_float_t *) ptr; - - while (n_clip--) - { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (bounds.x1 > box.x1) - box.x1 = bounds.x1; - if (bounds.y1 > box.y1) - box.y1 = bounds.y1; - if (bounds.x2 < box.x2) - box.x2 = bounds.x2; - if (bounds.y2 < box.y2) - box.y2 = bounds.y2; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - *data++ = (glitz_float_t) box.x1; - *data++ = (glitz_float_t) box.y1; - *data++ = (glitz_float_t) box.x2; - *data++ = (glitz_float_t) box.y1; - *data++ = (glitz_float_t) box.x2; - *data++ = (glitz_float_t) box.y2; - *data++ = (glitz_float_t) box.x1; - *data++ = (glitz_float_t) box.y2; - - vertices += 4; - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_SOLID_MASK); - } - - clip++; - } - - if (vertices) - { - gl->scissor (bounds.x1 + dst->x, - (target_height - dst->y) - bounds.y2, - bounds.x2 - bounds.x1, - bounds.y2 - bounds.y1); - - gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr); - gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices); - } - - free (ptr); - } - else - { - glitz_geometry_enable_none (gl, dst, &bounds); - glitz_geometry_draw_arrays (gl, dst, - GLITZ_GEOMETRY_TYPE_NONE, - &bounds, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_SOLID_MASK); - } - - glitz_texture_unbind (gl, texture); - } - } - - status = GLITZ_STATUS_SUCCESS; + if (glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) + { + int target_height = dst->attached->height; + + if (src->attached == dst->attached) + { + glitz_box_t box, *clip = dst->clip; + int n_clip = dst->n_clip; + + if (REGION_NOTEMPTY (&src->drawable_damage)) + { + glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT); + glitz_surface_pop_current (src); + } + + gl->read_buffer (src->buffer); + gl->draw_buffer (dst->buffer); + + glitz_set_operator (gl, GLITZ_OPERATOR_SRC); + + x_src += src->x; + y_src += src->y; + + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds.x1 > box.x1) + box.x1 = bounds.x1; + if (bounds.y1 > box.y1) + box.y1 = bounds.y1; + if (bounds.x2 < box.x2) + box.x2 = bounds.x2; + if (bounds.y2 < box.y2) + box.y2 = bounds.y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + glitz_set_raster_pos (gl, + dst->x + box.x1, + target_height - (dst->y + box.y2)); + + gl->scissor (dst->x + box.x1, + target_height - (dst->y + box.y2), + box.x2 - box.x1, + box.y2 - box.y1); + + gl->copy_pixels (x_src + (box.x1 - x_dst), + target_height - + (y_src + (box.y2 - y_dst)), + box.x2 - box.x1, box.y2 - box.y1, + GLITZ_GL_COLOR); + + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + clip++; + } + } + else + { + glitz_texture_t *texture; + + texture = glitz_surface_get_texture (src, 0); + if (texture) + { + glitz_texture_parameters_t param; + unsigned long mask; + + mask = GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK; + + glitz_texture_bind (gl, texture); + + glitz_texture_set_tex_gen (gl, texture, NULL, + x_dst - x_src, + y_dst - y_src, + mask, + NULL); + + gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, + GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_REPLACE); + + gl->color_4us (0x0, 0x0, 0x0, 0xffff); + + param.filter[0] = param.filter[1] = GLITZ_GL_CLAMP_TO_EDGE; + param.wrap[0] = param.wrap[1] = GLITZ_GL_NEAREST; + + glitz_texture_ensure_parameters (gl, texture, ¶m); + + glitz_set_operator (gl, GLITZ_OPERATOR_SRC); + + if (dst->n_clip > 1) + { + glitz_float_t *data; + void *ptr; + int vertices = 0; + glitz_box_t box, *clip = dst->clip; + int n_clip = dst->n_clip; + + ptr = malloc (n_clip * 8 * sizeof (glitz_float_t)); + if (!ptr) + { + mask = GLITZ_STATUS_NO_MEMORY_MASK; + glitz_surface_pop_current (dst); + glitz_surface_status_add (dst, mask); + return; + } + + data = (glitz_float_t *) ptr; + + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds.x1 > box.x1) + box.x1 = bounds.x1; + if (bounds.y1 > box.y1) + box.y1 = bounds.y1; + if (bounds.x2 < box.x2) + box.x2 = bounds.x2; + if (bounds.y2 < box.y2) + box.y2 = bounds.y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + *data++ = (glitz_float_t) box.x1; + *data++ = (glitz_float_t) box.y1; + *data++ = (glitz_float_t) box.x2; + *data++ = (glitz_float_t) box.y1; + *data++ = (glitz_float_t) box.x2; + *data++ = (glitz_float_t) box.y2; + *data++ = (glitz_float_t) box.x1; + *data++ = (glitz_float_t) box.y2; + + vertices += 4; + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + clip++; + } + + if (vertices) + { + gl->scissor (bounds.x1 + dst->x, + (target_height - dst->y) - bounds.y2, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + + gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr); + gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices); + } + + free (ptr); + } + else + { + glitz_geometry_enable_none (gl, dst, &bounds); + glitz_geometry_draw_arrays (gl, dst, + GLITZ_GEOMETRY_TYPE_NONE, + &bounds, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + glitz_texture_unbind (gl, texture); + } + } + + status = GLITZ_STATUS_SUCCESS; + } + + glitz_surface_pop_current (dst); } - glitz_surface_pop_current (dst); - - if (status && src->attached) + if (status) { - if (glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT)) - { - glitz_texture_t *texture; - - gl->read_buffer (src->buffer); - - texture = glitz_surface_get_texture (dst, 1); - if (texture) - { - glitz_box_t box, *clip = dst->clip; - int n_clip = dst->n_clip; - - gl->disable (GLITZ_GL_SCISSOR_TEST); - - glitz_texture_bind (gl, texture); - - x_src += src->x; - y_src += src->y; - - while (n_clip--) - { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (bounds.x1 > box.x1) - box.x1 = bounds.x1; - if (bounds.y1 > box.y1) - box.y1 = bounds.y1; - if (bounds.x2 < box.x2) - box.x2 = bounds.x2; - if (bounds.y2 < box.y2) - box.y2 = bounds.y2; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - glitz_texture_copy_drawable (gl, - texture, - src->attached, - x_src + (box.x1 - x_dst), - y_src + (box.y1 - y_dst), - box.x2 - box.x1, - box.y2 - box.y1, - box.x1, - box.y1); - - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_DRAWABLE_MASK | - GLITZ_DAMAGE_SOLID_MASK); - } - - clip++; - } - - glitz_texture_unbind (gl, texture); - - gl->enable (GLITZ_GL_SCISSOR_TEST); - - status = GLITZ_STATUS_SUCCESS; - } - } - glitz_surface_pop_current (src); + if (glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT)) + { + glitz_texture_t *texture; + + gl->read_buffer (src->buffer); + + texture = glitz_surface_get_texture (dst, 1); + if (texture) + { + glitz_box_t box, *clip = dst->clip; + int n_clip = dst->n_clip; + + gl->disable (GLITZ_GL_SCISSOR_TEST); + + glitz_texture_bind (gl, texture); + + x_src += src->x; + y_src += src->y; + + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds.x1 > box.x1) + box.x1 = bounds.x1; + if (bounds.y1 > box.y1) + box.y1 = bounds.y1; + if (bounds.x2 < box.x2) + box.x2 = bounds.x2; + if (bounds.y2 < box.y2) + box.y2 = bounds.y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + glitz_texture_copy_drawable (gl, + texture, + src->attached, + x_src + (box.x1 - x_dst), + y_src + (box.y1 - y_dst), + box.x2 - box.x1, + box.y2 - box.y1, + box.x1, + box.y1); + + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_DRAWABLE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + clip++; + } + + glitz_texture_unbind (gl, texture); + + gl->enable (GLITZ_GL_SCISSOR_TEST); + + status = GLITZ_STATUS_SUCCESS; + } + } + glitz_surface_pop_current (src); } if (status) - glitz_surface_status_add (dst, glitz_status_to_status_mask (status)); + glitz_surface_status_add (dst, glitz_status_to_status_mask (status)); } diff --git a/src/glitz.h b/src/glitz.h index 53dbcec..f07d5d1 100644 --- a/src/glitz.h +++ b/src/glitz.h @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -37,8 +37,8 @@ #endif #define GLITZ_MAJOR 0 -#define GLITZ_MINOR 4 -#define GLITZ_REVISION 4 +#define GLITZ_MINOR 5 +#define GLITZ_REVISION 0 #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -51,6 +51,9 @@ typedef float glitz_float_t; typedef double glitz_double_t; typedef int glitz_fixed16_16_t; +typedef struct _glitz_drawable glitz_drawable_t; +typedef struct _glitz_surface glitz_surface_t; + typedef struct _glitz_rectangle_t { short x, y; unsigned short width, height; @@ -78,7 +81,7 @@ typedef struct _glitz_trapezoid_t { typedef struct _glitz_span_fixed_t { glitz_fixed16_16_t left, right, y; } glitz_span_fixed_t; - + typedef struct _glitz_trap_t { glitz_span_fixed_t top, bottom; } glitz_trap_t; @@ -93,7 +96,7 @@ typedef struct { unsigned short blue; unsigned short alpha; } glitz_color_t; - + typedef enum { GLITZ_FILTER_NEAREST, GLITZ_FILTER_BILINEAR, @@ -137,13 +140,16 @@ typedef enum { #define GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK (1L << 15) #define GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK (1L << 16) + +/* glitz_format.c */ + typedef enum { GLITZ_STANDARD_ARGB32, GLITZ_STANDARD_RGB24, GLITZ_STANDARD_A8, GLITZ_STANDARD_A1 } glitz_format_name_t; - + #define GLITZ_FORMAT_ID_MASK (1L << 0) #define GLITZ_FORMAT_RED_SIZE_MASK (1L << 1) #define GLITZ_FORMAT_GREEN_SIZE_MASK (1L << 2) @@ -159,9 +165,57 @@ typedef struct _glitz_color_format_t { unsigned short alpha_size; } glitz_color_format_t; - +#define GLITZ_FORMAT_DEPTH_SIZE_MASK (1L << 5) +#define GLITZ_FORMAT_STENCIL_SIZE_MASK (1L << 6) +#define GLITZ_FORMAT_DOUBLEBUFFER_MASK (1L << 7) +#define GLITZ_FORMAT_SAMPLES_MASK (1L << 8) + +typedef struct _glitz_drawable_format_t { + glitz_format_id_t id; + glitz_color_format_t color; + unsigned short depth_size; + unsigned short stencil_size; + unsigned short samples; + glitz_bool_t doublebuffer; +} glitz_drawable_format_t; + +#define GLITZ_FORMAT_TYPE_MASK (1L << 5) + +typedef enum { + GLITZ_FORMAT_TYPE_COLOR +} glitz_format_type_t; + +typedef struct _glitz_format_t { + glitz_format_id_t id; + glitz_format_type_t type; + glitz_color_format_t color; +} glitz_format_t; + +glitz_format_t * +glitz_find_standard_format (glitz_drawable_t *drawable, + glitz_format_name_t format_name); + +glitz_format_t * +glitz_find_format (glitz_drawable_t *drawable, + unsigned long mask, + const glitz_format_t *templ, + int count); + +glitz_drawable_format_t * +glitz_find_drawable_format (glitz_drawable_t *other, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count); + +glitz_drawable_format_t * +glitz_find_pbuffer_format (glitz_drawable_t *other, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count); + + /* glitz_status.c */ - + typedef enum { GLITZ_STATUS_SUCCESS = 0, GLITZ_STATUS_NO_MEMORY, @@ -176,46 +230,22 @@ glitz_status_string (glitz_status_t status); /* glitz_drawable.c */ -typedef struct _glitz_drawable glitz_drawable_t; - typedef enum { GLITZ_DRAWABLE_BUFFER_FRONT_COLOR, GLITZ_DRAWABLE_BUFFER_BACK_COLOR } glitz_drawable_buffer_t; - -#define GLITZ_FORMAT_DEPTH_SIZE_MASK (1L << 5) -#define GLITZ_FORMAT_STENCIL_SIZE_MASK (1L << 6) -#define GLITZ_FORMAT_DOUBLEBUFFER_MASK (1L << 7) -#define GLITZ_FORMAT_SAMPLES_MASK (1L << 8) -#define GLITZ_FORMAT_WINDOW_MASK (1L << 9) -#define GLITZ_FORMAT_PBUFFER_MASK (1L << 10) - -typedef struct _glitz_drawable_types_t { - glitz_bool_t window; - glitz_bool_t pbuffer; -} glitz_drawable_types_t; -typedef struct _glitz_drawable_format_t { - glitz_format_id_t id; - glitz_color_format_t color; - unsigned short depth_size; - unsigned short stencil_size; - unsigned short samples; - glitz_bool_t doublebuffer; - glitz_drawable_types_t types; -} glitz_drawable_format_t; +glitz_drawable_t * +glitz_create_drawable (glitz_drawable_t *other, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); -glitz_drawable_format_t * -glitz_find_similar_drawable_format (glitz_drawable_t *other, - unsigned long mask, - const glitz_drawable_format_t *templ, - int count); - glitz_drawable_t * glitz_create_pbuffer_drawable (glitz_drawable_t *other, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height); + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); void glitz_drawable_destroy (glitz_drawable_t *drawable); @@ -225,8 +255,8 @@ glitz_drawable_reference (glitz_drawable_t *drawable); void glitz_drawable_update_size (glitz_drawable_t *drawable, - unsigned int width, - unsigned int height); + unsigned int width, + unsigned int height); unsigned int glitz_drawable_get_width (glitz_drawable_t *drawable); @@ -235,6 +265,13 @@ unsigned int glitz_drawable_get_height (glitz_drawable_t *drawable); void +glitz_drawable_swap_buffer_region (glitz_drawable_t *drawable, + int x_origin, + int y_origin, + glitz_box_t *box, + int n_box); + +void glitz_drawable_swap_buffers (glitz_drawable_t *drawable); void @@ -249,49 +286,22 @@ glitz_drawable_get_features (glitz_drawable_t *drawable); glitz_drawable_format_t * glitz_drawable_get_format (glitz_drawable_t *drawable); - -/* glitz_format.c */ - -#define GLITZ_FORMAT_TYPE_MASK (1L << 5) - -typedef enum { - GLITZ_FORMAT_TYPE_COLOR -} glitz_format_type_t; - -typedef struct _glitz_format_t { - glitz_format_id_t id; - glitz_format_type_t type; - glitz_color_format_t color; -} glitz_format_t; - -glitz_format_t * -glitz_find_standard_format (glitz_drawable_t *drawable, - glitz_format_name_t format_name); - -glitz_format_t * -glitz_find_format (glitz_drawable_t *drawable, - unsigned long mask, - const glitz_format_t *templ, - int count); - /* glitz_surface.c */ -typedef struct _glitz_surface glitz_surface_t; - #define GLITZ_SURFACE_UNNORMALIZED_MASK (1L << 0) typedef struct _glitz_surface_attributes_t { glitz_bool_t unnormalized; } glitz_surface_attributes_t; - + glitz_surface_t * glitz_surface_create (glitz_drawable_t *drawable, - glitz_format_t *format, - unsigned int width, - unsigned int height, - unsigned long mask, - glitz_surface_attributes_t *attributes); + glitz_format_t *format, + unsigned int width, + unsigned int height, + unsigned long mask, + glitz_surface_attributes_t *attributes); void glitz_surface_destroy (glitz_surface_t *surface); @@ -301,10 +311,8 @@ glitz_surface_reference (glitz_surface_t *surface); void glitz_surface_attach (glitz_surface_t *surface, - glitz_drawable_t *drawable, - glitz_drawable_buffer_t buffer, - int x, - int y); + glitz_drawable_t *drawable, + glitz_drawable_buffer_t buffer); void glitz_surface_detach (glitz_surface_t *surface); @@ -320,7 +328,7 @@ glitz_surface_get_attached_drawable (glitz_surface_t *surface); void glitz_surface_set_transform (glitz_surface_t *surface, - glitz_transform_t *transform); + glitz_transform_t *transform); typedef enum { GLITZ_FILL_TRANSPARENT, @@ -331,21 +339,21 @@ typedef enum { void glitz_surface_set_fill (glitz_surface_t *surface, - glitz_fill_t fill); + glitz_fill_t fill); void glitz_surface_set_component_alpha (glitz_surface_t *surface, - glitz_bool_t component_alpha); + glitz_bool_t component_alpha); void glitz_surface_set_filter (glitz_surface_t *surface, - glitz_filter_t filter, - glitz_fixed16_16_t *params, - int n_params); + glitz_filter_t filter, + glitz_fixed16_16_t *params, + int n_params); void glitz_surface_set_dither (glitz_surface_t *surface, - glitz_bool_t dither); + glitz_bool_t dither); unsigned int glitz_surface_get_width (glitz_surface_t *surface); @@ -361,27 +369,87 @@ glitz_surface_get_format (glitz_surface_t *surface); void glitz_surface_translate_point (glitz_surface_t *surface, - glitz_point_fixed_t *src, - glitz_point_fixed_t *dst); + glitz_point_fixed_t *src, + glitz_point_fixed_t *dst); void glitz_surface_set_clip_region (glitz_surface_t *surface, - int x_origin, - int y_origin, - glitz_box_t *box, - int n_box); + int x_origin, + int y_origin, + glitz_box_t *box, + int n_box); glitz_bool_t glitz_surface_valid_target (glitz_surface_t *surface); +/* glitz_texture.c */ + +typedef struct _glitz_texture_object glitz_texture_object_t; + +glitz_texture_object_t * +glitz_texture_object_create (glitz_surface_t *surface); + +void +glitz_texture_object_destroy (glitz_texture_object_t *texture); + +void +glitz_texture_object_reference (glitz_texture_object_t *texture); + +typedef enum { + GLITZ_TEXTURE_FILTER_TYPE_MAG = 0, + GLITZ_TEXTURE_FILTER_TYPE_MIN = 1 +} glitz_texture_filter_type_t; + +typedef enum { + GLITZ_TEXTURE_FILTER_NEAREST = 0, + GLITZ_TEXTURE_FILTER_LINEAR = 1 +} glitz_texture_filter_t; + +void +glitz_texture_object_set_filter (glitz_texture_object_t *texture, + glitz_texture_filter_type_t type, + glitz_texture_filter_t filter); + +typedef enum { + GLITZ_TEXTURE_WRAP_TYPE_S = 0, + GLITZ_TEXTURE_WRAP_TYPE_T = 1 +} glitz_texture_wrap_type_t; + +typedef enum { + GLITZ_TEXTURE_WRAP_CLAMP = 0, + GLITZ_TEXTURE_WRAP_CLAMP_TO_EDGE = 1, + GLITZ_TEXTURE_WRAP_CLAMP_TO_BORDER = 2, + GLITZ_TEXTURE_WRAP_REPEAT = 3, + GLITZ_TEXTURE_WRAP_MIRRORED_REPEAT = 4 +} glitz_texture_wrap_t; + +void +glitz_texture_object_set_wrap (glitz_texture_object_t *texture, + glitz_texture_wrap_type_t type, + glitz_texture_wrap_t wrap); + +void +glitz_texture_object_set_border_color (glitz_texture_object_t *texture, + glitz_color_t *color); + +typedef enum { + GLITZ_TEXTURE_TARGET_2D = 0, + GLITZ_TEXTURE_TARGET_RECT = 1 +} glitz_texture_target_t; + +glitz_texture_target_t +glitz_texture_object_get_target (glitz_texture_object_t *texture); + + /* glitz_context.c */ typedef struct _glitz_context glitz_context_t; glitz_context_t * glitz_context_create (glitz_drawable_t *drawable, - glitz_drawable_format_t *format); + glitz_drawable_format_t *format); + void glitz_context_destroy (glitz_context_t *context); @@ -390,51 +458,52 @@ glitz_context_reference (glitz_context_t *context); void glitz_context_copy (glitz_context_t *src, - glitz_context_t *dst, - unsigned long mask); + glitz_context_t *dst, + unsigned long mask); typedef void (*glitz_lose_current_function_t) (void *closure); void glitz_context_set_user_data (glitz_context_t *context, - void *closure, - glitz_lose_current_function_t lose_current); + void *closure, + glitz_lose_current_function_t lose_current); typedef void (*glitz_function_pointer_t) (void); glitz_function_pointer_t glitz_context_get_proc_address (glitz_context_t *context, - const char *name); + const char *name); void -glitz_context_make_current (glitz_context_t *context); +glitz_context_make_current (glitz_context_t *context, + glitz_drawable_t *drawable); void -glitz_context_bind_texture (glitz_context_t *context, - glitz_surface_t *surface); +glitz_context_bind_texture (glitz_context_t *context, + glitz_texture_object_t *texture); /* glitz_rect.c */ void glitz_set_rectangle (glitz_surface_t *dst, - const glitz_color_t *color, - int x, - int y, - unsigned int width, - unsigned int height); - + const glitz_color_t *color, + int x, + int y, + unsigned int width, + unsigned int height); + void glitz_set_rectangles (glitz_surface_t *dst, - const glitz_color_t *color, - const glitz_rectangle_t *rects, - int n_rects); + const glitz_color_t *color, + const glitz_rectangle_t *rects, + int n_rects); /* glitz_buffer.c */ typedef struct _glitz_buffer glitz_buffer_t; - + typedef enum { GLITZ_BUFFER_HINT_STREAM_DRAW, GLITZ_BUFFER_HINT_STREAM_READ, @@ -455,19 +524,19 @@ typedef enum { glitz_buffer_t * glitz_vertex_buffer_create (glitz_drawable_t *drawable, - void *data, - unsigned int size, - glitz_buffer_hint_t hint); + void *data, + unsigned int size, + glitz_buffer_hint_t hint); glitz_buffer_t * glitz_pixel_buffer_create (glitz_drawable_t *drawable, - void *data, - unsigned int size, - glitz_buffer_hint_t hint); + void *data, + unsigned int size, + glitz_buffer_hint_t hint); glitz_buffer_t * glitz_buffer_create_for_data (void *data); - + void glitz_buffer_destroy (glitz_buffer_t *buffer); @@ -476,26 +545,26 @@ glitz_buffer_reference (glitz_buffer_t *buffer); void glitz_buffer_set_data (glitz_buffer_t *buffer, - int offset, - unsigned int size, - const void *data); + int offset, + unsigned int size, + const void *data); void glitz_buffer_get_data (glitz_buffer_t *buffer, - int offset, - unsigned int size, - void *data); - + int offset, + unsigned int size, + void *data); + void * glitz_buffer_map (glitz_buffer_t *buffer, - glitz_buffer_access_t access); - + glitz_buffer_access_t access); + glitz_status_t glitz_buffer_unmap (glitz_buffer_t *buffer); - + /* glitz_pixel.c */ - + typedef enum { GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN, GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP @@ -519,23 +588,23 @@ typedef struct _glitz_pixel_format { void glitz_set_pixels (glitz_surface_t *dst, - int x_dst, - int y_dst, - int width, - int height, - glitz_pixel_format_t *format, - glitz_buffer_t *buffer); + int x_dst, + int y_dst, + int width, + int height, + glitz_pixel_format_t *format, + glitz_buffer_t *buffer); void glitz_get_pixels (glitz_surface_t *src, - int x_src, - int y_src, - int width, - int height, - glitz_pixel_format_t *format, - glitz_buffer_t *buffer); - - + int x_src, + int y_src, + int width, + int height, + glitz_pixel_format_t *format, + glitz_buffer_t *buffer); + + /* glitz_geometry.c */ typedef enum { @@ -562,7 +631,7 @@ typedef enum { GLITZ_COORDINATE_SIZE_X, GLITZ_COORDINATE_SIZE_XY } glitz_coordinate_size_t; - + typedef struct _glitz_coordinate_attribute { glitz_data_type_t type; glitz_coordinate_size_t size; @@ -600,17 +669,17 @@ typedef union _glitz_geometry_format { void glitz_set_geometry (glitz_surface_t *dst, - glitz_geometry_type_t type, - glitz_geometry_format_t *format, - glitz_buffer_t *buffer); + glitz_geometry_type_t type, + glitz_geometry_format_t *format, + glitz_buffer_t *buffer); void glitz_set_array (glitz_surface_t *dst, - int first, - int size, - unsigned int count, - glitz_fixed16_16_t x_off, - glitz_fixed16_16_t y_off); + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off); typedef struct _glitz_multi_array glitz_multi_array_t; @@ -625,71 +694,71 @@ glitz_multi_array_reference (glitz_multi_array_t *array); void glitz_multi_array_add (glitz_multi_array_t *array, - int first, - int size, - unsigned int count, - glitz_fixed16_16_t x_off, - glitz_fixed16_16_t y_off); + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off); void glitz_multi_array_reset (glitz_multi_array_t *array); void glitz_set_multi_array (glitz_surface_t *dst, - glitz_multi_array_t *array, - glitz_fixed16_16_t x_off, - glitz_fixed16_16_t y_off); + glitz_multi_array_t *array, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off); /* glitz_trap.c */ int glitz_add_trapezoids (glitz_buffer_t *buffer, - int offset, - unsigned int size, - glitz_data_type_t type, - glitz_surface_t *mask, - glitz_trapezoid_t *traps, - int n_traps, - int *n_added); + int offset, + unsigned int size, + glitz_data_type_t type, + glitz_surface_t *mask, + glitz_trapezoid_t *traps, + int n_traps, + int *n_added); int glitz_add_traps (glitz_buffer_t *buffer, - int offset, - unsigned int size, - glitz_data_type_t type, - glitz_surface_t *mask, - glitz_trap_t *traps, - int n_traps, - int *n_added); + int offset, + unsigned int size, + glitz_data_type_t type, + glitz_surface_t *mask, + glitz_trap_t *traps, + int n_traps, + int *n_added); /* glitz.c */ void glitz_composite (glitz_operator_t op, - glitz_surface_t *src, - glitz_surface_t *mask, - glitz_surface_t *dst, - int x_src, - int y_src, - int x_mask, - int y_mask, - int x_dst, - int y_dst, - int width, - int height); + glitz_surface_t *src, + glitz_surface_t *mask, + glitz_surface_t *dst, + int x_src, + int y_src, + int x_mask, + int y_mask, + int x_dst, + int y_dst, + int width, + int height); void glitz_copy_area (glitz_surface_t *src, - glitz_surface_t *dst, - int x_src, - int y_src, - int width, - int height, - int x_dst, - int y_dst); - + glitz_surface_t *dst, + int x_src, + int y_src, + int width, + int height, + int x_dst, + int y_dst); + #if defined(__cplusplus) || defined(c_plusplus) } #endif diff --git a/src/glitz_buffer.c b/src/glitz_buffer.c index df0561b..bc47310 100644 --- a/src/glitz_buffer.c +++ b/src/glitz_buffer.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,334 +31,335 @@ static glitz_status_t _glitz_buffer_init (glitz_buffer_t *buffer, - glitz_drawable_t *drawable, - void *data, - unsigned int size, - glitz_buffer_hint_t hint) + glitz_drawable_t *drawable, + void *data, + unsigned int size, + glitz_buffer_hint_t hint) { glitz_gl_enum_t usage; - + buffer->ref_count = 1; buffer->name = 0; if (drawable) { - GLITZ_GL_DRAWABLE (drawable); - - switch (hint) { - case GLITZ_BUFFER_HINT_STREAM_DRAW: - usage = GLITZ_GL_STREAM_DRAW; - break; - case GLITZ_BUFFER_HINT_STREAM_READ: - usage = GLITZ_GL_STREAM_READ; - break; - case GLITZ_BUFFER_HINT_STREAM_COPY: - usage = GLITZ_GL_STREAM_COPY; - break; - case GLITZ_BUFFER_HINT_STATIC_DRAW: - usage = GLITZ_GL_STATIC_DRAW; - break; - case GLITZ_BUFFER_HINT_STATIC_READ: - usage = GLITZ_GL_STATIC_READ; - break; - case GLITZ_BUFFER_HINT_STATIC_COPY: - usage = GLITZ_GL_STATIC_COPY; - break; - case GLITZ_BUFFER_HINT_DYNAMIC_DRAW: - usage = GLITZ_GL_DYNAMIC_DRAW; - break; - case GLITZ_BUFFER_HINT_DYNAMIC_READ: - usage = GLITZ_GL_DYNAMIC_READ; - break; - default: - usage = GLITZ_GL_DYNAMIC_COPY; - break; - } - - buffer->owns_data = 1; - buffer->drawable = drawable; - glitz_drawable_reference (drawable); - - drawable->backend->push_current (drawable, NULL, - GLITZ_ANY_CONTEXT_CURRENT); - - gl->gen_buffers (1, &buffer->name); - if (buffer->name) { - gl->bind_buffer (buffer->target, buffer->name); - gl->buffer_data (buffer->target, size, data, usage); - gl->bind_buffer (buffer->target, 0); - } - - drawable->backend->pop_current (drawable); + GLITZ_GL_DRAWABLE (drawable); + + switch (hint) { + case GLITZ_BUFFER_HINT_STREAM_DRAW: + usage = GLITZ_GL_STREAM_DRAW; + break; + case GLITZ_BUFFER_HINT_STREAM_READ: + usage = GLITZ_GL_STREAM_READ; + break; + case GLITZ_BUFFER_HINT_STREAM_COPY: + usage = GLITZ_GL_STREAM_COPY; + break; + case GLITZ_BUFFER_HINT_STATIC_DRAW: + usage = GLITZ_GL_STATIC_DRAW; + break; + case GLITZ_BUFFER_HINT_STATIC_READ: + usage = GLITZ_GL_STATIC_READ; + break; + case GLITZ_BUFFER_HINT_STATIC_COPY: + usage = GLITZ_GL_STATIC_COPY; + break; + case GLITZ_BUFFER_HINT_DYNAMIC_DRAW: + usage = GLITZ_GL_DYNAMIC_DRAW; + break; + case GLITZ_BUFFER_HINT_DYNAMIC_READ: + usage = GLITZ_GL_DYNAMIC_READ; + break; + default: + usage = GLITZ_GL_DYNAMIC_COPY; + break; + } + + buffer->owns_data = 1; + buffer->drawable = drawable; + glitz_drawable_reference (drawable); + + drawable->backend->push_current (drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + + gl->gen_buffers (1, &buffer->name); + if (buffer->name) { + gl->bind_buffer (buffer->target, buffer->name); + gl->buffer_data (buffer->target, size, data, usage); + gl->bind_buffer (buffer->target, 0); + } + + drawable->backend->pop_current (drawable); } else { - buffer->drawable = NULL; - usage = GLITZ_GL_DYNAMIC_COPY; + buffer->drawable = NULL; + usage = GLITZ_GL_DYNAMIC_COPY; } - + if (size > 0 && buffer->name == 0) { - buffer->data = malloc (size); - if (buffer->data == NULL) - return GLITZ_STATUS_NO_MEMORY; - - if (data) - memcpy (buffer->data, data, size); - - buffer->owns_data = 1; + buffer->data = malloc (size); + if (buffer->data == NULL) + return GLITZ_STATUS_NO_MEMORY; + + if (data) + memcpy (buffer->data, data, size); + + buffer->owns_data = 1; } else { - buffer->owns_data = 0; - buffer->data = data; + buffer->owns_data = 0; + buffer->data = data; } - + return GLITZ_STATUS_SUCCESS; } glitz_buffer_t * glitz_vertex_buffer_create (glitz_drawable_t *drawable, - void *data, - unsigned int size, - glitz_buffer_hint_t hint) + void *data, + unsigned int size, + glitz_buffer_hint_t hint) { - glitz_buffer_t *buffer; - glitz_status_t status; - - if (size == 0) - return NULL; - - buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); - if (buffer == NULL) - return NULL; - - buffer->target = GLITZ_GL_ARRAY_BUFFER; - - if (drawable->backend->feature_mask & - GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) - status = _glitz_buffer_init (buffer, drawable, data, size, hint); - else - status = _glitz_buffer_init (buffer, NULL, data, size, hint); - - if (status != GLITZ_STATUS_SUCCESS) { - free (buffer); - return NULL; - } - - return buffer; + glitz_buffer_t *buffer; + glitz_status_t status; + + if (size == 0) + return NULL; + + buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); + if (buffer == NULL) + return NULL; + + buffer->target = GLITZ_GL_ARRAY_BUFFER; + + if (drawable->backend->feature_mask & + GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) + status = _glitz_buffer_init (buffer, drawable, data, size, hint); + else + status = _glitz_buffer_init (buffer, NULL, data, size, hint); + + if (status != GLITZ_STATUS_SUCCESS) { + free (buffer); + return NULL; + } + + return buffer; } glitz_buffer_t * glitz_pixel_buffer_create (glitz_drawable_t *drawable, - void *data, - unsigned int size, - glitz_buffer_hint_t hint) + void *data, + unsigned int size, + glitz_buffer_hint_t hint) { - glitz_buffer_t *buffer; - glitz_status_t status; - - if (size == 0) - return NULL; - - buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); - if (buffer == NULL) - return NULL; - - switch (hint) { - case GLITZ_BUFFER_HINT_STREAM_READ: - case GLITZ_BUFFER_HINT_STATIC_READ: - case GLITZ_BUFFER_HINT_DYNAMIC_READ: - buffer->target = GLITZ_GL_PIXEL_PACK_BUFFER; - break; - default: - buffer->target = GLITZ_GL_PIXEL_UNPACK_BUFFER; - break; - } - - if (drawable->backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK) - status = _glitz_buffer_init (buffer, drawable, data, size, hint); - else - status = _glitz_buffer_init (buffer, NULL, data, size, hint); - - if (status != GLITZ_STATUS_SUCCESS) { - free (buffer); - return NULL; - } - - return buffer; + glitz_buffer_t *buffer; + glitz_status_t status; + + if (size == 0) + return NULL; + + buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); + if (buffer == NULL) + return NULL; + + switch (hint) { + case GLITZ_BUFFER_HINT_STREAM_READ: + case GLITZ_BUFFER_HINT_STATIC_READ: + case GLITZ_BUFFER_HINT_DYNAMIC_READ: + buffer->target = GLITZ_GL_PIXEL_PACK_BUFFER; + break; + default: + buffer->target = GLITZ_GL_PIXEL_UNPACK_BUFFER; + break; + } + + if (drawable->backend->feature_mask & + GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK) + status = _glitz_buffer_init (buffer, drawable, data, size, hint); + else + status = _glitz_buffer_init (buffer, NULL, data, size, hint); + + if (status != GLITZ_STATUS_SUCCESS) { + free (buffer); + return NULL; + } + + return buffer; } glitz_buffer_t * glitz_buffer_create_for_data (void *data) { - glitz_buffer_t *buffer; - - buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); - if (buffer == NULL) - return NULL; + glitz_buffer_t *buffer; - if (_glitz_buffer_init (buffer, NULL, data, 0, 0)) { - free (buffer); - return NULL; - } - - return buffer; + buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); + if (buffer == NULL) + return NULL; + + if (_glitz_buffer_init (buffer, NULL, data, 0, 0)) { + free (buffer); + return NULL; + } + + return buffer; } void glitz_buffer_destroy (glitz_buffer_t *buffer) { - if (!buffer) - return; - - buffer->ref_count--; - if (buffer->ref_count) - return; - - if (buffer->drawable) { - buffer->drawable->backend->push_current (buffer->drawable, NULL, - GLITZ_ANY_CONTEXT_CURRENT); - buffer->drawable->backend->gl.delete_buffers (1, &buffer->name); - buffer->drawable->backend->pop_current (buffer->drawable); - glitz_drawable_destroy (buffer->drawable); - } else if (buffer->owns_data) - free (buffer->data); - - free (buffer); + if (!buffer) + return; + + buffer->ref_count--; + if (buffer->ref_count) + return; + + if (buffer->drawable) { + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + buffer->drawable->backend->gl->delete_buffers (1, &buffer->name); + buffer->drawable->backend->pop_current (buffer->drawable); + glitz_drawable_destroy (buffer->drawable); + } else if (buffer->owns_data) + free (buffer->data); + + free (buffer); } void glitz_buffer_reference (glitz_buffer_t *buffer) { - if (!buffer) - return; + if (!buffer) + return; - buffer->ref_count++; + buffer->ref_count++; } void glitz_buffer_set_data (glitz_buffer_t *buffer, - int offset, - unsigned int size, - const void *data) + int offset, + unsigned int size, + const void *data) { - if (buffer->drawable) { - GLITZ_GL_DRAWABLE (buffer->drawable); - - buffer->drawable->backend->push_current (buffer->drawable, NULL, - GLITZ_ANY_CONTEXT_CURRENT); - gl->bind_buffer (buffer->target, buffer->name); - gl->buffer_sub_data (buffer->target, offset, size, data); - gl->bind_buffer (buffer->target, 0); - buffer->drawable->backend->pop_current (buffer->drawable); - } else if (buffer->data) - memcpy ((char *) buffer->data + offset, data, size); + if (buffer->drawable) { + GLITZ_GL_DRAWABLE (buffer->drawable); + + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + gl->bind_buffer (buffer->target, buffer->name); + gl->buffer_sub_data (buffer->target, offset, size, data); + gl->bind_buffer (buffer->target, 0); + buffer->drawable->backend->pop_current (buffer->drawable); + } else if (buffer->data) + memcpy ((char *) buffer->data + offset, data, size); } slim_hidden_def(glitz_buffer_set_data); void glitz_buffer_get_data (glitz_buffer_t *buffer, - int offset, - unsigned int size, - void *data) + int offset, + unsigned int size, + void *data) { - if (buffer->drawable) { - GLITZ_GL_DRAWABLE (buffer->drawable); - - buffer->drawable->backend->push_current (buffer->drawable, NULL, - GLITZ_ANY_CONTEXT_CURRENT); - - gl->bind_buffer (buffer->target, buffer->name); - gl->get_buffer_sub_data (buffer->target, offset, size, data); - gl->bind_buffer (buffer->target, 0); - - buffer->drawable->backend->pop_current (buffer->drawable); - } else if (buffer->data) - memcpy (data, (char *) buffer->data + offset, size); + if (buffer->drawable) { + GLITZ_GL_DRAWABLE (buffer->drawable); + + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + + gl->bind_buffer (buffer->target, buffer->name); + gl->get_buffer_sub_data (buffer->target, offset, size, data); + gl->bind_buffer (buffer->target, 0); + + buffer->drawable->backend->pop_current (buffer->drawable); + } else if (buffer->data) + memcpy (data, (char *) buffer->data + offset, size); } slim_hidden_def(glitz_buffer_get_data); void * glitz_buffer_map (glitz_buffer_t *buffer, - glitz_buffer_access_t access) + glitz_buffer_access_t access) { - void *pointer = NULL; - - if (buffer->drawable) { - glitz_gl_enum_t buffer_access; - - GLITZ_GL_DRAWABLE (buffer->drawable); - - buffer->drawable->backend->push_current (buffer->drawable, NULL, - GLITZ_ANY_CONTEXT_CURRENT); - - switch (access) { - case GLITZ_BUFFER_ACCESS_READ_ONLY: - buffer_access = GLITZ_GL_READ_ONLY; - break; - case GLITZ_BUFFER_ACCESS_WRITE_ONLY: - buffer_access = GLITZ_GL_WRITE_ONLY; - break; - default: - buffer_access = GLITZ_GL_READ_WRITE; - break; + void *pointer = NULL; + + if (buffer->drawable) { + glitz_gl_enum_t buffer_access; + + GLITZ_GL_DRAWABLE (buffer->drawable); + + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + + switch (access) { + case GLITZ_BUFFER_ACCESS_READ_ONLY: + buffer_access = GLITZ_GL_READ_ONLY; + break; + case GLITZ_BUFFER_ACCESS_WRITE_ONLY: + buffer_access = GLITZ_GL_WRITE_ONLY; + break; + default: + buffer_access = GLITZ_GL_READ_WRITE; + break; + } + + gl->bind_buffer (buffer->target, buffer->name); + pointer = gl->map_buffer (buffer->target, buffer_access); + gl->bind_buffer (buffer->target, 0); + + buffer->drawable->backend->pop_current (buffer->drawable); } - gl->bind_buffer (buffer->target, buffer->name); - pointer = gl->map_buffer (buffer->target, buffer_access); - gl->bind_buffer (buffer->target, 0); - - buffer->drawable->backend->pop_current (buffer->drawable); - } - - if (pointer == NULL) - pointer = buffer->data; - - return pointer; + if (pointer == NULL) + pointer = buffer->data; + + return pointer; } glitz_status_t glitz_buffer_unmap (glitz_buffer_t *buffer) { - glitz_status_t status = GLITZ_STATUS_SUCCESS; - - if (buffer->drawable) { - GLITZ_GL_DRAWABLE (buffer->drawable); - - buffer->drawable->backend->push_current (buffer->drawable, NULL, - GLITZ_ANY_CONTEXT_CURRENT); - - gl->bind_buffer (buffer->target, buffer->name); - - if (gl->unmap_buffer (buffer->target) == GLITZ_GL_FALSE) - status = GLITZ_STATUS_CONTENT_DESTROYED; - - gl->bind_buffer (buffer->target, 0); - - buffer->drawable->backend->pop_current (buffer->drawable); - } - - return status; + glitz_status_t status = GLITZ_STATUS_SUCCESS; + + if (buffer->drawable) { + GLITZ_GL_DRAWABLE (buffer->drawable); + + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + + gl->bind_buffer (buffer->target, buffer->name); + + if (gl->unmap_buffer (buffer->target) == GLITZ_GL_FALSE) + status = GLITZ_STATUS_CONTENT_DESTROYED; + + gl->bind_buffer (buffer->target, 0); + + buffer->drawable->backend->pop_current (buffer->drawable); + } + + return status; } void * glitz_buffer_bind (glitz_buffer_t *buffer, - glitz_gl_enum_t target) + glitz_gl_enum_t target) { - if (buffer->drawable) { - buffer->drawable->backend->gl.bind_buffer (target, buffer->name); - buffer->target = target; - - return NULL; - } - - return buffer->data; + if (buffer->drawable) { + buffer->drawable->backend->gl->bind_buffer (target, buffer->name); + buffer->target = target; + + return NULL; + } + + return buffer->data; } void glitz_buffer_unbind (glitz_buffer_t *buffer) { - if (buffer->drawable) - buffer->drawable->backend->gl.bind_buffer (buffer->target, 0); + if (buffer->drawable) + buffer->drawable->backend->gl->bind_buffer (buffer->target, 0); } diff --git a/src/glitz_compose.c b/src/glitz_compose.c index c2cbe8d..1dcf70f 100644 --- a/src/glitz_compose.c +++ b/src/glitz_compose.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -32,590 +32,591 @@ static void _glitz_combine_argb_argb (glitz_composite_op_t *op) { - glitz_set_operator (op->gl, op->render_op); - - op->gl->active_texture (GLITZ_GL_TEXTURE0); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); - op->gl->color_4us (0x0, 0x0, 0x0, 0xffff); - - op->gl->active_texture (GLITZ_GL_TEXTURE1); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_COMBINE); - - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB, - GLITZ_GL_MODULATE); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB, - GLITZ_GL_TEXTURE); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB, - GLITZ_GL_PREVIOUS); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB, - GLITZ_GL_SRC_COLOR); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB, - GLITZ_GL_SRC_ALPHA); - - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA, - GLITZ_GL_MODULATE); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA, - GLITZ_GL_TEXTURE); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_ALPHA, - GLITZ_GL_PREVIOUS); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA, - GLITZ_GL_SRC_ALPHA); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_ALPHA, - GLITZ_GL_SRC_ALPHA); -} - -static void -_glitz_combine_argb_argbc (glitz_composite_op_t *op) -{ - if (op->count == 0) { glitz_set_operator (op->gl, op->render_op); - + op->gl->active_texture (GLITZ_GL_TEXTURE0); op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_COMBINE); - - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB, - GLITZ_GL_INTERPOLATE); + GLITZ_GL_REPLACE); + op->gl->color_4us (0x0, 0x0, 0x0, 0xffff); + op->gl->active_texture (GLITZ_GL_TEXTURE1); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_COMBINE); + + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB, + GLITZ_GL_MODULATE); op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB, - GLITZ_GL_TEXTURE); + GLITZ_GL_TEXTURE); op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB, - GLITZ_GL_PRIMARY_COLOR); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE2_RGB, - GLITZ_GL_PRIMARY_COLOR); + GLITZ_GL_PREVIOUS); op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB, - GLITZ_GL_SRC_COLOR); + GLITZ_GL_SRC_COLOR); op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB, - GLITZ_GL_SRC_COLOR); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND2_RGB, - GLITZ_GL_SRC_ALPHA); + GLITZ_GL_SRC_ALPHA); - /* we don't care about the alpha channel, so lets do something (simple?) */ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA, - GLITZ_GL_REPLACE); + GLITZ_GL_MODULATE); op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA, - GLITZ_GL_PRIMARY_COLOR); + GLITZ_GL_TEXTURE); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_ALPHA, + GLITZ_GL_PREVIOUS); op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA, - GLITZ_GL_SRC_ALPHA); + GLITZ_GL_SRC_ALPHA); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_ALPHA, + GLITZ_GL_SRC_ALPHA); +} - - op->gl->active_texture (GLITZ_GL_TEXTURE1); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_COMBINE); - - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB, - GLITZ_GL_DOT3_RGBA); - - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB, - GLITZ_GL_PREVIOUS); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB, - GLITZ_GL_PRIMARY_COLOR); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB, - GLITZ_GL_SRC_COLOR); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB, - GLITZ_GL_SRC_COLOR); - - op->gl->active_texture (GLITZ_GL_TEXTURE2); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_MODULATE); - } - - if (op->alpha_mask.red) { - op->gl->color_4f (1.0f, 0.5f, 0.5f, 0.5f); - } else if (op->alpha_mask.green) { - op->gl->color_4f (0.5f, 1.0f, 0.5f, 0.5f); - } else if (op->alpha_mask.blue) { - op->gl->color_4f (0.5f, 0.5f, 1.0f, 0.5f); - } else { - op->gl->active_texture (GLITZ_GL_TEXTURE0); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); - op->gl->color_4us (0x0, 0x0, 0x0, 0xffff); - - op->gl->active_texture (GLITZ_GL_TEXTURE1); - glitz_texture_unbind (op->gl, &op->src->texture); - - op->gl->active_texture (GLITZ_GL_TEXTURE2); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_MODULATE); - } +static void +_glitz_combine_argb_argbc (glitz_composite_op_t *op) +{ + if (op->count == 0) { + glitz_set_operator (op->gl, op->render_op); + + op->gl->active_texture (GLITZ_GL_TEXTURE0); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_COMBINE); + + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB, + GLITZ_GL_INTERPOLATE); + + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB, + GLITZ_GL_TEXTURE); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB, + GLITZ_GL_PRIMARY_COLOR); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE2_RGB, + GLITZ_GL_PRIMARY_COLOR); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB, + GLITZ_GL_SRC_COLOR); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB, + GLITZ_GL_SRC_COLOR); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND2_RGB, + GLITZ_GL_SRC_ALPHA); + + /* we don't care about the alpha channel */ + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA, + GLITZ_GL_REPLACE); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA, + GLITZ_GL_PRIMARY_COLOR); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA, + GLITZ_GL_SRC_ALPHA); + + + op->gl->active_texture (GLITZ_GL_TEXTURE1); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_COMBINE); + + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB, + GLITZ_GL_DOT3_RGBA); + + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB, + GLITZ_GL_PREVIOUS); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB, + GLITZ_GL_PRIMARY_COLOR); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB, + GLITZ_GL_SRC_COLOR); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB, + GLITZ_GL_SRC_COLOR); + + op->gl->active_texture (GLITZ_GL_TEXTURE2); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_MODULATE); + } + + if (op->alpha_mask.red) { + op->gl->color_4f (1.0f, 0.5f, 0.5f, 0.5f); + } else if (op->alpha_mask.green) { + op->gl->color_4f (0.5f, 1.0f, 0.5f, 0.5f); + } else if (op->alpha_mask.blue) { + op->gl->color_4f (0.5f, 0.5f, 1.0f, 0.5f); + } else { + op->gl->active_texture (GLITZ_GL_TEXTURE0); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_REPLACE); + op->gl->color_4us (0x0, 0x0, 0x0, 0xffff); + + op->gl->active_texture (GLITZ_GL_TEXTURE1); + glitz_texture_unbind (op->gl, &op->src->texture); + + op->gl->active_texture (GLITZ_GL_TEXTURE2); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_MODULATE); + } } static void _glitz_combine_argb_argbf (glitz_composite_op_t *op) { - glitz_set_operator (op->gl, op->render_op); - glitz_filter_enable (op->mask, op); - - op->gl->color_4us (op->alpha_mask.red, - op->alpha_mask.green, - op->alpha_mask.blue, - op->alpha_mask.alpha); + glitz_set_operator (op->gl, op->render_op); + glitz_filter_enable (op->mask, op); + + op->gl->color_4us (op->alpha_mask.red, + op->alpha_mask.green, + op->alpha_mask.blue, + op->alpha_mask.alpha); } static void _glitz_combine_argb_solid (glitz_composite_op_t *op) { - glitz_set_operator (op->gl, op->render_op); - - if (op->alpha_mask.alpha != 0xffff) { - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_MODULATE); - op->gl->color_4us (op->alpha_mask.alpha, - op->alpha_mask.alpha, - op->alpha_mask.alpha, - op->alpha_mask.alpha); - } else { - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); - op->gl->color_4us (0x0, 0x0, 0x0, 0xffff); - } + glitz_set_operator (op->gl, op->render_op); + + if (op->alpha_mask.alpha != 0xffff) { + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_MODULATE); + op->gl->color_4us (op->alpha_mask.alpha, + op->alpha_mask.alpha, + op->alpha_mask.alpha, + op->alpha_mask.alpha); + } else { + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_REPLACE); + op->gl->color_4us (0x0, 0x0, 0x0, 0xffff); + } } static void _glitz_combine_argb_solidc (glitz_composite_op_t *op) { - unsigned short alpha; + unsigned short alpha; - if (op->count == 0) - glitz_set_operator (op->gl, op->render_op); - - if (op->alpha_mask.red) - alpha = op->alpha_mask.red; - else if (op->alpha_mask.green) - alpha = op->alpha_mask.green; - else if (op->alpha_mask.blue) - alpha = op->alpha_mask.blue; - else - alpha = op->alpha_mask.alpha; - - if (alpha != 0xffff) { - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_MODULATE); - op->gl->color_4us (alpha, alpha, alpha, alpha); - } else { - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); - op->gl->color_4us (0x0, 0x0, 0x0, 0xffff); - } + if (op->count == 0) + glitz_set_operator (op->gl, op->render_op); + + if (op->alpha_mask.red) + alpha = op->alpha_mask.red; + else if (op->alpha_mask.green) + alpha = op->alpha_mask.green; + else if (op->alpha_mask.blue) + alpha = op->alpha_mask.blue; + else + alpha = op->alpha_mask.alpha; + + if (alpha != 0xffff) { + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_MODULATE); + op->gl->color_4us (alpha, alpha, alpha, alpha); + } else { + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_REPLACE); + op->gl->color_4us (0x0, 0x0, 0x0, 0xffff); + } } static void _glitz_combine_argbf_solid (glitz_composite_op_t *op) { - if (op->count == 0) { - glitz_set_operator (op->gl, op->render_op); - glitz_filter_enable (op->src, op); - } + if (op->count == 0) { + glitz_set_operator (op->gl, op->render_op); + glitz_filter_enable (op->src, op); + } - op->gl->color_4us (0x0, 0x0, 0x0, op->alpha_mask.alpha); + op->gl->color_4us (0x0, 0x0, 0x0, op->alpha_mask.alpha); } static void _glitz_combine_argbf_argbc (glitz_composite_op_t *op) { - if (op->count == 0) { - glitz_set_operator (op->gl, op->render_op); - glitz_filter_enable (op->src, op); - } - - op->gl->color_4us (op->alpha_mask.red, - op->alpha_mask.green, - op->alpha_mask.blue, - op->alpha_mask.alpha); + if (op->count == 0) { + glitz_set_operator (op->gl, op->render_op); + glitz_filter_enable (op->src, op); + } + + op->gl->color_4us (op->alpha_mask.red, + op->alpha_mask.green, + op->alpha_mask.blue, + op->alpha_mask.alpha); } static void _glitz_combine_argbf_solidc (glitz_composite_op_t *op) { - unsigned short alpha; - - if (op->count == 0) { - glitz_set_operator (op->gl, op->render_op); - glitz_filter_enable (op->src, op); - } - - if (op->alpha_mask.red) - alpha = op->alpha_mask.red; - else if (op->alpha_mask.green) - alpha = op->alpha_mask.green; - else if (op->alpha_mask.blue) - alpha = op->alpha_mask.blue; - else - alpha = op->alpha_mask.alpha; - - op->gl->color_4us (0x0, 0x0, 0x0, alpha); + unsigned short alpha; + + if (op->count == 0) { + glitz_set_operator (op->gl, op->render_op); + glitz_filter_enable (op->src, op); + } + + if (op->alpha_mask.red) + alpha = op->alpha_mask.red; + else if (op->alpha_mask.green) + alpha = op->alpha_mask.green; + else if (op->alpha_mask.blue) + alpha = op->alpha_mask.blue; + else + alpha = op->alpha_mask.alpha; + + op->gl->color_4us (0x0, 0x0, 0x0, alpha); } static void _glitz_combine_solid_solid (glitz_composite_op_t *op) { - glitz_set_operator (op->gl, op->render_op); - - op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha), - SHORT_MULT (op->solid->green, op->alpha_mask.alpha), - SHORT_MULT (op->solid->blue, op->alpha_mask.alpha), - SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha)); + glitz_set_operator (op->gl, op->render_op); + + op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha), + SHORT_MULT (op->solid->green, op->alpha_mask.alpha), + SHORT_MULT (op->solid->blue, op->alpha_mask.alpha), + SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha)); } static void _glitz_combine_solid_argb (glitz_composite_op_t *op) { - glitz_set_operator (op->gl, op->render_op); - - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_COMBINE); - - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB, - GLITZ_GL_MODULATE); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB, - GLITZ_GL_TEXTURE); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB, - GLITZ_GL_PRIMARY_COLOR); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB, - GLITZ_GL_SRC_ALPHA); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB, - GLITZ_GL_SRC_COLOR); - - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA, - GLITZ_GL_MODULATE); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA, - GLITZ_GL_TEXTURE); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_ALPHA, - GLITZ_GL_PRIMARY_COLOR); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA, - GLITZ_GL_SRC_ALPHA); - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_ALPHA, - GLITZ_GL_SRC_ALPHA); - - op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha), - SHORT_MULT (op->solid->green, op->alpha_mask.alpha), - SHORT_MULT (op->solid->blue, op->alpha_mask.alpha), - SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha)); + glitz_set_operator (op->gl, op->render_op); + + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_COMBINE); + + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB, + GLITZ_GL_MODULATE); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB, + GLITZ_GL_TEXTURE); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB, + GLITZ_GL_PRIMARY_COLOR); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB, + GLITZ_GL_SRC_ALPHA); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB, + GLITZ_GL_SRC_COLOR); + + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA, + GLITZ_GL_MODULATE); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA, + GLITZ_GL_TEXTURE); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_ALPHA, + GLITZ_GL_PRIMARY_COLOR); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA, + GLITZ_GL_SRC_ALPHA); + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_ALPHA, + GLITZ_GL_SRC_ALPHA); + + op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha), + SHORT_MULT (op->solid->green, op->alpha_mask.alpha), + SHORT_MULT (op->solid->blue, op->alpha_mask.alpha), + SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha)); } /* This only works with the OVER operator. */ static void _glitz_combine_solid_argbc (glitz_composite_op_t *op) { - glitz_color_t solid; - - solid.red = SHORT_MULT (op->solid->red, op->alpha_mask.alpha); - solid.green = SHORT_MULT (op->solid->green, op->alpha_mask.alpha); - solid.blue = SHORT_MULT (op->solid->blue, op->alpha_mask.alpha); - solid.alpha = SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha); - - op->gl->enable (GLITZ_GL_BLEND); - op->gl->blend_func (GLITZ_GL_CONSTANT_COLOR, GLITZ_GL_ONE_MINUS_SRC_COLOR); - - if (solid.alpha > 0) - op->gl->blend_color ((glitz_gl_clampf_t) solid.red / solid.alpha, - (glitz_gl_clampf_t) solid.green / solid.alpha, - (glitz_gl_clampf_t) solid.blue / solid.alpha, - 1.0f); - else - op->gl->blend_color (1.0f, 1.0f, 1.0f, 1.0f); - - op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_MODULATE); - op->gl->color_4us (solid.alpha, - solid.alpha, - solid.alpha, - solid.alpha); + glitz_color_t solid; + + solid.red = SHORT_MULT (op->solid->red, op->alpha_mask.alpha); + solid.green = SHORT_MULT (op->solid->green, op->alpha_mask.alpha); + solid.blue = SHORT_MULT (op->solid->blue, op->alpha_mask.alpha); + solid.alpha = SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha); + + op->gl->enable (GLITZ_GL_BLEND); + op->gl->blend_func (GLITZ_GL_CONSTANT_COLOR, GLITZ_GL_ONE_MINUS_SRC_COLOR); + + if (solid.alpha > 0) + op->gl->blend_color ((glitz_gl_clampf_t) solid.red / solid.alpha, + (glitz_gl_clampf_t) solid.green / solid.alpha, + (glitz_gl_clampf_t) solid.blue / solid.alpha, + 1.0f); + else + op->gl->blend_color (1.0f, 1.0f, 1.0f, 1.0f); + + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_MODULATE); + op->gl->color_4us (solid.alpha, + solid.alpha, + solid.alpha, + solid.alpha); } static void _glitz_combine_solid_argbf (glitz_composite_op_t *op) { - glitz_set_operator (op->gl, op->render_op); - glitz_filter_enable (op->mask, op); + glitz_set_operator (op->gl, op->render_op); + glitz_filter_enable (op->mask, op); - op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha), - SHORT_MULT (op->solid->green, op->alpha_mask.alpha), - SHORT_MULT (op->solid->blue, op->alpha_mask.alpha), - SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha)); + op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha), + SHORT_MULT (op->solid->green, op->alpha_mask.alpha), + SHORT_MULT (op->solid->blue, op->alpha_mask.alpha), + SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha)); } /* This only works with the OVER operator. */ static void _glitz_combine_solid_solidc (glitz_composite_op_t *op) { - op->gl->enable (GLITZ_GL_BLEND); - op->gl->blend_func (GLITZ_GL_CONSTANT_COLOR, GLITZ_GL_ONE_MINUS_SRC_COLOR); - - if (op->solid->alpha > 0) - op->gl->blend_color ((glitz_gl_clampf_t) op->solid->red / op->solid->alpha, - (glitz_gl_clampf_t) - op->solid->green / op->solid->alpha, - (glitz_gl_clampf_t) - op->solid->blue / op->solid->alpha, - 1.0f); - else - op->gl->blend_color (1.0f, 1.0f, 1.0f, 1.0f); - - op->gl->color_4us (SHORT_MULT (op->alpha_mask.red, op->solid->alpha), - SHORT_MULT (op->alpha_mask.green, op->solid->alpha), - SHORT_MULT (op->alpha_mask.blue, op->solid->alpha), - SHORT_MULT (op->alpha_mask.alpha, op->solid->alpha)); + op->gl->enable (GLITZ_GL_BLEND); + op->gl->blend_func (GLITZ_GL_CONSTANT_COLOR, GLITZ_GL_ONE_MINUS_SRC_COLOR); + + if (op->solid->alpha > 0) + op->gl->blend_color ((glitz_gl_clampf_t) + op->solid->red / op->solid->alpha, + (glitz_gl_clampf_t) + op->solid->green / op->solid->alpha, + (glitz_gl_clampf_t) + op->solid->blue / op->solid->alpha, + 1.0f); + else + op->gl->blend_color (1.0f, 1.0f, 1.0f, 1.0f); + + op->gl->color_4us (SHORT_MULT (op->alpha_mask.red, op->solid->alpha), + SHORT_MULT (op->alpha_mask.green, op->solid->alpha), + SHORT_MULT (op->alpha_mask.blue, op->solid->alpha), + SHORT_MULT (op->alpha_mask.alpha, op->solid->alpha)); } static glitz_combine_t _glitz_combine_map[GLITZ_SURFACE_TYPES][GLITZ_SURFACE_TYPES] = { - { - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 } - }, { - { GLITZ_COMBINE_TYPE_ARGB, _glitz_combine_argb_solid, 1, 0 }, - { GLITZ_COMBINE_TYPE_ARGB_ARGB, _glitz_combine_argb_argb, 2, 0 }, - { GLITZ_COMBINE_TYPE_ARGB_ARGBC, _glitz_combine_argb_argbc, 3, 0 }, - { GLITZ_COMBINE_TYPE_ARGB_ARGBF, _glitz_combine_argb_argbf, 2, 2 }, - { GLITZ_COMBINE_TYPE_ARGB_SOLID, _glitz_combine_argb_solid, 1, 0 }, - { GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 } - }, { - { GLITZ_COMBINE_TYPE_ARGB, _glitz_combine_argb_solid, 1, 0 }, - { GLITZ_COMBINE_TYPE_ARGB_ARGB, _glitz_combine_argb_argb, 2, 0 }, - { GLITZ_COMBINE_TYPE_ARGB_ARGBC, _glitz_combine_argb_argbc, 3, 0 }, - { GLITZ_COMBINE_TYPE_ARGB_ARGBF, _glitz_combine_argb_argbf, 2, 2 }, - { GLITZ_COMBINE_TYPE_ARGB_SOLID, _glitz_combine_argb_solid, 1, 0 }, - { GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 } - }, { - { GLITZ_COMBINE_TYPE_ARGBF, _glitz_combine_argbf_solid, 1, 1 }, - { GLITZ_COMBINE_TYPE_ARGBF_ARGB, _glitz_combine_argbf_solid, 2, 1 }, - { GLITZ_COMBINE_TYPE_ARGBF_ARGBC, _glitz_combine_argbf_argbc, 2, 1 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, - { GLITZ_COMBINE_TYPE_ARGBF_SOLID, _glitz_combine_argbf_solid, 1, 1 }, - { GLITZ_COMBINE_TYPE_ARGBF_SOLIDC, _glitz_combine_argbf_solidc, 1, 1 } - }, { - { GLITZ_COMBINE_TYPE_SOLID, _glitz_combine_solid_solid, 0, 0 }, - { GLITZ_COMBINE_TYPE_SOLID_ARGB, _glitz_combine_solid_argb, 1, 0 }, - { GLITZ_COMBINE_TYPE_SOLID_ARGBC, _glitz_combine_solid_argbc, 1, 0 }, - { GLITZ_COMBINE_TYPE_SOLID_ARGBF, _glitz_combine_solid_argbf, 1, 2 }, - { GLITZ_COMBINE_TYPE_SOLID_SOLID, _glitz_combine_solid_solid, 0, 0 }, - { GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 } - }, { - { GLITZ_COMBINE_TYPE_SOLID, _glitz_combine_solid_solid, 0, 0 }, - { GLITZ_COMBINE_TYPE_SOLID_ARGB, _glitz_combine_solid_argb, 1, 0 }, - { GLITZ_COMBINE_TYPE_SOLID_ARGBC, _glitz_combine_solid_argbc, 1, 0 }, - { GLITZ_COMBINE_TYPE_SOLID_ARGBF, _glitz_combine_solid_argbf, 1, 2 }, - { GLITZ_COMBINE_TYPE_SOLID_SOLID, _glitz_combine_solid_solid, 0, 0 }, - { GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 } - } + { + { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 } + }, { + { GLITZ_COMBINE_TYPE_ARGB, _glitz_combine_argb_solid, 1, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_ARGB, _glitz_combine_argb_argb, 2, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_ARGBC, _glitz_combine_argb_argbc, 3, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_ARGBF, _glitz_combine_argb_argbf, 2, 2 }, + { GLITZ_COMBINE_TYPE_ARGB_SOLID, _glitz_combine_argb_solid, 1, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 } + }, { + { GLITZ_COMBINE_TYPE_ARGB, _glitz_combine_argb_solid, 1, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_ARGB, _glitz_combine_argb_argb, 2, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_ARGBC, _glitz_combine_argb_argbc, 3, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_ARGBF, _glitz_combine_argb_argbf, 2, 2 }, + { GLITZ_COMBINE_TYPE_ARGB_SOLID, _glitz_combine_argb_solid, 1, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 } + }, { + { GLITZ_COMBINE_TYPE_ARGBF, _glitz_combine_argbf_solid, 1, 1 }, + { GLITZ_COMBINE_TYPE_ARGBF_ARGB, _glitz_combine_argbf_solid, 2, 1 }, + { GLITZ_COMBINE_TYPE_ARGBF_ARGBC, _glitz_combine_argbf_argbc, 2, 1 }, + { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_ARGBF_SOLID, _glitz_combine_argbf_solid, 1, 1 }, + { GLITZ_COMBINE_TYPE_ARGBF_SOLIDC, _glitz_combine_argbf_solidc, 1, 1 } + }, { + { GLITZ_COMBINE_TYPE_SOLID, _glitz_combine_solid_solid, 0, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_ARGB, _glitz_combine_solid_argb, 1, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_ARGBC, _glitz_combine_solid_argbc, 1, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_ARGBF, _glitz_combine_solid_argbf, 1, 2 }, + { GLITZ_COMBINE_TYPE_SOLID_SOLID, _glitz_combine_solid_solid, 0, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 } + }, { + { GLITZ_COMBINE_TYPE_SOLID, _glitz_combine_solid_solid, 0, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_ARGB, _glitz_combine_solid_argb, 1, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_ARGBC, _glitz_combine_solid_argbc, 1, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_ARGBF, _glitz_combine_solid_argbf, 1, 2 }, + { GLITZ_COMBINE_TYPE_SOLID_SOLID, _glitz_combine_solid_solid, 0, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 } + } }; -#define SURFACE_WRAP(surface, feature_mask) \ - (SURFACE_REPEAT (surface)? \ - (TEXTURE_REPEATABLE (&(surface)->texture) && \ - ( \ - (!SURFACE_MIRRORED (surface)) || \ - ((feature_mask) & GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK) \ - ) \ - ) \ - : \ - ((SURFACE_PAD (surface))? \ - (TEXTURE_PADABLE (&(surface)->texture)) \ - : \ - ( \ - (!SURFACE_PROJECTIVE_TRANSFORM (surface)) || \ - ((feature_mask) & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK) \ - ) \ - ) \ - ) - +#define SURFACE_WRAP(surface, feature_mask) \ + (SURFACE_REPEAT (surface)? \ + (TEXTURE_REPEATABLE (&(surface)->texture) && \ + ( \ + (!SURFACE_MIRRORED (surface)) || \ + ((feature_mask) & GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK) \ + ) \ + ) \ + : \ + ((SURFACE_PAD (surface))? \ + (TEXTURE_PADABLE (&(surface)->texture)) \ + : \ + ( \ + (!SURFACE_PROJECTIVE_TRANSFORM (surface)) || \ + ((feature_mask) & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK) \ + ) \ + ) \ + ) + static glitz_surface_type_t _glitz_get_surface_type (glitz_surface_t *surface, - unsigned long feature_mask) + unsigned long feature_mask) { - if (surface == NULL) - return GLITZ_SURFACE_TYPE_NULL; + if (surface == NULL) + return GLITZ_SURFACE_TYPE_NULL; + + if (SURFACE_SOLID (surface) && + (SURFACE_REPEAT (surface) || SURFACE_PAD (surface))) { + if (SURFACE_COMPONENT_ALPHA (surface)) + return GLITZ_SURFACE_TYPE_SOLIDC; + else + return GLITZ_SURFACE_TYPE_SOLID; + } - if (SURFACE_SOLID (surface) && - (SURFACE_REPEAT (surface) || SURFACE_PAD (surface))) { - if (SURFACE_COMPONENT_ALPHA (surface)) - return GLITZ_SURFACE_TYPE_SOLIDC; - else - return GLITZ_SURFACE_TYPE_SOLID; - } - - if (SURFACE_WRAP (surface, feature_mask)) { - if (SURFACE_FRAGMENT_FILTER (surface)) { - if (SURFACE_COMPONENT_ALPHA (surface)) - return GLITZ_SURFACE_TYPE_NA; - - if (feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) - return GLITZ_SURFACE_TYPE_ARGBF; - - } else if (SURFACE_COMPONENT_ALPHA (surface)) { - return GLITZ_SURFACE_TYPE_ARGBC; - } else - return GLITZ_SURFACE_TYPE_ARGB; - } - - return GLITZ_SURFACE_TYPE_NA; + if (SURFACE_WRAP (surface, feature_mask)) { + if (SURFACE_FRAGMENT_FILTER (surface)) { + if (SURFACE_COMPONENT_ALPHA (surface)) + return GLITZ_SURFACE_TYPE_NA; + + if (feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) + return GLITZ_SURFACE_TYPE_ARGBF; + + } else if (SURFACE_COMPONENT_ALPHA (surface)) { + return GLITZ_SURFACE_TYPE_ARGBC; + } else + return GLITZ_SURFACE_TYPE_ARGB; + } + + return GLITZ_SURFACE_TYPE_NA; } static glitz_color_t _default_alpha_mask = { - 0xffff, 0xffff, 0xffff, 0xffff + 0xffff, 0xffff, 0xffff, 0xffff }; void glitz_composite_op_init (glitz_composite_op_t *op, - glitz_operator_t render_op, - glitz_surface_t *src, - glitz_surface_t *mask, - glitz_surface_t *dst) + glitz_operator_t render_op, + glitz_surface_t *src, + glitz_surface_t *mask, + glitz_surface_t *dst) { - glitz_surface_type_t src_type; - glitz_surface_type_t mask_type; - glitz_combine_t *combine; - unsigned long feature_mask; - - op->render_op = render_op; - op->type = GLITZ_COMBINE_TYPE_NA; - op->combine = NULL; - op->alpha_mask = _default_alpha_mask; - op->src = src; - op->mask = mask; - op->dst = dst; - op->count = 0; - op->solid = NULL; - op->per_component = 0; - op->fp = 0; - - if (dst->attached) - { - op->gl = &dst->attached->backend->gl; - feature_mask = dst->attached->backend->feature_mask; - } - else - { - op->gl = &dst->drawable->backend->gl; - feature_mask = dst->drawable->backend->feature_mask; - } - - src_type = _glitz_get_surface_type (src, feature_mask); - if (src_type < 1) - return; - - mask_type = _glitz_get_surface_type (mask, feature_mask); - if (mask_type < 0) - return; - - if (src_type == GLITZ_SURFACE_TYPE_SOLIDC) - src_type = GLITZ_SURFACE_TYPE_SOLID; - - /* We can't do solid IN argbc OP dest, unless OP is OVER. - But we can do argb IN argbc OP dest, so lets just not use the - source as a solid color if this is the case. I need to figure out - a better way to handle special cases like this. */ - if (src_type == GLITZ_SURFACE_TYPE_SOLID && - (mask_type == GLITZ_SURFACE_TYPE_SOLIDC || - mask_type == GLITZ_SURFACE_TYPE_ARGBC) && - render_op != GLITZ_OPERATOR_OVER) - src_type = GLITZ_SURFACE_TYPE_ARGB; - - combine = &_glitz_combine_map[src_type][mask_type]; - if (!combine->type) - return; - - if (dst->geometry.type == GLITZ_GEOMETRY_TYPE_BITMAP) - { - /* We can't do anything but solid colors with bitmaps yet. */ - if (src_type != GLITZ_SURFACE_TYPE_SOLID || - (mask_type != GLITZ_SURFACE_TYPE_NULL && - mask_type != GLITZ_SURFACE_TYPE_SOLID)) - return; - } - - if (src_type == GLITZ_SURFACE_TYPE_SOLID) { - if (SURFACE_SOLID_DAMAGE (src)) { - glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); - glitz_surface_sync_solid (src); - glitz_surface_pop_current (dst); + glitz_surface_type_t src_type; + glitz_surface_type_t mask_type; + glitz_combine_t *combine; + unsigned long feature_mask; + + op->render_op = render_op; + op->type = GLITZ_COMBINE_TYPE_NA; + op->combine = NULL; + op->alpha_mask = _default_alpha_mask; + op->src = src; + op->mask = mask; + op->dst = dst; + op->count = 0; + op->solid = NULL; + op->per_component = 0; + op->fp = 0; + + if (dst->attached) + { + op->gl = dst->attached->backend->gl; + feature_mask = dst->attached->backend->feature_mask; } - op->solid = &src->solid; - op->src = NULL; - } - - if (mask_type == GLITZ_SURFACE_TYPE_SOLID) { - if (SURFACE_SOLID_DAMAGE (mask)) { - glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); - glitz_surface_sync_solid (mask); - glitz_surface_pop_current (dst); + else + { + op->gl = dst->drawable->backend->gl; + feature_mask = dst->drawable->backend->feature_mask; } - op->alpha_mask = mask->solid; - op->mask = NULL; - op->combine = combine; - } else if (mask_type == GLITZ_SURFACE_TYPE_SOLIDC) { - if (SURFACE_SOLID_DAMAGE (mask)) { - glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); - glitz_surface_sync_solid (mask); - glitz_surface_pop_current (dst); + + src_type = _glitz_get_surface_type (src, feature_mask); + if (src_type < 1) + return; + + mask_type = _glitz_get_surface_type (mask, feature_mask); + if (mask_type < 0) + return; + + if (src_type == GLITZ_SURFACE_TYPE_SOLIDC) + src_type = GLITZ_SURFACE_TYPE_SOLID; + + /* We can't do solid IN argbc OP dest, unless OP is OVER. + But we can do argb IN argbc OP dest, so lets just not use the + source as a solid color if this is the case. I need to figure out + a better way to handle special cases like this. */ + if (src_type == GLITZ_SURFACE_TYPE_SOLID && + (mask_type == GLITZ_SURFACE_TYPE_SOLIDC || + mask_type == GLITZ_SURFACE_TYPE_ARGBC) && + render_op != GLITZ_OPERATOR_OVER) + src_type = GLITZ_SURFACE_TYPE_ARGB; + + combine = &_glitz_combine_map[src_type][mask_type]; + if (!combine->type) + return; + + if (dst->geometry.type == GLITZ_GEOMETRY_TYPE_BITMAP) + { + /* We can't do anything but solid colors with bitmaps yet. */ + if (src_type != GLITZ_SURFACE_TYPE_SOLID || + (mask_type != GLITZ_SURFACE_TYPE_NULL && + mask_type != GLITZ_SURFACE_TYPE_SOLID)) + return; } - op->alpha_mask = mask->solid; - op->mask = NULL; - - if (op->src) { - op->per_component = 4; - op->combine = combine; - } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) - op->combine = combine; - - } else if (mask_type != GLITZ_SURFACE_TYPE_NULL) { - if (mask_type == GLITZ_SURFACE_TYPE_ARGBC) { - if (op->src) { - /* we can't do component alpha with alpha only surfaces */ - if (op->src->format->color.red_size) { - op->per_component = 4; - if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) - op->combine = combine; - } - } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) - op->combine = combine; - } else if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) - op->combine = combine; - } else - op->combine = combine; - - if (!(feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK)) { - if (op->src && op->mask) - op->combine = NULL; - } - - if (op->per_component && - (!(feature_mask & GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK))) - op->combine = NULL; - - if (op->combine == combine) { - op->type = combine->type; - if (combine->source_shader) { - if (combine->source_shader == 1) - op->fp = glitz_filter_get_fragment_program (src, op); - else - op->fp = glitz_filter_get_fragment_program (mask, op); - if (op->fp == 0) - op->type = GLITZ_COMBINE_TYPE_NA; + + if (src_type == GLITZ_SURFACE_TYPE_SOLID) { + if (SURFACE_SOLID_DAMAGE (src)) { + glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); + glitz_surface_sync_solid (src); + glitz_surface_pop_current (dst); + } + op->solid = &src->solid; + op->src = NULL; + } + + if (mask_type == GLITZ_SURFACE_TYPE_SOLID) { + if (SURFACE_SOLID_DAMAGE (mask)) { + glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); + glitz_surface_sync_solid (mask); + glitz_surface_pop_current (dst); + } + op->alpha_mask = mask->solid; + op->mask = NULL; + op->combine = combine; + } else if (mask_type == GLITZ_SURFACE_TYPE_SOLIDC) { + if (SURFACE_SOLID_DAMAGE (mask)) { + glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); + glitz_surface_sync_solid (mask); + glitz_surface_pop_current (dst); + } + op->alpha_mask = mask->solid; + op->mask = NULL; + + if (op->src) { + op->per_component = 4; + op->combine = combine; + } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) + op->combine = combine; + + } else if (mask_type != GLITZ_SURFACE_TYPE_NULL) { + if (mask_type == GLITZ_SURFACE_TYPE_ARGBC) { + if (op->src) { + /* we can't do component alpha with alpha only surfaces */ + if (op->src->format->color.red_size) { + op->per_component = 4; + if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) + op->combine = combine; + } + } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) + op->combine = combine; + } else if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) + op->combine = combine; + } else + op->combine = combine; + + if (!(feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK)) { + if (op->src && op->mask) + op->combine = NULL; + } + + if (op->per_component && + (!(feature_mask & GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK))) + op->combine = NULL; + + if (op->combine == combine) { + op->type = combine->type; + if (combine->source_shader) { + if (combine->source_shader == 1) + op->fp = glitz_filter_get_fragment_program (src, op); + else + op->fp = glitz_filter_get_fragment_program (mask, op); + if (op->fp == 0) + op->type = GLITZ_COMBINE_TYPE_NA; + } } - } } void glitz_composite_enable (glitz_composite_op_t *op) { - op->combine->enable (op); - op->count++; + op->combine->enable (op); + op->count++; } void glitz_composite_disable (glitz_composite_op_t *op) { - if (op->fp) { - op->gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, 0); - op->gl->disable (GLITZ_GL_FRAGMENT_PROGRAM); - } + if (op->fp) { + op->gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, 0); + op->gl->disable (GLITZ_GL_FRAGMENT_PROGRAM); + } } diff --git a/src/glitz_context.c b/src/glitz_context.c index 0f11cf6..f0977cb 100644 --- a/src/glitz_context.c +++ b/src/glitz_context.c @@ -1,6 +1,6 @@ /* * Copyright © 2005 Novell, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,10 +31,10 @@ void _glitz_context_init (glitz_context_t *context, - glitz_drawable_t *drawable) + glitz_drawable_t *drawable) { glitz_drawable_reference (drawable); - + context->ref_count = 1; context->drawable = drawable; context->closure = NULL; @@ -49,7 +49,7 @@ _glitz_context_fini (glitz_context_t *context) glitz_context_t * glitz_context_create (glitz_drawable_t *drawable, - glitz_drawable_format_t *format) + glitz_drawable_format_t *format) { return drawable->backend->create_context (drawable, format); } @@ -59,11 +59,11 @@ void glitz_context_destroy (glitz_context_t *context) { if (!context) - return; + return; context->ref_count--; if (context->ref_count) - return; + return; context->drawable->backend->destroy_context (context); } @@ -73,16 +73,16 @@ void glitz_context_reference (glitz_context_t *context) { if (!context) - return; - + return; + context->ref_count++; } slim_hidden_def(glitz_context_reference); void glitz_context_copy (glitz_context_t *src, - glitz_context_t *dst, - unsigned long mask) + glitz_context_t *dst, + unsigned long mask) { src->drawable->backend->copy_context (src, dst, mask); } @@ -90,8 +90,8 @@ slim_hidden_def(glitz_context_copy); void glitz_context_set_user_data (glitz_context_t *context, - void *closure, - glitz_lose_current_function_t lose_current) + void *closure, + glitz_lose_current_function_t lose_current) { context->closure = closure; context->lose_current = lose_current; @@ -100,28 +100,82 @@ slim_hidden_def(glitz_context_set_user_data); glitz_function_pointer_t glitz_context_get_proc_address (glitz_context_t *context, - const char *name) + const char *name) { return context->drawable->backend->get_proc_address (context, name); } slim_hidden_def(glitz_context_get_proc_address); void -glitz_context_make_current (glitz_context_t *context) +glitz_context_make_current (glitz_context_t *context, + glitz_drawable_t *drawable) { - context->drawable->backend->make_current (context, context->drawable); + if (drawable != context->drawable) + { + glitz_drawable_reference (drawable); + glitz_drawable_destroy (context->drawable); + context->drawable = drawable; + } + + if (drawable->front) + { + if (REGION_NOTEMPTY (&drawable->front->drawable_damage)) + { + glitz_surface_push_current (drawable->front, + GLITZ_DRAWABLE_CURRENT); + glitz_surface_pop_current (drawable->front); + } + + glitz_surface_damage (drawable->front, NULL, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + if (drawable->back) + { + if (REGION_NOTEMPTY (&drawable->back->drawable_damage)) + { + glitz_surface_push_current (drawable->back, + GLITZ_DRAWABLE_CURRENT); + glitz_surface_pop_current (drawable->back); + } + + glitz_surface_damage (drawable->back, NULL, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + drawable->backend->make_current (drawable, context); } slim_hidden_def(glitz_context_make_current); void -glitz_context_bind_texture (glitz_context_t *context, - glitz_surface_t *surface) +glitz_context_bind_texture (glitz_context_t *context, + glitz_texture_object_t *texture) { - glitz_gl_proc_address_list_t *gl = &context->drawable->backend->gl; - - if (!surface->texture.name) - gl->gen_textures (1, &surface->texture.name); - - gl->bind_texture (surface->texture.target, surface->texture.name); + glitz_gl_proc_address_list_t *gl = context->drawable->backend->gl; + + if (REGION_NOTEMPTY (&texture->surface->texture_damage)) + { + glitz_lose_current_function_t lose_current; + + lose_current = context->lose_current; + context->lose_current = 0; + + glitz_surface_push_current (texture->surface, GLITZ_CONTEXT_CURRENT); + _glitz_surface_sync_texture (texture->surface); + glitz_surface_pop_current (texture->surface); + + context->lose_current = lose_current; + + glitz_context_make_current (context, context->drawable); + } + + gl->bind_texture (texture->surface->texture.target, + texture->surface->texture.name); + + glitz_texture_ensure_parameters (gl, + &texture->surface->texture, + &texture->param); } slim_hidden_def(glitz_context_bind_texture); diff --git a/src/glitz_drawable.c b/src/glitz_drawable.c index f8431e4..9b0e77f 100644 --- a/src/glitz_drawable.c +++ b/src/glitz_drawable.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -29,119 +29,312 @@ #include "glitzint.h" -glitz_drawable_format_t * -glitz_find_similar_drawable_format (glitz_drawable_t *other, - unsigned long mask, - const glitz_drawable_format_t *templ, - int count) +void +_glitz_drawable_init (glitz_drawable_t *drawable, + glitz_int_drawable_format_t *format, + glitz_backend_t *backend, + int width, + int height) +{ + drawable->ref_count = 1; + + drawable->format = format; + drawable->backend = backend; + + drawable->width = width; + drawable->height = height; + + drawable->front = NULL; + drawable->back = NULL; + + drawable->viewport.x = -32767; + drawable->viewport.y = -32767; + drawable->viewport.width = 65535; + drawable->viewport.height = 65535; + + drawable->update_all = 1; +} + +static glitz_bool_t +_glitz_drawable_size_check (glitz_drawable_t *other, + unsigned int width, + unsigned int height) { - return glitz_drawable_format_find (other->backend->drawable_formats, - other->backend->n_drawable_formats, - mask, templ, count); + if (width == 0 || height == 0) + return 0; + + if (width > other->backend->max_viewport_dims[0] || + height > other->backend->max_viewport_dims[1]) + return 0; + + return 1; } -slim_hidden_def(glitz_find_similar_drawable_format); - + +glitz_drawable_t * +glitz_create_drawable (glitz_drawable_t *other, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) +{ + glitz_int_drawable_format_t *iformat; + + if (!_glitz_drawable_size_check (other, width, height)) + return NULL; + + if (format->id >= other->backend->n_drawable_formats) + return NULL; + + iformat = &other->backend->drawable_formats[format->id]; + if (!(iformat->types & GLITZ_DRAWABLE_TYPE_FBO_MASK)) + return NULL; + + return _glitz_fbo_drawable_create (other, iformat, width, height); +} +slim_hidden_def(glitz_create_drawable); + glitz_drawable_t * glitz_create_pbuffer_drawable (glitz_drawable_t *other, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { - if (!format->types.pbuffer) - return NULL; - - return other->backend->create_pbuffer (other, format, width, height); + glitz_int_drawable_format_t *iformat; + + if (!_glitz_drawable_size_check (other, width, height)) + return NULL; + + if (format->id >= other->backend->n_drawable_formats) + return NULL; + + iformat = &other->backend->drawable_formats[format->id]; + if (!(iformat->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK)) + return NULL; + + return other->backend->create_pbuffer (other, format, width, height); } slim_hidden_def(glitz_create_pbuffer_drawable); void glitz_drawable_destroy (glitz_drawable_t *drawable) { - if (!drawable) - return; - - drawable->ref_count--; - if (drawable->ref_count) - return; - - drawable->backend->destroy (drawable); + if (!drawable) + return; + + drawable->ref_count--; + if (drawable->ref_count) + return; + + drawable->backend->destroy (drawable); } void glitz_drawable_reference (glitz_drawable_t *drawable) { - if (!drawable) - return; + if (!drawable) + return; - drawable->ref_count++; + drawable->ref_count++; } void glitz_drawable_update_size (glitz_drawable_t *drawable, - unsigned int width, - unsigned int height) + unsigned int width, + unsigned int height) { - drawable->width = (int) width; - drawable->height = (int) height; + drawable->width = (int) width; + drawable->height = (int) height; - drawable->viewport.x = -32767; - drawable->viewport.y = -32767; - drawable->viewport.width = 65535; - drawable->viewport.height = 65535; + drawable->viewport.x = -32767; + drawable->viewport.y = -32767; + drawable->viewport.width = 65535; + drawable->viewport.height = 65535; - drawable->update_all = 1; + drawable->update_all = 1; } unsigned int glitz_drawable_get_width (glitz_drawable_t *drawable) { - return (unsigned int) drawable->width; + return (unsigned int) drawable->width; } slim_hidden_def(glitz_drawable_get_width); unsigned int glitz_drawable_get_height (glitz_drawable_t *drawable) { - return (unsigned int) drawable->height; + return (unsigned int) drawable->height; } slim_hidden_def(glitz_drawable_get_height); void +glitz_drawable_swap_buffer_region (glitz_drawable_t *drawable, + int x_origin, + int y_origin, + glitz_box_t *box, + int n_box) +{ + if (drawable->format->d.doublebuffer && n_box) + { + glitz_box_t rect; + glitz_surface_t *surface = NULL; + int x_pos, y_pos; + int x, y, w, h; + + GLITZ_GL_DRAWABLE (drawable); + + if (n_box == 1) + { + rect.x1 = x_origin + box->x1; + rect.y1 = y_origin + box->y1; + rect.x2 = x_origin + box->x2; + rect.y2 = y_origin + box->y2; + + if (rect.x1 <= 0 && + rect.y1 <= 0 && + rect.x2 >= drawable->width && + rect.x2 >= drawable->height) + { + if (drawable->backend->swap_buffers (drawable)) + { + if (drawable->front) + { + REGION_EMPTY (&drawable->front->drawable_damage); + glitz_surface_damage (drawable->front, NULL, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + return; + } + } + } + + if (drawable->front) + { + if (glitz_surface_push_current (drawable->front, + GLITZ_DRAWABLE_CURRENT)) + surface = drawable->front; + } + + if (!surface) + { + if (drawable->backend->push_current (drawable, NULL, + GLITZ_DRAWABLE_CURRENT)) + { + drawable->update_all = 1; + + gl->viewport (0, 0, drawable->width, drawable->height); + gl->matrix_mode (GLITZ_GL_PROJECTION); + gl->load_identity (); + gl->ortho (0.0, drawable->width, 0.0, + drawable->height, -1.0, 1.0); + gl->matrix_mode (GLITZ_GL_MODELVIEW); + gl->load_identity (); + gl->scale_f (1.0f, -1.0f, 1.0f); + gl->translate_f (0.0f, -drawable->height, 0.0f); + } + else + { + drawable->backend->pop_current (drawable); + return; + } + } + + gl->disable (GLITZ_GL_DITHER); + + gl->read_buffer (GLITZ_GL_BACK); + gl->draw_buffer (GLITZ_GL_FRONT); + + glitz_set_operator (gl, GLITZ_OPERATOR_SRC); + + x_pos = 0; + y_pos = 0; + + glitz_set_raster_pos (gl, x_pos, y_pos); + + while (n_box--) + { + rect.x1 = x_origin + box->x1; + rect.y1 = y_origin + box->y1; + rect.x2 = x_origin + box->x2; + rect.y2 = y_origin + box->y2; + + if (rect.x1 < rect.x2 && rect.y1 < rect.y2) + { + x = rect.x1; + y = drawable->height - rect.y2; + w = rect.x2 - rect.x1; + h = rect.y2 - rect.y1; + + if (x != x_pos || y != y_pos) + { + gl->bitmap (0, 0, 0, 0, x - x_pos, y - y_pos, NULL); + + x_pos = x; + y_pos = y; + } + + gl->scissor (x, y, w, h); + gl->copy_pixels (x, y, w, h, GLITZ_GL_COLOR); + + if (surface) + glitz_surface_damage (surface, &rect, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + + box++; + } + } + drawable->backend->gl->finish (); + + if (surface) + glitz_surface_pop_current (surface); + else + drawable->backend->pop_current (drawable); + } +} + +void glitz_drawable_swap_buffers (glitz_drawable_t *drawable) { - if (drawable->format->doublebuffer) - drawable->backend->swap_buffers (drawable); + glitz_box_t box; + + box.x1 = 0; + box.y1 = 0; + box.x2 = drawable->width; + box.y2 = drawable->height; + + glitz_drawable_swap_buffer_region (drawable, 0, 0, &box, 1); } slim_hidden_def(glitz_drawable_swap_buffers); void glitz_drawable_flush (glitz_drawable_t *drawable) { - drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT); - drawable->backend->gl.flush (); - drawable->backend->pop_current (drawable); + drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT); + drawable->backend->gl->flush (); + drawable->backend->pop_current (drawable); } slim_hidden_def(glitz_drawable_flush); void glitz_drawable_finish (glitz_drawable_t *drawable) { - drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT); - drawable->backend->gl.finish (); - drawable->backend->pop_current (drawable); + drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT); + drawable->backend->gl->finish (); + drawable->backend->pop_current (drawable); } slim_hidden_def(glitz_drawable_finish); unsigned long glitz_drawable_get_features (glitz_drawable_t *drawable) { - return drawable->backend->feature_mask; + return drawable->backend->feature_mask; } slim_hidden_def(glitz_drawable_get_features); glitz_drawable_format_t * glitz_drawable_get_format (glitz_drawable_t *drawable) { - return drawable->format; + return &drawable->format->d; } slim_hidden_def(glitz_drawable_get_format); diff --git a/src/glitz_filter.c b/src/glitz_filter.c index 4ec4444..cfe939d 100644 --- a/src/glitz_filter.c +++ b/src/glitz_filter.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -30,396 +30,408 @@ #include "glitzint.h" struct _glitz_filter_params_t { - int fp_type; - int id; - glitz_vec4_t *vectors; - int n_vectors; + int fp_type; + int id; + glitz_vec4_t *vectors; + int n_vectors; }; static glitz_status_t _glitz_filter_params_ensure (glitz_surface_t *surface, - int vectors) + int vectors) { int size; - + size = sizeof (glitz_filter_params_t) + vectors * sizeof (glitz_vec4_t); - + if (!surface->filter_params || - surface->filter_params->n_vectors != vectors) + surface->filter_params->n_vectors != vectors) { - if (surface->filter_params) - free (surface->filter_params); - - surface->filter_params = malloc (size); - if (surface->filter_params == NULL) - return GLITZ_STATUS_NO_MEMORY; - - surface->filter_params->fp_type = 0; - surface->filter_params->id = 0; - surface->filter_params->vectors = - (glitz_vec4_t *) (surface->filter_params + 1); - surface->filter_params->n_vectors = vectors; + if (surface->filter_params) + free (surface->filter_params); + + surface->filter_params = malloc (size); + if (surface->filter_params == NULL) + return GLITZ_STATUS_NO_MEMORY; + + surface->filter_params->fp_type = 0; + surface->filter_params->id = 0; + surface->filter_params->vectors = + (glitz_vec4_t *) (surface->filter_params + 1); + surface->filter_params->n_vectors = vectors; } - + return GLITZ_STATUS_SUCCESS; } static void _glitz_filter_params_set (glitz_float_t *value, - const glitz_float_t default_value, - glitz_fixed16_16_t **params, - int *n_params) + const glitz_float_t default_value, + glitz_fixed16_16_t **params, + int *n_params) { - if (*n_params > 0) { - *value = FIXED_TO_FLOAT (**params); - (*params)++; - (*n_params)--; - } else - *value = default_value; + if (*n_params > 0) { + *value = FIXED_TO_FLOAT (**params); + (*params)++; + (*n_params)--; + } else + *value = default_value; } static int _glitz_color_stop_compare (const void *elem1, const void *elem2) { - return - (((glitz_vec4_t *) elem1)->v[2] == ((glitz_vec4_t *) elem2)->v[2]) ? - /* equal offsets, sort on id */ - ((((glitz_vec4_t *) elem1)->v[3] < - ((glitz_vec4_t *) elem2)->v[3]) ? -1 : 1) : - /* sort on offset */ - ((((glitz_vec4_t *) elem1)->v[2] < - ((glitz_vec4_t *) elem2)->v[2]) ? -1 : 1); + return + (((glitz_vec4_t *) elem1)->v[2] == ((glitz_vec4_t *) elem2)->v[2]) ? + /* equal offsets, sort on id */ + ((((glitz_vec4_t *) elem1)->v[3] < + ((glitz_vec4_t *) elem2)->v[3]) ? -1 : 1) : + /* sort on offset */ + ((((glitz_vec4_t *) elem1)->v[2] < + ((glitz_vec4_t *) elem2)->v[2]) ? -1 : 1); } glitz_status_t glitz_filter_set_params (glitz_surface_t *surface, - glitz_filter_t filter, - glitz_fixed16_16_t *params, - int n_params) + glitz_filter_t filter, + glitz_fixed16_16_t *params, + int n_params) { - glitz_vec4_t *vecs; - int i, size = 0; - - switch (filter) { - case GLITZ_FILTER_CONVOLUTION: { - glitz_float_t dm, dn; - int cx, cy, m, n, j; - - _glitz_filter_params_set (&dm, 3.0f, ¶ms, &n_params); - _glitz_filter_params_set (&dn, 3.0f, ¶ms, &n_params); - m = dm; - n = dn; - - size = m * n; - if (_glitz_filter_params_ensure (surface, size)) - return GLITZ_STATUS_NO_MEMORY; - - vecs = surface->filter_params->vectors; - - surface->filter_params->id = 0; - - /* center point is rounded down in case dimensions are not even */ - cx = m / 2; - cy = n / 2; - - for (i = 0; i < m; i++) { - glitz_vec4_t *vec; - glitz_float_t weight; - - for (j = 0; j < n; j++) { - _glitz_filter_params_set (&weight, 0.0f, ¶ms, &n_params); - if (weight != 0.0f) { - vec = &vecs[surface->filter_params->id++]; - vec->v[0] = (i - cx) * surface->texture.texcoord_width_unit; - vec->v[1] = (cy - j) * surface->texture.texcoord_height_unit; - vec->v[2] = weight; - vec->v[3] = 0.0f; - } - } - } - } break; - case GLITZ_FILTER_GAUSSIAN: { - glitz_float_t radius, sigma, alpha, scale, xy_scale, sum; - int half_size, x, y; - - _glitz_filter_params_set (&radius, 1.0f, ¶ms, &n_params); - glitz_clamp_value (&radius, 0.0f, 1024.0f); - - _glitz_filter_params_set (&sigma, radius / 2.0f, ¶ms, &n_params); - glitz_clamp_value (&sigma, 0.0f, 1024.0f); - - _glitz_filter_params_set (&alpha, radius, ¶ms, &n_params); - glitz_clamp_value (&alpha, 0.0f, 1024.0f); - - scale = 1.0f / (2.0f * GLITZ_PI * sigma * sigma); - half_size = alpha + 0.5f; - - if (half_size == 0) - half_size = 1; - - size = half_size * 2 + 1; - xy_scale = 2.0f * radius / size; - - if (_glitz_filter_params_ensure (surface, size * size)) - return GLITZ_STATUS_NO_MEMORY; - - vecs = surface->filter_params->vectors; - - surface->filter_params->id = 0; - - sum = 0.0f; - for (x = 0; x < size; x++) { - glitz_vec4_t *vec; - glitz_float_t fx, fy, amp; - - fx = xy_scale * (x - half_size); - - for (y = 0; y < size; y++) { - fy = xy_scale * (y - half_size); - - amp = scale * exp ((-1.0f * (fx * fx + fy * fy)) / - (2.0f * sigma * sigma)); - - if (amp > 0.0f) { - vec = &vecs[surface->filter_params->id++]; - vec->v[0] = fx * surface->texture.texcoord_width_unit; - vec->v[1] = fy * surface->texture.texcoord_height_unit; - vec->v[2] = amp; - vec->v[3] = 0.0f; - sum += amp; - } - } - } + glitz_vec4_t *vecs; + int i, size = 0; + + switch (filter) { + case GLITZ_FILTER_CONVOLUTION: { + glitz_float_t dm, dn; + int cx, cy, m, n, j; + + _glitz_filter_params_set (&dm, 3.0f, ¶ms, &n_params); + _glitz_filter_params_set (&dn, 3.0f, ¶ms, &n_params); + m = dm; + n = dn; + + size = m * n; + if (_glitz_filter_params_ensure (surface, size)) + return GLITZ_STATUS_NO_MEMORY; + + vecs = surface->filter_params->vectors; + + surface->filter_params->id = 0; + + /* center point is rounded down in case dimensions are not even */ + cx = m / 2; + cy = n / 2; + + for (i = 0; i < m; i++) { + glitz_vec4_t *vec; + glitz_float_t weight; + + for (j = 0; j < n; j++) { + _glitz_filter_params_set (&weight, 0.0f, ¶ms, &n_params); + if (weight != 0.0f) { + vec = &vecs[surface->filter_params->id++]; + vec->v[0] = (i - cx) * surface->texture.texcoord_width_unit; + vec->v[1] = (cy - j) * surface->texture.texcoord_height_unit; + vec->v[2] = weight; + vec->v[3] = 0.0f; + } + } + } + } break; + case GLITZ_FILTER_GAUSSIAN: { + glitz_float_t radius, sigma, alpha, scale, xy_scale, sum; + int half_size, x, y; - /* normalize */ - if (sum != 0.0f) - sum = 1.0f / sum; - - for (i = 0; i < surface->filter_params->id; i++) - vecs[i].v[2] *= sum; - } break; - case GLITZ_FILTER_LINEAR_GRADIENT: - case GLITZ_FILTER_RADIAL_GRADIENT: - if (n_params <= 4) { - if (surface->box.x2 == 1) - size = surface->box.y2; - else if (surface->box.y2 == 1) - size = surface->box.x2; - } else - size = (n_params - 2) / 3; - - if (size < 2) - size = 2; - - if (_glitz_filter_params_ensure (surface, size + 1)) - return GLITZ_STATUS_NO_MEMORY; - - vecs = surface->filter_params->vectors; - - if (filter == GLITZ_FILTER_LINEAR_GRADIENT) { - glitz_float_t length, angle, dh, dv; - glitz_float_t start_x, start_y, stop_x, stop_y; - - _glitz_filter_params_set (&start_x, 0.0f, ¶ms, &n_params); - _glitz_filter_params_set (&start_y, 0.0f, ¶ms, &n_params); - _glitz_filter_params_set (&stop_x, 1.0f, ¶ms, &n_params); - _glitz_filter_params_set (&stop_y, 0.0f, ¶ms, &n_params); - - dh = stop_x - start_x; - dv = stop_y - start_y; - - length = sqrtf (dh * dh + dv * dv); - - angle = -atan2f (dv, dh); - - vecs->v[2] = cosf (angle); - vecs->v[3] = -sinf (angle); - - vecs->v[0] = vecs->v[2] * start_x; - vecs->v[0] += vecs->v[3] * start_y; - - vecs->v[1] = (length)? 1.0f / length: 2147483647.0f; - } else { - glitz_float_t r0, r1; - - _glitz_filter_params_set (&vecs->v[0], 0.5f, ¶ms, &n_params); - _glitz_filter_params_set (&vecs->v[1], 0.5f, ¶ms, &n_params); - _glitz_filter_params_set (&r0, 0.0f, ¶ms, &n_params); - _glitz_filter_params_set (&r1, 0.5f, ¶ms, &n_params); - - glitz_clamp_value (&r0, 0.0f, r1); - - vecs->v[2] = r0; - if (r1 != r0) - vecs->v[3] = 1.0f / (r1 - r0); - else - vecs->v[3] = 2147483647.0f; - } + _glitz_filter_params_set (&radius, 1.0f, ¶ms, &n_params); + glitz_clamp_value (&radius, 0.0f, 1024.0f); + + _glitz_filter_params_set (&sigma, radius / 2.0f, ¶ms, &n_params); + glitz_clamp_value (&sigma, 0.0f, 1024.0f); - vecs++; - surface->filter_params->id = size; - - for (i = 0; i < size; i++) { - glitz_float_t x_default, y_default, o_default; - - o_default = i / (glitz_float_t) (size - 1); - x_default = (surface->box.x2 * i) / (glitz_float_t) size; - y_default = (surface->box.y2 * i) / (glitz_float_t) size; - - _glitz_filter_params_set (&vecs[i].v[2], o_default, ¶ms, &n_params); - _glitz_filter_params_set (&vecs[i].v[0], x_default, ¶ms, &n_params); - _glitz_filter_params_set (&vecs[i].v[1], y_default, ¶ms, &n_params); - - glitz_clamp_value (&vecs[i].v[2], 0.0f, 1.0f); - glitz_clamp_value (&vecs[i].v[0], 0.0f, surface->box.x2 - 1.0f); - glitz_clamp_value (&vecs[i].v[1], 0.0f, surface->box.y2 - 1.0f); - - vecs[i].v[0] += 0.5f; - vecs[i].v[1] += 0.5f; - - vecs[i].v[0] += surface->texture.box.x1; - vecs[i].v[1] = surface->texture.box.y2 - vecs[i].v[1]; - - vecs[i].v[0] *= surface->texture.texcoord_width_unit; - vecs[i].v[1] *= surface->texture.texcoord_height_unit; - - vecs[i].v[3] = i; - } - - /* sort color stops in ascending order */ - qsort (vecs, surface->filter_params->id, sizeof (glitz_vec4_t), - _glitz_color_stop_compare); - - for (i = 0; i < size; i++) { - glitz_float_t diff; - - if ((i + 1) == size) - diff = 1.0f - vecs[i].v[2]; - else - diff = vecs[i + 1].v[2] - vecs[i].v[2]; - - if (diff != 0.0f) - vecs[i].v[3] = 1.0f / diff; - else - vecs[i].v[3] = 2147483647.0f; /* should be FLT_MAX, but this will do */ + _glitz_filter_params_set (&alpha, radius, ¶ms, &n_params); + glitz_clamp_value (&alpha, 0.0f, 1024.0f); + + scale = 1.0f / (2.0f * GLITZ_PI * sigma * sigma); + half_size = alpha + 0.5f; + + if (half_size == 0) + half_size = 1; + + size = half_size * 2 + 1; + xy_scale = 2.0f * radius / size; + + if (_glitz_filter_params_ensure (surface, size * size)) + return GLITZ_STATUS_NO_MEMORY; + + vecs = surface->filter_params->vectors; + + surface->filter_params->id = 0; + + sum = 0.0f; + for (x = 0; x < size; x++) { + glitz_vec4_t *vec; + glitz_float_t fx, fy, amp; + + fx = xy_scale * (x - half_size); + + for (y = 0; y < size; y++) { + fy = xy_scale * (y - half_size); + + amp = scale * exp ((-1.0f * (fx * fx + fy * fy)) / + (2.0f * sigma * sigma)); + + if (amp > 0.0f) { + vec = &vecs[surface->filter_params->id++]; + vec->v[0] = fx * surface->texture.texcoord_width_unit; + vec->v[1] = fy * surface->texture.texcoord_height_unit; + vec->v[2] = amp; + vec->v[3] = 0.0f; + sum += amp; + } + } + } + + /* normalize */ + if (sum != 0.0f) + sum = 1.0f / sum; + + for (i = 0; i < surface->filter_params->id; i++) + vecs[i].v[2] *= sum; + } break; + case GLITZ_FILTER_LINEAR_GRADIENT: + case GLITZ_FILTER_RADIAL_GRADIENT: + if (n_params <= 4) { + if (surface->box.x2 == 1) + size = surface->box.y2; + else if (surface->box.y2 == 1) + size = surface->box.x2; + } else + size = (n_params - 2) / 3; + + if (size < 2) + size = 2; + + if (_glitz_filter_params_ensure (surface, size + 1)) + return GLITZ_STATUS_NO_MEMORY; + + vecs = surface->filter_params->vectors; + + if (filter == GLITZ_FILTER_LINEAR_GRADIENT) { + glitz_float_t length, angle, dh, dv; + glitz_float_t start_x, start_y, stop_x, stop_y; + + _glitz_filter_params_set (&start_x, 0.0f, ¶ms, &n_params); + _glitz_filter_params_set (&start_y, 0.0f, ¶ms, &n_params); + _glitz_filter_params_set (&stop_x, 1.0f, ¶ms, &n_params); + _glitz_filter_params_set (&stop_y, 0.0f, ¶ms, &n_params); + + dh = stop_x - start_x; + dv = stop_y - start_y; + + length = sqrtf (dh * dh + dv * dv); + + angle = -atan2f (dv, dh); + + vecs->v[2] = cosf (angle); + vecs->v[3] = -sinf (angle); + + vecs->v[0] = vecs->v[2] * start_x; + vecs->v[0] += vecs->v[3] * start_y; + + vecs->v[1] = (length)? 1.0f / length: 2147483647.0f; + } else { + glitz_float_t r0, r1; + + _glitz_filter_params_set (&vecs->v[0], 0.5f, ¶ms, &n_params); + _glitz_filter_params_set (&vecs->v[1], 0.5f, ¶ms, &n_params); + _glitz_filter_params_set (&r0, 0.0f, ¶ms, &n_params); + _glitz_filter_params_set (&r1, 0.5f, ¶ms, &n_params); + + glitz_clamp_value (&r0, 0.0f, r1); + + vecs->v[2] = r0; + if (r1 != r0) + vecs->v[3] = 1.0f / (r1 - r0); + else + vecs->v[3] = 2147483647.0f; + } + + vecs++; + surface->filter_params->id = size; + + for (i = 0; i < size; i++) { + glitz_float_t x_default, y_default, o_default; + + o_default = i / (glitz_float_t) (size - 1); + x_default = (surface->box.x2 * i) / (glitz_float_t) size; + y_default = (surface->box.y2 * i) / (glitz_float_t) size; + + _glitz_filter_params_set (&vecs[i].v[2], o_default, ¶ms, + &n_params); + _glitz_filter_params_set (&vecs[i].v[0], x_default, ¶ms, + &n_params); + _glitz_filter_params_set (&vecs[i].v[1], y_default, ¶ms, + &n_params); + + glitz_clamp_value (&vecs[i].v[2], 0.0f, 1.0f); + glitz_clamp_value (&vecs[i].v[0], 0.0f, surface->box.x2 - 1.0f); + glitz_clamp_value (&vecs[i].v[1], 0.0f, surface->box.y2 - 1.0f); + + vecs[i].v[0] += 0.5f; + vecs[i].v[1] += 0.5f; + + vecs[i].v[0] += surface->texture.box.x1; + vecs[i].v[1] = surface->texture.box.y2 - vecs[i].v[1]; + + vecs[i].v[0] *= surface->texture.texcoord_width_unit; + vecs[i].v[1] *= surface->texture.texcoord_height_unit; + + vecs[i].v[3] = i; + } + + /* sort color stops in ascending order */ + qsort (vecs, surface->filter_params->id, sizeof (glitz_vec4_t), + _glitz_color_stop_compare); + + for (i = 0; i < size; i++) { + glitz_float_t diff; + + if ((i + 1) == size) + diff = 1.0f - vecs[i].v[2]; + else + diff = vecs[i + 1].v[2] - vecs[i].v[2]; + + if (diff != 0.0f) + vecs[i].v[3] = 1.0f / diff; + else + vecs[i].v[3] = 2147483647.0f; + } + break; + case GLITZ_FILTER_BILINEAR: + case GLITZ_FILTER_NEAREST: + if (surface->filter_params) + free (surface->filter_params); + + surface->filter_params = NULL; + break; } - break; - case GLITZ_FILTER_BILINEAR: - case GLITZ_FILTER_NEAREST: - if (surface->filter_params) - free (surface->filter_params); - - surface->filter_params = NULL; - break; - } - - glitz_filter_set_type (surface, filter); - - return GLITZ_STATUS_SUCCESS; + + glitz_filter_set_type (surface, filter); + + return GLITZ_STATUS_SUCCESS; } glitz_gl_uint_t glitz_filter_get_fragment_program (glitz_surface_t *surface, - glitz_composite_op_t *op) + glitz_composite_op_t *op) { - return glitz_get_fragment_program (op, - surface->filter_params->fp_type, - surface->filter_params->id); + return glitz_get_fragment_program (op, + surface->filter_params->fp_type, + surface->filter_params->id); } void glitz_filter_set_type (glitz_surface_t *surface, - glitz_filter_t filter) + glitz_filter_t filter) { - switch (filter) { - case GLITZ_FILTER_CONVOLUTION: - case GLITZ_FILTER_GAUSSIAN: - surface->filter_params->fp_type = GLITZ_FP_CONVOLUTION; - break; - case GLITZ_FILTER_LINEAR_GRADIENT: - if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) { - if (SURFACE_MIRRORED (surface)) - surface->filter_params->fp_type = GLITZ_FP_LINEAR_GRADIENT_REFLECT; - else - surface->filter_params->fp_type = GLITZ_FP_LINEAR_GRADIENT_REPEAT; - } else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) { - surface->filter_params->fp_type = GLITZ_FP_LINEAR_GRADIENT_NEAREST; - } else - surface->filter_params->fp_type = GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT; - break; - case GLITZ_FILTER_RADIAL_GRADIENT: - if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) { - if (SURFACE_MIRRORED (surface)) - surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_REFLECT; - else - surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_REPEAT; - } else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) { - surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_NEAREST; - } else - surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT; - break; - case GLITZ_FILTER_BILINEAR: - case GLITZ_FILTER_NEAREST: - break; - } + switch (filter) { + case GLITZ_FILTER_CONVOLUTION: + case GLITZ_FILTER_GAUSSIAN: + surface->filter_params->fp_type = GLITZ_FP_CONVOLUTION; + break; + case GLITZ_FILTER_LINEAR_GRADIENT: + if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) { + if (SURFACE_MIRRORED (surface)) + surface->filter_params->fp_type = + GLITZ_FP_LINEAR_GRADIENT_REFLECT; + else + surface->filter_params->fp_type = + GLITZ_FP_LINEAR_GRADIENT_REPEAT; + } else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) { + surface->filter_params->fp_type = + GLITZ_FP_LINEAR_GRADIENT_NEAREST; + } else + surface->filter_params->fp_type = + GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT; + break; + case GLITZ_FILTER_RADIAL_GRADIENT: + if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) { + if (SURFACE_MIRRORED (surface)) + surface->filter_params->fp_type = + GLITZ_FP_RADIAL_GRADIENT_REFLECT; + else + surface->filter_params->fp_type = + GLITZ_FP_RADIAL_GRADIENT_REPEAT; + } else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) { + surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_NEAREST; + } else + surface->filter_params->fp_type = + GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT; + break; + case GLITZ_FILTER_BILINEAR: + case GLITZ_FILTER_NEAREST: + break; + } } void glitz_filter_enable (glitz_surface_t *surface, - glitz_composite_op_t *op) + glitz_composite_op_t *op) { - glitz_gl_proc_address_list_t *gl = op->gl; - int i; - - gl->enable (GLITZ_GL_FRAGMENT_PROGRAM); - gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, op->fp); - - switch (surface->filter) { - case GLITZ_FILTER_GAUSSIAN: - case GLITZ_FILTER_CONVOLUTION: - for (i = 0; i < surface->filter_params->id; i++) - gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, i, - surface->filter_params->vectors[i].v); - break; - case GLITZ_FILTER_LINEAR_GRADIENT: - case GLITZ_FILTER_RADIAL_GRADIENT: { - int j, fp_type = surface->filter_params->fp_type; - glitz_vec4_t *vec; - - vec = surface->filter_params->vectors; - - gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, 0, vec->v); - - vec++; - - if (fp_type == GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT || - fp_type == GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT) { - glitz_vec4_t v; - - v.v[0] = v.v[1] = -1.0f; - v.v[2] = 0.0f; - v.v[3] = (vec->v[3])? 1.0f / vec->v[3]: 1.0f; - - gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, 1, v.v); - j = 2; - } else - j = 1; - - for (i = 0; i < surface->filter_params->id; i++, vec++) - gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, i + j, vec->v); - - if (fp_type == GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT || - fp_type == GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT) { - glitz_vec4_t v; - - v.v[0] = v.v[1] = -1.0f; - v.v[2] = v.v[3] = 1.0f; - - gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, i + j, v.v); - } - } break; - case GLITZ_FILTER_BILINEAR: - case GLITZ_FILTER_NEAREST: - break; - } + glitz_gl_proc_address_list_t *gl = op->gl; + int i; + + gl->enable (GLITZ_GL_FRAGMENT_PROGRAM); + gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, op->fp); + + switch (surface->filter) { + case GLITZ_FILTER_GAUSSIAN: + case GLITZ_FILTER_CONVOLUTION: + for (i = 0; i < surface->filter_params->id; i++) + gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, i, + surface->filter_params->vectors[i].v); + break; + case GLITZ_FILTER_LINEAR_GRADIENT: + case GLITZ_FILTER_RADIAL_GRADIENT: { + int j, fp_type = surface->filter_params->fp_type; + glitz_vec4_t *vec; + + vec = surface->filter_params->vectors; + + gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, 0, vec->v); + + vec++; + + if (fp_type == GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT || + fp_type == GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT) { + glitz_vec4_t v; + + v.v[0] = v.v[1] = -1.0f; + v.v[2] = 0.0f; + v.v[3] = (vec->v[3])? 1.0f / vec->v[3]: 1.0f; + + gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, 1, v.v); + j = 2; + } else + j = 1; + + for (i = 0; i < surface->filter_params->id; i++, vec++) + gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, + i + j, vec->v); + + if (fp_type == GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT || + fp_type == GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT) { + glitz_vec4_t v; + + v.v[0] = v.v[1] = -1.0f; + v.v[2] = v.v[3] = 1.0f; + + gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, + i + j, v.v); + } + } break; + case GLITZ_FILTER_BILINEAR: + case GLITZ_FILTER_NEAREST: + break; + } } diff --git a/src/glitz_format.c b/src/glitz_format.c index d359690..8e93e3a 100644 --- a/src/glitz_format.c +++ b/src/glitz_format.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -32,254 +32,387 @@ #include <stdlib.h> struct _texture_format { - glitz_gl_int_t texture_format; - glitz_format_t format; + glitz_gl_int_t texture_format; + glitz_format_t format; } _texture_formats[] = { - { GLITZ_GL_ALPHA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 4 } } }, - { GLITZ_GL_ALPHA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 8 } } }, - { GLITZ_GL_ALPHA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 12 } } }, - { GLITZ_GL_ALPHA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 16 } } }, - { GLITZ_GL_R3_G3_B2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 3, 3, 2, 0 } } }, - { GLITZ_GL_RGB4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 0 } } }, - { GLITZ_GL_RGB5, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 6, 5, 0 } } }, - { GLITZ_GL_RGB8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 0 } } }, - { GLITZ_GL_RGB10, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 0 } } }, - { GLITZ_GL_RGB12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 0 } } }, - { GLITZ_GL_RGB16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 0 } } }, - { GLITZ_GL_RGBA2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 2, 2, 2, 2 } } }, - { GLITZ_GL_RGB5_A1, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 5, 5, 1 } } }, - { GLITZ_GL_RGBA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 4 } } }, - { GLITZ_GL_RGBA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 8 } } }, - { GLITZ_GL_RGB10_A2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 2 } } }, - { GLITZ_GL_RGBA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 12 } } }, - { GLITZ_GL_RGBA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 16 } } } + { GLITZ_GL_ALPHA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 4 } } }, + { GLITZ_GL_ALPHA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 8 } } }, + { GLITZ_GL_ALPHA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 12 } } }, + { GLITZ_GL_ALPHA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 16 } } }, + { GLITZ_GL_R3_G3_B2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 3, 3, 2, 0 } } }, + { GLITZ_GL_RGB4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 0 } } }, + { GLITZ_GL_RGB5, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 6, 5, 0 } } }, + { GLITZ_GL_RGB8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 0 } } }, + { GLITZ_GL_RGB10, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 0 } } }, + { GLITZ_GL_RGB12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 0 } } }, + { GLITZ_GL_RGB16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 0 } } }, + { GLITZ_GL_RGBA2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 2, 2, 2, 2 } } }, + { GLITZ_GL_RGB5_A1, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 5, 5, 1 } } }, + { GLITZ_GL_RGBA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 4 } } }, + { GLITZ_GL_RGBA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 8 } } }, + { GLITZ_GL_RGB10_A2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 2 } } }, + { GLITZ_GL_RGBA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 12 } } }, + { GLITZ_GL_RGBA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 16 } } } }; static void _glitz_add_texture_format (glitz_format_t **formats, - glitz_gl_int_t **texture_formats, - int *n_formats, - glitz_gl_int_t texture_format, - glitz_format_t *format) + glitz_gl_int_t **texture_formats, + int *n_formats, + glitz_gl_int_t texture_format, + glitz_format_t *format) { - *formats = realloc (*formats, sizeof (glitz_format_t) * (*n_formats + 1)); - *texture_formats = realloc (*texture_formats, - sizeof (glitz_gl_enum_t) * (*n_formats + 1)); - - if (*formats && *texture_formats) { - (*texture_formats)[*n_formats] = texture_format; - (*formats)[*n_formats] = *format; - (*formats)[*n_formats].id = *n_formats; - (*n_formats)++; - } else - *n_formats = 0; + *formats = realloc (*formats, sizeof (glitz_format_t) * (*n_formats + 1)); + *texture_formats = realloc (*texture_formats, + sizeof (glitz_gl_enum_t) * (*n_formats + 1)); + + if (*formats && *texture_formats) { + (*texture_formats)[*n_formats] = texture_format; + (*formats)[*n_formats] = *format; + (*formats)[*n_formats].id = *n_formats; + (*n_formats)++; + } else + *n_formats = 0; } void glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl, - glitz_format_t **formats, - glitz_gl_int_t **texture_formats, - int *n_formats) + glitz_format_t **formats, + glitz_gl_int_t **texture_formats, + int *n_formats) { - glitz_gl_int_t value; - int i, n_texture_formats; - - n_texture_formats = - sizeof (_texture_formats) / sizeof (struct _texture_format); - - for (i = 0; i < n_texture_formats; i++) { - gl->tex_image_2d (GLITZ_GL_PROXY_TEXTURE_2D, 0, - _texture_formats[i].texture_format, 1, 1, 0, - GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL); - - switch (_texture_formats[i].format.type) { - case GLITZ_FORMAT_TYPE_COLOR: - if (_texture_formats[i].format.color.red_size) { - gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, - GLITZ_GL_TEXTURE_RED_SIZE, &value); - if (value != _texture_formats[i].format.color.red_size) - continue; - } - - if (_texture_formats[i].format.color.green_size) { - gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, - GLITZ_GL_TEXTURE_GREEN_SIZE, &value); - if (value != _texture_formats[i].format.color.green_size) - continue; - } - - if (_texture_formats[i].format.color.blue_size) { - gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, - GLITZ_GL_TEXTURE_BLUE_SIZE, &value); - if (value != _texture_formats[i].format.color.blue_size) - continue; - } - - if (_texture_formats[i].format.color.alpha_size) { - gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, - GLITZ_GL_TEXTURE_ALPHA_SIZE, &value); - if (value != _texture_formats[i].format.color.alpha_size) - continue; - } - break; - default: - continue; + glitz_gl_int_t value; + int i, n_texture_formats; + + n_texture_formats = + sizeof (_texture_formats) / sizeof (struct _texture_format); + + for (i = 0; i < n_texture_formats; i++) { + gl->tex_image_2d (GLITZ_GL_PROXY_TEXTURE_2D, 0, + _texture_formats[i].texture_format, 1, 1, 0, + GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL); + + switch (_texture_formats[i].format.type) { + case GLITZ_FORMAT_TYPE_COLOR: + if (_texture_formats[i].format.color.red_size) { + gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, + GLITZ_GL_TEXTURE_RED_SIZE, + &value); + if (value != _texture_formats[i].format.color.red_size) + continue; + } + + if (_texture_formats[i].format.color.green_size) { + gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, + GLITZ_GL_TEXTURE_GREEN_SIZE, + &value); + if (value != _texture_formats[i].format.color.green_size) + continue; + } + + if (_texture_formats[i].format.color.blue_size) { + gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, + GLITZ_GL_TEXTURE_BLUE_SIZE, + &value); + if (value != _texture_formats[i].format.color.blue_size) + continue; + } + + if (_texture_formats[i].format.color.alpha_size) { + gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, + GLITZ_GL_TEXTURE_ALPHA_SIZE, + &value); + if (value != _texture_formats[i].format.color.alpha_size) + continue; + } + break; + default: + continue; + } + + _glitz_add_texture_format (formats, + texture_formats, + n_formats, + _texture_formats[i].texture_format, + &_texture_formats[i].format); } - - _glitz_add_texture_format (formats, - texture_formats, - n_formats, - _texture_formats[i].texture_format, - &_texture_formats[i].format); - } } -glitz_drawable_format_t * -glitz_drawable_format_find (glitz_drawable_format_t *formats, - int n_formats, - unsigned long mask, - const glitz_drawable_format_t *templ, - int count) +static void +_glitz_add_drawable_format (glitz_int_drawable_format_t *format, + glitz_int_drawable_format_t **formats, + int *n_formats) +{ + void *ptr; + + ptr = realloc (*formats, + sizeof (glitz_int_drawable_format_t) * (*n_formats + 1)); + if (ptr) + { + *formats = ptr; + (*formats)[*n_formats] = *format; + (*n_formats)++; + } +} + +/* TODO: Available drawable formats needs to be validated is a similar way + as surface formats. */ +void +_glitz_add_drawable_formats (glitz_gl_proc_address_list_t *gl, + unsigned long feature_mask, + glitz_int_drawable_format_t **formats, + int *n_formats) +{ + if (feature_mask & GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) + { + glitz_int_drawable_format_t format; + glitz_drawable_format_t d[] = { + { 0, { 8, 8, 8, 0 }, 0, 0, 1, 0 }, + { 0, { 8, 8, 8, 8 }, 0, 0, 1, 0 }, + { 0, { 8, 8, 8, 0 }, 24, 8, 1, 1 }, + { 0, { 8, 8, 8, 8 }, 24, 8, 1, 1 } + }; + int i; + + format.types = GLITZ_DRAWABLE_TYPE_FBO_MASK; + format.caveat = 0; + format.u.val = 0; + + for (i = 0; i < sizeof (d) / sizeof (d[0]); i++) + { + format.d = d[i]; + format.d.id = *n_formats; + + _glitz_add_drawable_format (&format, formats, n_formats); + } + } +} + +void +glitz_drawable_format_copy (const glitz_drawable_format_t *src, + glitz_drawable_format_t *dst, + unsigned long mask) { - for (; n_formats; n_formats--, formats++) { if (mask & GLITZ_FORMAT_ID_MASK) - if (templ->id != formats->id) - continue; + dst->id = src->id; if (mask & GLITZ_FORMAT_RED_SIZE_MASK) - if (templ->color.red_size != formats->color.red_size) - continue; + dst->color.red_size = src->color.red_size; if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK) - if (templ->color.green_size != formats->color.green_size) - continue; + dst->color.green_size = src->color.green_size; if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK) - if (templ->color.blue_size != formats->color.blue_size) - continue; + dst->color.blue_size = src->color.blue_size; if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK) - if (templ->color.alpha_size != formats->color.alpha_size) - continue; + dst->color.alpha_size = src->color.alpha_size; if (mask & GLITZ_FORMAT_DEPTH_SIZE_MASK) - if (templ->depth_size != formats->depth_size) - continue; + dst->depth_size = src->depth_size; if (mask & GLITZ_FORMAT_STENCIL_SIZE_MASK) - if (templ->stencil_size != formats->stencil_size) - continue; + dst->stencil_size = src->stencil_size; if (mask & GLITZ_FORMAT_DOUBLEBUFFER_MASK) - if (templ->doublebuffer != formats->doublebuffer) - continue; + dst->doublebuffer = src->doublebuffer; if (mask & GLITZ_FORMAT_SAMPLES_MASK) - if (templ->samples != formats->samples) - continue; - - if (mask & GLITZ_FORMAT_WINDOW_MASK) - if (templ->types.window != formats->types.window) - continue; - - if (mask & GLITZ_FORMAT_PBUFFER_MASK) - if (templ->types.pbuffer != formats->types.pbuffer) - continue; - - if (count-- == 0) - return formats; - } - - return NULL; + dst->samples = src->samples; +} + +glitz_drawable_format_t * +glitz_drawable_format_find (glitz_int_drawable_format_t *formats, + int n_formats, + unsigned long mask, + const glitz_int_drawable_format_t *templ, + int count) +{ + for (; n_formats; n_formats--, formats++) + { + if (mask & GLITZ_FORMAT_ID_MASK) + if (templ->d.id != formats->d.id) + continue; + + if (mask & GLITZ_FORMAT_RED_SIZE_MASK) + if (templ->d.color.red_size != formats->d.color.red_size) + continue; + + if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK) + if (templ->d.color.green_size != formats->d.color.green_size) + continue; + + if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK) + if (templ->d.color.blue_size != formats->d.color.blue_size) + continue; + + if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK) + if (templ->d.color.alpha_size != formats->d.color.alpha_size) + continue; + + if (mask & GLITZ_FORMAT_DEPTH_SIZE_MASK) + if (templ->d.depth_size != formats->d.depth_size) + continue; + + if (mask & GLITZ_FORMAT_STENCIL_SIZE_MASK) + if (templ->d.stencil_size != formats->d.stencil_size) + continue; + + if (mask & GLITZ_FORMAT_DOUBLEBUFFER_MASK) + if (templ->d.doublebuffer != formats->d.doublebuffer) + continue; + + if (mask & GLITZ_FORMAT_SAMPLES_MASK) + if (templ->d.samples != formats->d.samples) + continue; + + if (mask & GLITZ_INT_FORMAT_WINDOW_MASK) + if ((templ->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK) != + (formats->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK)) + continue; + + if (mask & GLITZ_INT_FORMAT_PBUFFER_MASK) + if ((templ->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK) != + (formats->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK)) + continue; + + if (mask & GLITZ_INT_FORMAT_FBO_MASK) + if ((templ->types & GLITZ_DRAWABLE_TYPE_FBO_MASK) != + (formats->types & GLITZ_DRAWABLE_TYPE_FBO_MASK)) + continue; + + if (count-- == 0) + return &formats->d; + } + + return NULL; } static glitz_format_t * _glitz_format_find (glitz_format_t *formats, - int n_formats, - unsigned long mask, - const glitz_format_t *templ, - int count) + int n_formats, + unsigned long mask, + const glitz_format_t *templ, + int count) { - for (; n_formats; n_formats--, formats++) { - if (mask & GLITZ_FORMAT_ID_MASK) - if (templ->id != formats->id) - continue; + for (; n_formats; n_formats--, formats++) { + if (mask & GLITZ_FORMAT_ID_MASK) + if (templ->id != formats->id) + continue; - if (mask & GLITZ_FORMAT_TYPE_MASK) - if (templ->type != formats->type) - continue; + if (mask & GLITZ_FORMAT_TYPE_MASK) + if (templ->type != formats->type) + continue; - if (mask & GLITZ_FORMAT_RED_SIZE_MASK) - if (templ->color.red_size != formats->color.red_size) - continue; + if (mask & GLITZ_FORMAT_RED_SIZE_MASK) + if (templ->color.red_size != formats->color.red_size) + continue; - if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK) - if (templ->color.green_size != formats->color.green_size) - continue; + if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK) + if (templ->color.green_size != formats->color.green_size) + continue; - if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK) - if (templ->color.blue_size != formats->color.blue_size) - continue; + if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK) + if (templ->color.blue_size != formats->color.blue_size) + continue; - if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK) - if (templ->color.alpha_size != formats->color.alpha_size) - continue; + if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK) + if (templ->color.alpha_size != formats->color.alpha_size) + continue; - if (count-- == 0) - return formats; - } + if (count-- == 0) + return formats; + } - return NULL; + return NULL; } glitz_format_t * glitz_find_format (glitz_drawable_t *drawable, - unsigned long mask, - const glitz_format_t *templ, - int count) + unsigned long mask, + const glitz_format_t *templ, + int count) { - return _glitz_format_find (drawable->backend->formats, - drawable->backend->n_formats, - mask, templ, count); + return _glitz_format_find (drawable->backend->formats, + drawable->backend->n_formats, + mask, templ, count); } glitz_format_t * glitz_find_standard_format (glitz_drawable_t *drawable, - glitz_format_name_t format_name) + glitz_format_name_t format_name) +{ + glitz_format_t templ; + unsigned long mask = GLITZ_FORMAT_RED_SIZE_MASK | + GLITZ_FORMAT_GREEN_SIZE_MASK | GLITZ_FORMAT_BLUE_SIZE_MASK | + GLITZ_FORMAT_ALPHA_SIZE_MASK | GLITZ_FORMAT_TYPE_MASK; + + templ.type = GLITZ_FORMAT_TYPE_COLOR; + + switch (format_name) { + case GLITZ_STANDARD_ARGB32: + templ.color.red_size = 8; + templ.color.green_size = 8; + templ.color.blue_size = 8; + templ.color.alpha_size = 8; + break; + case GLITZ_STANDARD_RGB24: + templ.color.red_size = 8; + templ.color.green_size = 8; + templ.color.blue_size = 8; + templ.color.alpha_size = 0; + break; + case GLITZ_STANDARD_A8: + templ.color.red_size = 0; + templ.color.green_size = 0; + templ.color.blue_size = 0; + templ.color.alpha_size = 8; + break; + case GLITZ_STANDARD_A1: + templ.color.red_size = 0; + templ.color.green_size = 0; + templ.color.blue_size = 0; + templ.color.alpha_size = 1; + break; + } + + return glitz_find_format (drawable, mask, &templ, 0); +} + +glitz_drawable_format_t * +glitz_find_drawable_format (glitz_drawable_t *other, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count) { - glitz_format_t templ; - unsigned long mask = GLITZ_FORMAT_RED_SIZE_MASK | - GLITZ_FORMAT_GREEN_SIZE_MASK | GLITZ_FORMAT_BLUE_SIZE_MASK | - GLITZ_FORMAT_ALPHA_SIZE_MASK | GLITZ_FORMAT_TYPE_MASK; - - templ.type = GLITZ_FORMAT_TYPE_COLOR; - - switch (format_name) { - case GLITZ_STANDARD_ARGB32: - templ.color.red_size = 8; - templ.color.green_size = 8; - templ.color.blue_size = 8; - templ.color.alpha_size = 8; - break; - case GLITZ_STANDARD_RGB24: - templ.color.red_size = 8; - templ.color.green_size = 8; - templ.color.blue_size = 8; - templ.color.alpha_size = 0; - break; - case GLITZ_STANDARD_A8: - templ.color.red_size = 0; - templ.color.green_size = 0; - templ.color.blue_size = 0; - templ.color.alpha_size = 8; - break; - case GLITZ_STANDARD_A1: - templ.color.red_size = 0; - templ.color.green_size = 0; - templ.color.blue_size = 0; - templ.color.alpha_size = 1; - break; - } - - return glitz_find_format (drawable, mask, &templ, 0); + glitz_int_drawable_format_t itempl; + + glitz_drawable_format_copy (templ, &itempl.d, mask); + + itempl.types = GLITZ_DRAWABLE_TYPE_FBO_MASK; + mask |= GLITZ_INT_FORMAT_FBO_MASK; + + return glitz_drawable_format_find (other->backend->drawable_formats, + other->backend->n_drawable_formats, + mask, &itempl, count); +} +slim_hidden_def(glitz_find_drawable_format); + +glitz_drawable_format_t * +glitz_find_pbuffer_format (glitz_drawable_t *other, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count) +{ + glitz_int_drawable_format_t itempl; + + glitz_drawable_format_copy (templ, &itempl.d, mask); + + itempl.types = GLITZ_DRAWABLE_TYPE_PBUFFER_MASK; + mask |= GLITZ_INT_FORMAT_PBUFFER_MASK; + + return glitz_drawable_format_find (other->backend->drawable_formats, + other->backend->n_drawable_formats, + mask, &itempl, count); } +slim_hidden_def(glitz_find_pbuffer_format); diff --git a/src/glitz_framebuffer.c b/src/glitz_framebuffer.c index 87edbe4..69e7381 100644 --- a/src/glitz_framebuffer.c +++ b/src/glitz_framebuffer.c @@ -1,6 +1,6 @@ /* * Copyright © 2005 Novell, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -29,48 +29,375 @@ #include "glitzint.h" -void -glitz_framebuffer_init (glitz_framebuffer_t *framebuffer) +typedef struct _glitz_fbo_drawable { + glitz_drawable_t base; + glitz_drawable_t *other; + int width; + int height; + glitz_gl_uint_t fb; + glitz_gl_uint_t front; + glitz_gl_uint_t back; + glitz_gl_uint_t depth; + glitz_gl_uint_t stencil; + glitz_gl_uint_t front_texture; + glitz_gl_uint_t back_texture; + glitz_gl_enum_t internal_format; +} glitz_fbo_drawable_t; + +static glitz_bool_t +_glitz_fbo_bind (glitz_fbo_drawable_t *drawable) { - framebuffer->name = 0; + glitz_bool_t update = 0; + glitz_gl_enum_t status; + + GLITZ_GL_DRAWABLE (drawable->other); + + if (!drawable->fb) + { + gl->gen_framebuffers (1, &drawable->fb); + + drawable->width = drawable->base.width; + drawable->height = drawable->base.height; + update = 1; + } + else if (drawable->width != drawable->base.width || + drawable->height != drawable->base.height) + { + drawable->width = drawable->base.width; + drawable->height = drawable->base.height; + update = 1; + } + + gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, drawable->fb); + + if (drawable->base.front && + drawable->front_texture != drawable->base.front->texture.name) + { + gl->framebuffer_texture_2d (GLITZ_GL_FRAMEBUFFER, + GLITZ_GL_COLOR_ATTACHMENT0, + drawable->base.front->texture.target, + drawable->base.front->texture.name, + 0); + + drawable->front_texture = drawable->base.front->texture.name; + + if (drawable->front) + { + gl->delete_renderbuffers (1, &drawable->front); + drawable->front = 0; + } + } + + if (!drawable->front_texture && !drawable->front) + { + gl->gen_renderbuffers (1, &drawable->front); + gl->bind_renderbuffer (GLITZ_GL_RENDERBUFFER, drawable->front); + gl->renderbuffer_storage (GLITZ_GL_RENDERBUFFER, + drawable->internal_format, + drawable->base.width, + drawable->base.height); + gl->bind_renderbuffer (GLITZ_GL_RENDERBUFFER, 0); + gl->framebuffer_renderbuffer (GLITZ_GL_FRAMEBUFFER, + GLITZ_GL_COLOR_ATTACHMENT0, + GLITZ_GL_RENDERBUFFER, + drawable->front); + } + + if (drawable->base.format->d.doublebuffer) + { + if (drawable->base.back && + drawable->back_texture != drawable->base.back->texture.name) + { + gl->framebuffer_texture_2d (GLITZ_GL_FRAMEBUFFER, + GLITZ_GL_COLOR_ATTACHMENT1, + drawable->base.back->texture.target, + drawable->base.back->texture.name, + 0); + + drawable->back_texture = drawable->base.back->texture.name; + + if (drawable->back) + { + gl->delete_renderbuffers (1, &drawable->back); + drawable->back = 0; + } + } + + if (!drawable->back_texture && !drawable->back) + { + gl->gen_renderbuffers (1, &drawable->back); + gl->bind_renderbuffer (GLITZ_GL_RENDERBUFFER, + drawable->back); + gl->renderbuffer_storage (GLITZ_GL_RENDERBUFFER, + drawable->internal_format, + drawable->base.width, + drawable->base.height); + gl->bind_renderbuffer (GLITZ_GL_RENDERBUFFER, 0); + gl->framebuffer_renderbuffer (GLITZ_GL_FRAMEBUFFER, + GLITZ_GL_COLOR_ATTACHMENT1, + GLITZ_GL_RENDERBUFFER, + drawable->back); + } + } + + if (update) + { + if (drawable->base.format->d.depth_size) + { + if (!drawable->depth) + gl->gen_renderbuffers (1, &drawable->depth); + + gl->bind_renderbuffer (GLITZ_GL_RENDERBUFFER, drawable->depth); + gl->renderbuffer_storage (GLITZ_GL_RENDERBUFFER, + GLITZ_GL_DEPTH_COMPONENT, + drawable->base.width, + drawable->base.height); + gl->bind_renderbuffer (GLITZ_GL_RENDERBUFFER, 0); + + gl->framebuffer_renderbuffer (GLITZ_GL_FRAMEBUFFER, + GLITZ_GL_DEPTH_ATTACHMENT, + GLITZ_GL_RENDERBUFFER, + drawable->depth); + } + + if (drawable->base.format->d.stencil_size) + { + if (!drawable->stencil) + gl->gen_renderbuffers (1, &drawable->stencil); + + gl->bind_renderbuffer (GLITZ_GL_RENDERBUFFER, + drawable->stencil); + gl->renderbuffer_storage (GLITZ_GL_RENDERBUFFER, + GLITZ_GL_STENCIL_INDEX, + drawable->base.width, + drawable->base.height); + gl->bind_renderbuffer (GLITZ_GL_RENDERBUFFER, 0); + + gl->framebuffer_renderbuffer (GLITZ_GL_FRAMEBUFFER, + GLITZ_GL_STENCIL_ATTACHMENT, + GLITZ_GL_RENDERBUFFER, + drawable->stencil); + } + } + + status = gl->check_framebuffer_status (GLITZ_GL_FRAMEBUFFER); + if (status == GLITZ_GL_FRAMEBUFFER_COMPLETE) + return 1; + + return 0; } -void -glitz_framebuffer_fini (glitz_gl_proc_address_list_t *gl, - glitz_framebuffer_t *framebuffer) +static void +_glitz_fbo_attach_notify (void *abstract_drawable, + glitz_surface_t *surface) { - if (framebuffer->name) - gl->delete_framebuffers (1, &framebuffer->name); + glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *) + abstract_drawable; + glitz_texture_t *texture; + + GLITZ_GL_DRAWABLE (drawable->other); + + texture = &surface->texture; + if (!TEXTURE_ALLOCATED (texture)) + { + drawable->other->backend->push_current (drawable->other, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + glitz_texture_allocate (gl, texture); + drawable->other->backend->pop_current (drawable->other); + + if (!TEXTURE_ALLOCATED (texture)) + return; + } + + REGION_EMPTY (&surface->drawable_damage); } -void -glitz_framebuffer_unbind (glitz_gl_proc_address_list_t *gl) +static void +_glitz_fbo_detach_notify (void *abstract_drawable, + glitz_surface_t *surface) { + glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *) + abstract_drawable; + + if (surface->texture.name == drawable->front_texture || + surface->texture.name == drawable->back_texture) + { + GLITZ_GL_DRAWABLE (drawable->other); + + drawable->other->backend->push_current (drawable->other, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + + gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, drawable->fb); + + if (surface->texture.name == drawable->front_texture) + { + gl->framebuffer_texture_2d (GLITZ_GL_FRAMEBUFFER, + GLITZ_GL_COLOR_ATTACHMENT0, + surface->texture.target, + 0, 0); + drawable->front_texture = 0; + } + + if (surface->texture.name == drawable->back_texture) + { + gl->framebuffer_texture_2d (GLITZ_GL_FRAMEBUFFER, + GLITZ_GL_COLOR_ATTACHMENT1, + surface->texture.target, + 0, 0); + drawable->back_texture = 0; + } + + gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, 0); + + surface->fb = 0; + + drawable->other->backend->pop_current (drawable->other); + } +} + +static glitz_bool_t +_glitz_fbo_push_current (void *abstract_drawable, + glitz_surface_t *surface, + glitz_constraint_t constraint) +{ + glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *) + abstract_drawable; + + drawable->other->backend->push_current (drawable->other, surface, + constraint); + + if (constraint == GLITZ_DRAWABLE_CURRENT) + { + if (_glitz_fbo_bind (drawable)) + { + drawable->base.update_all = drawable->other->update_all = 1; + surface->fb = drawable->fb; + return 1; + } + } + + return 0; +} + +static glitz_surface_t * +_glitz_fbo_pop_current (void *abstract_drawable) +{ + glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *) + abstract_drawable; + + GLITZ_GL_DRAWABLE (drawable->other); + gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, 0); + + return drawable->other->backend->pop_current (drawable->other); +} + +static void +_glitz_fbo_make_current (void *abstract_drawable, + void *abstract_context) +{ + glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *) + abstract_drawable; + + drawable->other->backend->make_current (drawable->other, abstract_context); + + _glitz_fbo_bind (drawable); +} + +static glitz_bool_t +_glitz_fbo_swap_buffers (void *abstract_drawable) +{ + glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *) + abstract_drawable; + + if (!drawable->fb) + return 1; + + return 0; } -glitz_bool_t -glitz_framebuffer_complete (glitz_gl_proc_address_list_t *gl, - glitz_framebuffer_t *framebuffer, - glitz_texture_t *texture) -{ - if (!framebuffer->name) +static void +_glitz_fbo_destroy (void *abstract_drawable) +{ + glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *) + abstract_drawable; + + if (drawable->fb) { - if (!TEXTURE_ALLOCATED (texture)) - glitz_texture_allocate (gl, texture); - - gl->gen_framebuffers (1, &framebuffer->name); - - gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, framebuffer->name); - - gl->framebuffer_texture_2d (GLITZ_GL_FRAMEBUFFER, - GLITZ_GL_COLOR_ATTACHMENT0, - GLITZ_GL_TEXTURE_2D, texture->name, - 0); + GLITZ_GL_DRAWABLE (drawable->other); + + drawable->other->backend->push_current (drawable->other, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + + gl->delete_framebuffers (1, &drawable->fb); + + if (drawable->front) + gl->delete_renderbuffers (1, &drawable->front); + + if (drawable->back) + gl->delete_renderbuffers (1, &drawable->back); + + if (drawable->depth) + gl->delete_renderbuffers (1, &drawable->depth); + + if (drawable->stencil) + gl->delete_renderbuffers (1, &drawable->stencil); + + drawable->other->backend->pop_current (drawable->other); } + + glitz_drawable_destroy (drawable->other); + + free (drawable); +} + +glitz_drawable_t * +_glitz_fbo_drawable_create (glitz_drawable_t *other, + glitz_int_drawable_format_t *format, + int width, + int height) +{ + glitz_fbo_drawable_t *drawable; + glitz_backend_t *backend; + + drawable = malloc (sizeof (glitz_fbo_drawable_t) + + sizeof (glitz_backend_t)); + if (!drawable) + return NULL; + + glitz_drawable_reference (other); + drawable->other = other; + backend = (glitz_backend_t *) (drawable + 1); + *backend = *other->backend; + + backend->destroy = _glitz_fbo_destroy; + backend->push_current = _glitz_fbo_push_current; + backend->pop_current = _glitz_fbo_pop_current; + backend->attach_notify = _glitz_fbo_attach_notify; + backend->detach_notify = _glitz_fbo_detach_notify; + backend->swap_buffers = _glitz_fbo_swap_buffers; + backend->make_current = _glitz_fbo_make_current; + + drawable->fb = 0; + + drawable->width = 0; + drawable->height = 0; + + drawable->front = 0; + drawable->back = 0; + drawable->depth = 0; + drawable->stencil = 0; + + drawable->front_texture = 0; + drawable->back_texture = 0; + + /* XXX: temporary solution until we have proper format validation */ + if (format->d.color.alpha_size) + drawable->internal_format = GLITZ_GL_RGBA; else - gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, framebuffer->name); + drawable->internal_format = GLITZ_GL_RGB; + + _glitz_drawable_init (&drawable->base, format, backend, width, height); - return (gl->check_framebuffer_status (GLITZ_GL_FRAMEBUFFER) == - GLITZ_GL_FRAMEBUFFER_COMPLETE); + return &drawable->base; } diff --git a/src/glitz_geometry.c b/src/glitz_geometry.c index 9c16aa9..4a5cbdf 100644 --- a/src/glitz_geometry.c +++ b/src/glitz_geometry.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -35,151 +35,151 @@ _glitz_data_type (glitz_data_type_t type) { switch (type) { case GLITZ_DATA_TYPE_SHORT: - return GLITZ_GL_SHORT; + return GLITZ_GL_SHORT; case GLITZ_DATA_TYPE_INT: - return GLITZ_GL_INT; + return GLITZ_GL_INT; case GLITZ_DATA_TYPE_DOUBLE: - return GLITZ_GL_DOUBLE; + return GLITZ_GL_DOUBLE; default: - return GLITZ_GL_FLOAT; + return GLITZ_GL_FLOAT; } } void glitz_set_geometry (glitz_surface_t *dst, - glitz_geometry_type_t type, - glitz_geometry_format_t *format, - glitz_buffer_t *buffer) + glitz_geometry_type_t type, + glitz_geometry_format_t *format, + glitz_buffer_t *buffer) { switch (type) { case GLITZ_GEOMETRY_TYPE_VERTEX: { - glitz_buffer_reference (buffer); - if (dst->geometry.buffer) - glitz_buffer_destroy (dst->geometry.buffer); - dst->geometry.buffer = buffer; - - dst->geometry.type = GLITZ_GEOMETRY_TYPE_VERTEX; - - switch (format->vertex.primitive) { - case GLITZ_PRIMITIVE_POINTS: - dst->geometry.u.v.prim = GLITZ_GL_POINTS; - break; - case GLITZ_PRIMITIVE_LINES: - dst->geometry.u.v.prim = GLITZ_GL_LINES; - break; - case GLITZ_PRIMITIVE_LINE_STRIP: - dst->geometry.u.v.prim = GLITZ_GL_LINE_STRIP; - break; - case GLITZ_PRIMITIVE_LINE_LOOP: - dst->geometry.u.v.prim = GLITZ_GL_LINE_LOOP; - break; - case GLITZ_PRIMITIVE_TRIANGLES: - dst->geometry.u.v.prim = GLITZ_GL_TRIANGLES; - break; - case GLITZ_PRIMITIVE_TRIANGLE_STRIP: - dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_STRIP; - break; - case GLITZ_PRIMITIVE_TRIANGLE_FAN: - dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_FAN; - break; - case GLITZ_PRIMITIVE_QUADS: - dst->geometry.u.v.prim = GLITZ_GL_QUADS; - break; - case GLITZ_PRIMITIVE_QUAD_STRIP: - dst->geometry.u.v.prim = GLITZ_GL_QUAD_STRIP; - break; - default: - dst->geometry.u.v.prim = GLITZ_GL_POLYGON; - break; - } - - dst->geometry.u.v.type = _glitz_data_type (format->vertex.type); - dst->geometry.stride = format->vertex.bytes_per_vertex; - dst->geometry.attributes = format->vertex.attributes; - - if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) - { - dst->geometry.u.v.src.type = - _glitz_data_type (format->vertex.src.type); - dst->geometry.u.v.src.offset = format->vertex.src.offset; - - if (format->vertex.src.size == GLITZ_COORDINATE_SIZE_XY) - dst->geometry.u.v.src.size = 2; - else - dst->geometry.u.v.src.size = 1; - } - - if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) - { - dst->geometry.u.v.mask.type = - _glitz_data_type (format->vertex.mask.type); - dst->geometry.u.v.mask.offset = format->vertex.mask.offset; - - if (format->vertex.mask.size == GLITZ_COORDINATE_SIZE_XY) - dst->geometry.u.v.mask.size = 2; - else - dst->geometry.u.v.mask.size = 1; - } + glitz_buffer_reference (buffer); + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); + dst->geometry.buffer = buffer; + + dst->geometry.type = GLITZ_GEOMETRY_TYPE_VERTEX; + + switch (format->vertex.primitive) { + case GLITZ_PRIMITIVE_POINTS: + dst->geometry.u.v.prim = GLITZ_GL_POINTS; + break; + case GLITZ_PRIMITIVE_LINES: + dst->geometry.u.v.prim = GLITZ_GL_LINES; + break; + case GLITZ_PRIMITIVE_LINE_STRIP: + dst->geometry.u.v.prim = GLITZ_GL_LINE_STRIP; + break; + case GLITZ_PRIMITIVE_LINE_LOOP: + dst->geometry.u.v.prim = GLITZ_GL_LINE_LOOP; + break; + case GLITZ_PRIMITIVE_TRIANGLES: + dst->geometry.u.v.prim = GLITZ_GL_TRIANGLES; + break; + case GLITZ_PRIMITIVE_TRIANGLE_STRIP: + dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_STRIP; + break; + case GLITZ_PRIMITIVE_TRIANGLE_FAN: + dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_FAN; + break; + case GLITZ_PRIMITIVE_QUADS: + dst->geometry.u.v.prim = GLITZ_GL_QUADS; + break; + case GLITZ_PRIMITIVE_QUAD_STRIP: + dst->geometry.u.v.prim = GLITZ_GL_QUAD_STRIP; + break; + default: + dst->geometry.u.v.prim = GLITZ_GL_POLYGON; + break; + } + + dst->geometry.u.v.type = _glitz_data_type (format->vertex.type); + dst->geometry.stride = format->vertex.bytes_per_vertex; + dst->geometry.attributes = format->vertex.attributes; + + if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) + { + dst->geometry.u.v.src.type = + _glitz_data_type (format->vertex.src.type); + dst->geometry.u.v.src.offset = format->vertex.src.offset; + + if (format->vertex.src.size == GLITZ_COORDINATE_SIZE_XY) + dst->geometry.u.v.src.size = 2; + else + dst->geometry.u.v.src.size = 1; + } + + if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) + { + dst->geometry.u.v.mask.type = + _glitz_data_type (format->vertex.mask.type); + dst->geometry.u.v.mask.offset = format->vertex.mask.offset; + + if (format->vertex.mask.size == GLITZ_COORDINATE_SIZE_XY) + dst->geometry.u.v.mask.size = 2; + else + dst->geometry.u.v.mask.size = 1; + } } break; case GLITZ_GEOMETRY_TYPE_BITMAP: - glitz_buffer_reference (buffer); - if (dst->geometry.buffer) - glitz_buffer_destroy (dst->geometry.buffer); - dst->geometry.buffer = buffer; - - dst->geometry.type = GLITZ_GEOMETRY_TYPE_BITMAP; - - if (format->bitmap.scanline_order == - GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) - dst->geometry.u.b.top_down = 1; - else - dst->geometry.u.b.top_down = 0; - - switch (format->bitmap.pad) { - case 2: - dst->geometry.u.b.pad = 2; - break; - case 4: - dst->geometry.u.b.pad = 4; - break; - case 8: - dst->geometry.u.b.pad = 8; - break; - default: - dst->geometry.u.b.pad = 1; - break; - } - - dst->geometry.stride = format->bitmap.bytes_per_line; - dst->geometry.attributes = 0; - break; + glitz_buffer_reference (buffer); + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); + dst->geometry.buffer = buffer; + + dst->geometry.type = GLITZ_GEOMETRY_TYPE_BITMAP; + + if (format->bitmap.scanline_order == + GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) + dst->geometry.u.b.top_down = 1; + else + dst->geometry.u.b.top_down = 0; + + switch (format->bitmap.pad) { + case 2: + dst->geometry.u.b.pad = 2; + break; + case 4: + dst->geometry.u.b.pad = 4; + break; + case 8: + dst->geometry.u.b.pad = 8; + break; + default: + dst->geometry.u.b.pad = 1; + break; + } + + dst->geometry.stride = format->bitmap.bytes_per_line; + dst->geometry.attributes = 0; + break; default: - dst->geometry.type = GLITZ_GEOMETRY_TYPE_NONE; - if (dst->geometry.buffer) - glitz_buffer_destroy (dst->geometry.buffer); + dst->geometry.type = GLITZ_GEOMETRY_TYPE_NONE; + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); - dst->geometry.buffer = NULL; - dst->geometry.attributes = 0; - break; + dst->geometry.buffer = NULL; + dst->geometry.attributes = 0; + break; } } slim_hidden_def(glitz_set_geometry); void glitz_set_array (glitz_surface_t *dst, - int first, - int size, - unsigned int count, - glitz_fixed16_16_t x_off, - glitz_fixed16_16_t y_off) + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off) { if (dst->geometry.array) { - glitz_multi_array_destroy (dst->geometry.array); - dst->geometry.array = NULL; + glitz_multi_array_destroy (dst->geometry.array); + dst->geometry.array = NULL; } - + dst->geometry.first = first; dst->geometry.size = size; dst->geometry.count = count; @@ -191,33 +191,33 @@ slim_hidden_def(glitz_set_array); glitz_multi_array_t * glitz_multi_array_create (unsigned int size) { - glitz_multi_array_t *array; - int alloc_size; - - if (!size) - return NULL; - - alloc_size = sizeof (glitz_multi_array_t) + (sizeof (int) + - sizeof (int) + - sizeof (unsigned int) + - sizeof (glitz_vec2_t) + - sizeof (int)) * (size); - - array = (glitz_multi_array_t *) malloc (alloc_size); - if (array == NULL) - return NULL; - - array->ref_count = 1; - array->size = size; - array->first = (int *) (array + 1); - array->sizes = (int *) (array->first + size); - array->count = (int *) (array->sizes + size); - array->off = (glitz_vec2_t *) (array->count + size); - array->span = (int *) (array->off + size); - - array->n_arrays = 0; - - return array; + glitz_multi_array_t *array; + int alloc_size; + + if (!size) + return NULL; + + alloc_size = sizeof (glitz_multi_array_t) + (sizeof (int) + + sizeof (int) + + sizeof (unsigned int) + + sizeof (glitz_vec2_t) + + sizeof (int)) * (size); + + array = (glitz_multi_array_t *) malloc (alloc_size); + if (array == NULL) + return NULL; + + array->ref_count = 1; + array->size = size; + array->first = (int *) (array + 1); + array->sizes = (int *) (array->first + size); + array->count = (int *) (array->sizes + size); + array->off = (glitz_vec2_t *) (array->count + size); + array->span = (int *) (array->off + size); + + array->n_arrays = 0; + + return array; } slim_hidden_def(glitz_multi_array_create); @@ -225,12 +225,12 @@ void glitz_multi_array_destroy (glitz_multi_array_t *array) { if (!array) - return; - + return; + array->ref_count--; if (array->ref_count) - return; - + return; + free (array); } @@ -238,23 +238,23 @@ void glitz_multi_array_reference (glitz_multi_array_t *array) { if (array == NULL) - return; - + return; + array->ref_count++; } void glitz_multi_array_add (glitz_multi_array_t *array, - int first, - int size, - unsigned int count, - glitz_fixed16_16_t x_off, - glitz_fixed16_16_t y_off) + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off) { int i; if (array->size == array->n_arrays) - return; + return; i = array->n_arrays++; @@ -262,14 +262,14 @@ glitz_multi_array_add (glitz_multi_array_t *array, array->sizes[i] = size; array->count[i] = count; array->span[i] = 0; - + if (i == 0 || x_off || y_off) { - array->off[i].v[0] = FIXED_TO_FLOAT (x_off); - array->off[i].v[1] = FIXED_TO_FLOAT (y_off); - array->current_span = &array->span[i]; + array->off[i].v[0] = FIXED_TO_FLOAT (x_off); + array->off[i].v[1] = FIXED_TO_FLOAT (y_off); + array->current_span = &array->span[i]; } - + (*array->current_span)++; } slim_hidden_def(glitz_multi_array_add); @@ -283,14 +283,14 @@ slim_hidden_def(glitz_multi_array_reset); void glitz_set_multi_array (glitz_surface_t *dst, - glitz_multi_array_t *array, - glitz_fixed16_16_t x_off, - glitz_fixed16_16_t y_off) + glitz_multi_array_t *array, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off) { glitz_multi_array_reference (array); - + if (dst->geometry.array) - glitz_multi_array_destroy (dst->geometry.array); + glitz_multi_array_destroy (dst->geometry.array); dst->geometry.array = array; dst->geometry.count = array->n_arrays; @@ -301,49 +301,49 @@ slim_hidden_def(glitz_set_multi_array); void glitz_geometry_enable_none (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *box) + glitz_surface_t *dst, + glitz_box_t *box) { - dst->geometry.data[0] = (glitz_float_t) box->x1; - dst->geometry.data[1] = (glitz_float_t) box->y1; - dst->geometry.data[2] = (glitz_float_t) box->x2; - dst->geometry.data[3] = (glitz_float_t) box->y1; - dst->geometry.data[4] = (glitz_float_t) box->x2; - dst->geometry.data[5] = (glitz_float_t) box->y2; - dst->geometry.data[6] = (glitz_float_t) box->x1; - dst->geometry.data[7] = (glitz_float_t) box->y2; - - gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, dst->geometry.data); + dst->geometry.data[0] = (glitz_float_t) box->x1; + dst->geometry.data[1] = (glitz_float_t) box->y1; + dst->geometry.data[2] = (glitz_float_t) box->x2; + dst->geometry.data[3] = (glitz_float_t) box->y1; + dst->geometry.data[4] = (glitz_float_t) box->x2; + dst->geometry.data[5] = (glitz_float_t) box->y2; + dst->geometry.data[6] = (glitz_float_t) box->x1; + dst->geometry.data[7] = (glitz_float_t) box->y2; + + gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, dst->geometry.data); } void glitz_geometry_enable (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *box) + glitz_surface_t *dst, + glitz_box_t *box) { switch (dst->geometry.type) { case GLITZ_GEOMETRY_TYPE_VERTEX: - gl->vertex_pointer (2, dst->geometry.u.v.type, dst->geometry.stride, - glitz_buffer_bind (dst->geometry.buffer, - GLITZ_GL_ARRAY_BUFFER)); - break; + gl->vertex_pointer (2, dst->geometry.u.v.type, dst->geometry.stride, + glitz_buffer_bind (dst->geometry.buffer, + GLITZ_GL_ARRAY_BUFFER)); + break; case GLITZ_GEOMETRY_TYPE_BITMAP: - dst->geometry.u.b.base = - glitz_buffer_bind (dst->geometry.buffer, - GLITZ_GL_PIXEL_UNPACK_BUFFER); + dst->geometry.u.b.base = + glitz_buffer_bind (dst->geometry.buffer, + GLITZ_GL_PIXEL_UNPACK_BUFFER); - gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0); - gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0); + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0); + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0); #if BITMAP_BIT_ORDER == MSBFirst - gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_FALSE); + gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_FALSE); #else - gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_TRUE); + gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_TRUE); #endif - - break; + + break; case GLITZ_GEOMETRY_TYPE_NONE: - glitz_geometry_enable_none (gl, dst, box); + glitz_geometry_enable_none (gl, dst, box); } } @@ -351,132 +351,130 @@ void glitz_geometry_disable (glitz_surface_t *dst) { if (dst->geometry.buffer) - glitz_buffer_unbind (dst->geometry.buffer); + glitz_buffer_unbind (dst->geometry.buffer); } static void _glitz_draw_rectangle (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *bounds, - int damage) + glitz_surface_t *dst, + glitz_box_t *bounds, + int damage) { glitz_box_t *clip = dst->clip; int n_clip = dst->n_clip; glitz_box_t box; - int target_height = SURFACE_DRAWABLE_HEIGHT (dst); - + while (n_clip--) { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (bounds->x1 > box.x1) - box.x1 = bounds->x1; - if (bounds->y1 > box.y1) - box.y1 = bounds->y1; - if (bounds->x2 < box.x2) - box.x2 = bounds->x2; - if (bounds->y2 < box.y2) - box.y2 = bounds->y2; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - gl->scissor (box.x1 + dst->x, - target_height - dst->y - box.y2, - box.x2 - box.x1, box.y2 - box.y1); - - gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); - - if (damage) - glitz_surface_damage (dst, &box, damage); - } - - clip++; + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds->x1 > box.x1) + box.x1 = bounds->x1; + if (bounds->y1 > box.y1) + box.y1 = bounds->y1; + if (bounds->x2 < box.x2) + box.x2 = bounds->x2; + if (bounds->y2 < box.y2) + box.y2 = bounds->y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, box.y2 - box.y1); + + gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); + + if (damage) + glitz_surface_damage (dst, &box, damage); + } + + clip++; } } -#define MULTI_DRAW_ARRAYS(surface) \ - ((surface)->drawable->backend->feature_mask & \ +#define MULTI_DRAW_ARRAYS(surface) \ + ((surface)->drawable->backend->feature_mask & \ GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK) static void _glitz_draw_vertex_arrays (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *bounds, - int damage) + glitz_surface_t *dst, + glitz_box_t *bounds, + int damage) { glitz_multi_array_t *array = dst->geometry.array; glitz_box_t *clip = dst->clip; int i, n_clip = dst->n_clip; glitz_box_t box; - int target_height = SURFACE_DRAWABLE_HEIGHT (dst); - + while (n_clip--) { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (bounds->x1 > box.x1) - box.x1 = bounds->x1; - if (bounds->y1 > box.y1) - box.y1 = bounds->y1; - if (bounds->x2 < box.x2) - box.x2 = bounds->x2; - if (bounds->y2 < box.y2) - box.y2 = bounds->y2; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - gl->scissor (box.x1 + dst->x, - target_height - dst->y - box.y2, - box.x2 - box.x1, box.y2 - box.y1); - - gl->push_matrix (); - - if (dst->geometry.off.v[0] || dst->geometry.off.v[1]) - gl->translate_f (dst->geometry.off.v[0], - dst->geometry.off.v[1], 0.0f); - - if (array) - { - for (i = 0; i < array->n_arrays;) - { - gl->translate_f (array->off[i].v[0], - array->off[i].v[1], 0.0f); - - if (MULTI_DRAW_ARRAYS (dst)) - { - gl->multi_draw_arrays (dst->geometry.u.v.prim, - &array->first[i], - &array->count[i], - array->span[i]); - i += array->span[i]; - } - else - { - do { - if (array->count[i]) - gl->draw_arrays (dst->geometry.u.v.prim, - array->first[i], - array->count[i]); - - } while (array->span[++i] == 0); - } - } - } else - gl->draw_arrays (dst->geometry.u.v.prim, - dst->geometry.first, - dst->geometry.count); - - gl->pop_matrix (); - - if (damage) - glitz_surface_damage (dst, &box, damage); - } - - clip++; + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds->x1 > box.x1) + box.x1 = bounds->x1; + if (bounds->y1 > box.y1) + box.y1 = bounds->y1; + if (bounds->x2 < box.x2) + box.x2 = bounds->x2; + if (bounds->y2 < box.y2) + box.y2 = bounds->y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, box.y2 - box.y1); + + gl->push_matrix (); + + if (dst->geometry.off.v[0] || dst->geometry.off.v[1]) + gl->translate_f (dst->geometry.off.v[0], + dst->geometry.off.v[1], 0.0f); + + if (array) + { + for (i = 0; i < array->n_arrays;) + { + gl->translate_f (array->off[i].v[0], + array->off[i].v[1], 0.0f); + + if (MULTI_DRAW_ARRAYS (dst)) + { + gl->multi_draw_arrays (dst->geometry.u.v.prim, + &array->first[i], + &array->count[i], + array->span[i]); + i += array->span[i]; + } + else + { + do { + if (array->count[i]) + gl->draw_arrays (dst->geometry.u.v.prim, + array->first[i], + array->count[i]); + + } while (array->span[++i] == 0); + } + } + } else + gl->draw_arrays (dst->geometry.u.v.prim, + dst->geometry.first, + dst->geometry.count); + + gl->pop_matrix (); + + if (damage) + glitz_surface_damage (dst, &box, damage); + } + + clip++; } } @@ -486,43 +484,43 @@ _glitz_draw_vertex_arrays (glitz_gl_proc_address_list_t *gl, #define BITMAP_STRIDE(x, w, a) \ (((((x) & 3) + (w) + (((a) << 3) - 1)) / ((a) << 3)) * (a)) -#define BITMAP_SETUP(dst, first, size, count, _w, _h, _b_off, _p_off) \ - (_w) = (size); \ - (_h) = (count); \ - (_b_off) = (first) >> 3; \ - if ((_p_off) != ((first) & 3)) \ - { \ - (_p_off) = (first) & 3; \ - gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, _p_off); \ - } \ - if ((dst)->geometry.u.b.top_down) \ - { \ - dst_stride = BITMAP_STRIDE ((first), _w, BITMAP_PAD); \ - if ((dst)->geometry.stride) \ - src_stride = (dst)->geometry.stride; \ - else \ - src_stride = BITMAP_STRIDE ((first), _w, \ - (dst)->geometry.u.b.pad); \ - min_stride = MIN (src_stride, dst_stride); \ - base = (dst)->geometry.u.b.base + (_b_off); \ - y = (_h); \ - while (y--) \ - memcpy (bitmap + ((_h) - 1 - y) * dst_stride, \ - base + y * src_stride, \ - min_stride); \ - (_b_off) = 0; \ +#define BITMAP_SETUP(dst, first, size, count, _w, _h, _b_off, _p_off) \ + (_w) = (size); \ + (_h) = (count); \ + (_b_off) = (first) >> 3; \ + if ((_p_off) != ((first) & 3)) \ + { \ + (_p_off) = (first) & 3; \ + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, _p_off); \ + } \ + if ((dst)->geometry.u.b.top_down) \ + { \ + dst_stride = BITMAP_STRIDE ((first), _w, BITMAP_PAD); \ + if ((dst)->geometry.stride) \ + src_stride = (dst)->geometry.stride; \ + else \ + src_stride = BITMAP_STRIDE ((first), _w, \ + (dst)->geometry.u.b.pad); \ + min_stride = MIN (src_stride, dst_stride); \ + base = (dst)->geometry.u.b.base + (_b_off); \ + y = (_h); \ + while (y--) \ + memcpy (bitmap + ((_h) - 1 - y) * dst_stride, \ + base + y * src_stride, \ + min_stride); \ + (_b_off) = 0; \ } /* TODO: clipping could be done without glScissor, that might be faster. Other then solid colors can be used if bitmap fits into a stipple pattern. Maybe we should add a repeat parameter to glitz_bitmap_format_t as 2, 4, 8, 16 and 32 sized bitmaps can be tiled. - */ +*/ static void _glitz_draw_bitmap_arrays (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *bounds, - int damage) + glitz_surface_t *dst, + glitz_box_t *bounds, + int damage) { glitz_multi_array_t *array = dst->geometry.array; glitz_box_t *clip = dst->clip; @@ -534,148 +532,149 @@ _glitz_draw_bitmap_arrays (glitz_gl_proc_address_list_t *gl, int byte_offset, pixel_offset = 0; glitz_float_t x_off, y_off; glitz_box_t box; - int target_height = SURFACE_DRAWABLE_HEIGHT (dst); - + if (dst->geometry.u.b.top_down) { - int max_size = 0; - - if (array) - { - int size; - - for (i = 0, n = array->n_arrays; n--; i++) - { - x = array->first[i]; - w = array->sizes[i]; - size = BITMAP_STRIDE (x, w, BITMAP_PAD) * array->count[i]; - if (size > max_size) - max_size = size; - } - } - else - { - x = dst->geometry.first; - w = dst->geometry.size; - max_size = BITMAP_STRIDE (x, w, BITMAP_PAD) * dst->geometry.count; - } - - if (max_size > N_STACK_BITMAP) - { - heap_bitmap = malloc (max_size); - if (!heap_bitmap) - { - glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); - return; - } - bitmap = heap_bitmap; - } else - bitmap = stack_bitmap; - - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, BITMAP_PAD); - gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); + int max_size = 0; + + if (array) + { + int size; + + for (i = 0, n = array->n_arrays; n--; i++) + { + x = array->first[i]; + w = array->sizes[i]; + size = BITMAP_STRIDE (x, w, BITMAP_PAD) * array->count[i]; + if (size > max_size) + max_size = size; + } + } + else + { + x = dst->geometry.first; + w = dst->geometry.size; + max_size = BITMAP_STRIDE (x, w, BITMAP_PAD) * dst->geometry.count; + } + + if (max_size > N_STACK_BITMAP) + { + heap_bitmap = malloc (max_size); + if (!heap_bitmap) + { + glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); + return; + } + bitmap = heap_bitmap; + } else + bitmap = stack_bitmap; + + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, BITMAP_PAD); + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); } else { - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, dst->geometry.u.b.pad); - gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, - dst->geometry.stride * 8); + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, dst->geometry.u.b.pad); + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, + dst->geometry.stride * 8); } - + while (n_clip--) { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (bounds->x1 > box.x1) - box.x1 = bounds->x1; - if (bounds->y1 > box.y1) - box.y1 = bounds->y1; - if (bounds->x2 < box.x2) - box.x2 = bounds->x2; - if (bounds->y2 < box.y2) - box.y2 = bounds->y2; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - gl->scissor (box.x1 + dst->x, - target_height - dst->y - box.y2, - box.x2 - box.x1, box.y2 - box.y1); - - x_off = dst->x + dst->geometry.off.v[0]; - y_off = dst->y + dst->geometry.off.v[1]; - - if (array) - { - x_off += array->off->v[0]; - y_off += array->off->v[1]; - - glitz_set_raster_pos (gl, x_off, target_height - y_off); - - for (i = 0, n = array->n_arrays; n--; i++) - { - if (n) - { - x_off = array->off[i + 1].v[0]; - y_off = array->off[i + 1].v[1]; - } - - BITMAP_SETUP (dst, - array->first[i], - array->sizes[i], - array->count[i], - w, h, byte_offset, pixel_offset); - - gl->bitmap (w, h, - 0.0f, (glitz_gl_float_t) array->count[i], - x_off, -y_off, - bitmap + byte_offset); - } - } - else - { - glitz_set_raster_pos (gl, x_off, target_height - y_off); - - BITMAP_SETUP (dst, - dst->geometry.first, - dst->geometry.size, - dst->geometry.count, - w, h, byte_offset, pixel_offset); - - gl->bitmap (w, h, - 0.0f, (glitz_gl_float_t) dst->geometry.count, - 0.0f, 0.0f, - bitmap + byte_offset); - } - - if (damage) - glitz_surface_damage (dst, &box, damage); - } - - clip++; + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds->x1 > box.x1) + box.x1 = bounds->x1; + if (bounds->y1 > box.y1) + box.y1 = bounds->y1; + if (bounds->x2 < box.x2) + box.x2 = bounds->x2; + if (bounds->y2 < box.y2) + box.y2 = bounds->y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, box.y2 - box.y1); + + x_off = dst->x + dst->geometry.off.v[0]; + y_off = dst->y + dst->geometry.off.v[1]; + + if (array) + { + x_off += array->off->v[0]; + y_off += array->off->v[1]; + + glitz_set_raster_pos (gl, x_off, + dst->attached->height - y_off); + + for (i = 0, n = array->n_arrays; n--; i++) + { + if (n) + { + x_off = array->off[i + 1].v[0]; + y_off = array->off[i + 1].v[1]; + } + + BITMAP_SETUP (dst, + array->first[i], + array->sizes[i], + array->count[i], + w, h, byte_offset, pixel_offset); + + gl->bitmap (w, h, + 0.0f, (glitz_gl_float_t) array->count[i], + x_off, -y_off, + bitmap + byte_offset); + } + } + else + { + glitz_set_raster_pos (gl, x_off, + dst->attached->height - y_off); + + BITMAP_SETUP (dst, + dst->geometry.first, + dst->geometry.size, + dst->geometry.count, + w, h, byte_offset, pixel_offset); + + gl->bitmap (w, h, + 0.0f, (glitz_gl_float_t) dst->geometry.count, + 0.0f, 0.0f, + bitmap + byte_offset); + } + + if (damage) + glitz_surface_damage (dst, &box, damage); + } + + clip++; } if (heap_bitmap) - free (heap_bitmap); + free (heap_bitmap); } void glitz_geometry_draw_arrays (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_geometry_type_t type, - glitz_box_t *bounds, - int damage) + glitz_surface_t *dst, + glitz_geometry_type_t type, + glitz_box_t *bounds, + int damage) { switch (type) { case GLITZ_GEOMETRY_TYPE_VERTEX: - _glitz_draw_vertex_arrays (gl, dst, bounds, damage); - break; + _glitz_draw_vertex_arrays (gl, dst, bounds, damage); + break; case GLITZ_GEOMETRY_TYPE_BITMAP: - _glitz_draw_bitmap_arrays (gl, dst, bounds, damage); - break; + _glitz_draw_bitmap_arrays (gl, dst, bounds, damage); + break; case GLITZ_GEOMETRY_TYPE_NONE: - _glitz_draw_rectangle (gl, dst, bounds, damage); - break; + _glitz_draw_rectangle (gl, dst, bounds, damage); + break; } } diff --git a/src/glitz_gl.h b/src/glitz_gl.h index 85d96ef..98f587b 100644 --- a/src/glitz_gl.h +++ b/src/glitz_gl.h @@ -106,8 +106,9 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_MAX_TEXTURE_SIZE 0x0D33 #define GLITZ_GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GLITZ_GL_TEXTURE_WIDTH 0x1000 -#define GLITZ_GL_TEXTURE_HEIGHT 0x1001 +#define GLITZ_GL_TEXTURE_WIDTH 0x1000 +#define GLITZ_GL_TEXTURE_HEIGHT 0x1001 +#define GLITZ_GL_TEXTURE_BORDER_COLOR 0x1004 #define GLITZ_GL_TEXTURE_ENV 0x2300 #define GLITZ_GL_TEXTURE_ENV_MODE 0x2200 @@ -129,6 +130,7 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_MODULATE 0x2100 #define GLITZ_GL_NEAREST 0x2600 #define GLITZ_GL_LINEAR 0x2601 +#define GLITZ_GL_CLAMP 0x2900 #define GLITZ_GL_REPEAT 0x2901 #define GLITZ_GL_CLAMP_TO_EDGE 0x812F #define GLITZ_GL_CLAMP_TO_BORDER 0x812D @@ -182,6 +184,9 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_TRANSFORM_BIT 0x00001000 #define GLITZ_GL_COLOR_BUFFER_BIT 0x00004000 +#define GLITZ_GL_STENCIL_INDEX 0x1901 +#define GLITZ_GL_DEPTH_COMPONENT 0x1902 + #define GLITZ_GL_ALPHA 0x1906 #define GLITZ_GL_RGB 0x1907 #define GLITZ_GL_LUMINANCE 0x1909 @@ -303,8 +308,14 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_WRITE_ONLY 0x88B9 #define GLITZ_GL_READ_WRITE 0x88BA -#define GLITZ_GL_FRAMEBUFFER 0x8D40 -#define GLITZ_GL_COLOR_ATTACHMENT0 0x8CE0 +#define GLITZ_GL_FRAMEBUFFER 0x8D40 +#define GLITZ_GL_RENDERBUFFER 0x8D41 + +#define GLITZ_GL_COLOR_ATTACHMENT0 0x8CE0 +#define GLITZ_GL_COLOR_ATTACHMENT1 0x8CE1 +#define GLITZ_GL_DEPTH_ATTACHMENT 0x8D00 +#define GLITZ_GL_STENCIL_ATTACHMENT 0x8D20 + #define GLITZ_GL_FRAMEBUFFER_COMPLETE 0x8CD5 #define GLITZ_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 #define GLITZ_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 @@ -316,6 +327,13 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD #define GLITZ_GL_FRAMEBUFFER_STATUS_ERROR 0x8CDE +#define GLITZ_GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GLITZ_GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GLITZ_GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GLITZ_GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GLITZ_GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GLITZ_GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + typedef glitz_gl_void_t (* glitz_gl_enable_t) (glitz_gl_enum_t cap); typedef glitz_gl_void_t (* glitz_gl_disable_t) @@ -464,6 +482,9 @@ typedef glitz_gl_void_t (* glitz_gl_tex_image_2d_t) const glitz_gl_void_t *pixels); typedef glitz_gl_void_t (* glitz_gl_tex_parameter_i_t) (glitz_gl_enum_t target, glitz_gl_enum_t pname, glitz_gl_int_t param); +typedef glitz_gl_void_t (* glitz_gl_tex_parameter_fv_t) + (glitz_gl_enum_t target, glitz_gl_enum_t pname, + const glitz_gl_float_t *parama); typedef glitz_gl_void_t (* glitz_gl_get_tex_level_parameter_iv_t) (glitz_gl_enum_t target, glitz_gl_int_t level, glitz_gl_enum_t pname, glitz_gl_int_t *param); @@ -518,10 +539,23 @@ typedef void (* glitz_gl_delete_framebuffers_t) (glitz_gl_sizei_t, const glitz_gl_uint_t *); typedef glitz_gl_void_t (* glitz_gl_bind_framebuffer_t) (glitz_gl_enum_t, glitz_gl_uint_t); -typedef glitz_gl_enum_t (* glitz_gl_check_framebuffer_status_t) - (glitz_gl_enum_t); +typedef void (* glitz_gl_framebuffer_renderbuffer_t) + (glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_enum_t, + glitz_gl_uint_t); typedef void (* glitz_gl_framebuffer_texture_2d_t) (glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_uint_t, glitz_gl_int_t); +typedef glitz_gl_enum_t (* glitz_gl_check_framebuffer_status_t) + (glitz_gl_enum_t); +typedef void (* glitz_gl_gen_renderbuffers_t) + (glitz_gl_sizei_t, glitz_gl_uint_t *); +typedef void (* glitz_gl_delete_renderbuffers_t) + (glitz_gl_sizei_t, const glitz_gl_uint_t *); +typedef glitz_gl_void_t (* glitz_gl_bind_renderbuffer_t) + (glitz_gl_enum_t, glitz_gl_uint_t); +typedef glitz_gl_void_t (* glitz_gl_renderbuffer_storage_t) + (glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_sizei_t, glitz_gl_sizei_t); +typedef glitz_gl_void_t (* glitz_gl_get_renderbuffer_parameter_iv_t) + (glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_int_t *); #endif /* GLITZ_GL_H_INCLUDED */ diff --git a/src/glitz_operator.c b/src/glitz_operator.c index b19186b..194b508 100644 --- a/src/glitz_operator.c +++ b/src/glitz_operator.c @@ -32,59 +32,61 @@ #include "glitzint.h" void -glitz_set_operator (glitz_gl_proc_address_list_t *gl, glitz_operator_t op) { - switch (op) { - case GLITZ_OPERATOR_CLEAR: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ZERO); - break; - case GLITZ_OPERATOR_SRC: - gl->disable (GLITZ_GL_BLEND); - break; - case GLITZ_OPERATOR_DST: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ONE); - break; - case GLITZ_OPERATOR_OVER: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ONE, GLITZ_GL_ONE_MINUS_SRC_ALPHA); - break; - case GLITZ_OPERATOR_OVER_REVERSE: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, GLITZ_GL_ONE); - break; - case GLITZ_OPERATOR_IN: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_DST_ALPHA, GLITZ_GL_ZERO); - break; - case GLITZ_OPERATOR_IN_REVERSE: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_SRC_ALPHA); - break; - case GLITZ_OPERATOR_OUT: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, GLITZ_GL_ZERO); - break; - case GLITZ_OPERATOR_OUT_REVERSE: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ONE_MINUS_SRC_ALPHA); - break; - case GLITZ_OPERATOR_ATOP: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_DST_ALPHA, GLITZ_GL_ONE_MINUS_SRC_ALPHA); - break; - case GLITZ_OPERATOR_ATOP_REVERSE: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, GLITZ_GL_SRC_ALPHA); - break; - case GLITZ_OPERATOR_XOR: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, - GLITZ_GL_ONE_MINUS_SRC_ALPHA); - break; - case GLITZ_OPERATOR_ADD: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ONE, GLITZ_GL_ONE); - break; - } +glitz_set_operator (glitz_gl_proc_address_list_t *gl, + glitz_operator_t op) +{ + switch (op) { + case GLITZ_OPERATOR_CLEAR: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ZERO); + break; + case GLITZ_OPERATOR_SRC: + gl->disable (GLITZ_GL_BLEND); + break; + case GLITZ_OPERATOR_DST: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ONE); + break; + case GLITZ_OPERATOR_OVER: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ONE, GLITZ_GL_ONE_MINUS_SRC_ALPHA); + break; + case GLITZ_OPERATOR_OVER_REVERSE: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, GLITZ_GL_ONE); + break; + case GLITZ_OPERATOR_IN: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_DST_ALPHA, GLITZ_GL_ZERO); + break; + case GLITZ_OPERATOR_IN_REVERSE: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_SRC_ALPHA); + break; + case GLITZ_OPERATOR_OUT: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, GLITZ_GL_ZERO); + break; + case GLITZ_OPERATOR_OUT_REVERSE: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ONE_MINUS_SRC_ALPHA); + break; + case GLITZ_OPERATOR_ATOP: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_DST_ALPHA, GLITZ_GL_ONE_MINUS_SRC_ALPHA); + break; + case GLITZ_OPERATOR_ATOP_REVERSE: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, GLITZ_GL_SRC_ALPHA); + break; + case GLITZ_OPERATOR_XOR: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, + GLITZ_GL_ONE_MINUS_SRC_ALPHA); + break; + case GLITZ_OPERATOR_ADD: + gl->enable (GLITZ_GL_BLEND); + gl->blend_func (GLITZ_GL_ONE, GLITZ_GL_ONE); + break; + } } diff --git a/src/glitz_pixel.c b/src/glitz_pixel.c index 56f16c1..95c3d75 100644 --- a/src/glitz_pixel.c +++ b/src/glitz_pixel.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -32,71 +32,71 @@ #include <string.h> typedef struct _glitz_gl_pixel_format { - glitz_pixel_format_t pixel; - glitz_gl_enum_t format; - glitz_gl_enum_t type; + glitz_pixel_format_t pixel; + glitz_gl_enum_t format; + glitz_gl_enum_t type; } glitz_gl_pixel_format_t; - + static glitz_gl_pixel_format_t _gl_pixel_formats[] = { - { { - { - 8, - 0x000000ff, - 0x00000000, - 0x00000000, - 0x00000000 - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - }, - GLITZ_GL_ALPHA, - GLITZ_GL_UNSIGNED_BYTE - }, { - { - { - 32, - 0xff000000, - 0x00ff0000, - 0x0000ff00, - 0x000000ff - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - }, - GLITZ_GL_BGRA, - -#if IMAGE_BYTE_ORDER == MSBFirst - GLITZ_GL_UNSIGNED_INT_8_8_8_8_REV + { + { + 8, + 0x000000ff, + 0x00000000, + 0x00000000, + 0x00000000 + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }, + GLITZ_GL_ALPHA, + GLITZ_GL_UNSIGNED_BYTE + }, { + { + { + 32, + 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }, + GLITZ_GL_BGRA, + +#if IMAGE_BYTE_ORDER == MSBFirst + GLITZ_GL_UNSIGNED_INT_8_8_8_8_REV #else - GLITZ_GL_UNSIGNED_BYTE + GLITZ_GL_UNSIGNED_BYTE #endif - - } + + } }; static glitz_gl_pixel_format_t _gl_packed_pixel_formats[] = { - { { - { - 16, - 0x00000000, - 0x0000f800, - 0x000007e0, - 0x0000001f - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - }, - GLITZ_GL_BGR, - -#if IMAGE_BYTE_ORDER == MSBFirst - GLITZ_GL_UNSIGNED_SHORT_5_6_5_REV + { + { + 16, + 0x00000000, + 0x0000f800, + 0x000007e0, + 0x0000001f + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }, + GLITZ_GL_BGR, + +#if IMAGE_BYTE_ORDER == MSBFirst + GLITZ_GL_UNSIGNED_SHORT_5_6_5_REV #else - GLITZ_GL_UNSIGNED_SHORT_5_6_5 + GLITZ_GL_UNSIGNED_SHORT_5_6_5 #endif - - } + + } }; #define SOLID_ALPHA 0 @@ -105,148 +105,148 @@ static glitz_gl_pixel_format_t _gl_packed_pixel_formats[] = { #define SOLID_BLUE 3 static glitz_pixel_format_t _solid_format[] = { - { - { - 16, - 0x0000ffff, - 0x00000000, - 0x00000000, - 0x00000000 - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - }, { - { - 16, - 0x00000000, - 0x0000ffff, - 0x00000000, - 0x00000000 - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - }, { - { - 16, - 0x00000000, - 0x00000000, - 0x0000ffff, - 0x00000000 - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - }, { { - 16, - 0x00000000, - 0x00000000, - 0x00000000, - 0x0000ffff - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - } + { + 16, + 0x0000ffff, + 0x00000000, + 0x00000000, + 0x00000000 + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }, { + { + 16, + 0x00000000, + 0x0000ffff, + 0x00000000, + 0x00000000 + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }, { + { + 16, + 0x00000000, + 0x00000000, + 0x0000ffff, + 0x00000000 + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }, { + { + 16, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0000ffff + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + } }; typedef struct _glitz_pixel_color { - uint32_t r, g, b, a; + uint32_t r, g, b, a; } glitz_pixel_color_t; typedef struct _glitz_pixel_transform_op { - char *line; - int offset; - glitz_pixel_format_t *format; - glitz_pixel_color_t *color; + char *line; + int offset; + glitz_pixel_format_t *format; + glitz_pixel_color_t *color; } glitz_pixel_transform_op_t; -#define FETCH(p, mask) ((mask)? \ - ((uint32_t) ((((uint64_t) (((uint32_t) (p)) & (mask))) * 0xffffffff) / \ - ((uint64_t) (mask)))): 0x0) +#define FETCH(p, mask) \ + ((mask) ? ((uint32_t) ((((uint64_t) (((uint32_t) (p)) & (mask))) * \ + 0xffffffff) / ((uint64_t) (mask)))): 0x0) -#define FETCH_A(p, mask) ((mask)? \ - ((uint32_t) ((((uint64_t) (((uint32_t) (p)) & (mask))) * 0xffffffff) / \ - ((uint64_t) (mask)))): 0xffffffff) +#define FETCH_A(p, mask) \ + ((mask) ? ((uint32_t) ((((uint64_t) (((uint32_t) (p)) & (mask))) * \ + 0xffffffff) /((uint64_t) (mask)))): 0xffffffff) typedef void (*glitz_pixel_fetch_function_t) (glitz_pixel_transform_op_t *op); static void _fetch_1 (glitz_pixel_transform_op_t *op) { - uint8_t p = (uint8_t) op->line[op->offset / 8]; + uint8_t p = (uint8_t) op->line[op->offset / 8]; #if BITMAP_BIT_ORDER == MSBFirst - p = (p >> (7 - (op->offset % 8))) & 0x1; + p = (p >> (7 - (op->offset % 8))) & 0x1; #else - p = (p >> (op->offset % 8)) & 0x1; + p = (p >> (op->offset % 8)) & 0x1; #endif - - op->color->a = FETCH_A (p, op->format->masks.alpha_mask); - op->color->r = FETCH (p, op->format->masks.red_mask); - op->color->g = FETCH (p, op->format->masks.green_mask); - op->color->b = FETCH (p, op->format->masks.blue_mask); + + op->color->a = FETCH_A (p, op->format->masks.alpha_mask); + op->color->r = FETCH (p, op->format->masks.red_mask); + op->color->g = FETCH (p, op->format->masks.green_mask); + op->color->b = FETCH (p, op->format->masks.blue_mask); } static void _fetch_8 (glitz_pixel_transform_op_t *op) { - uint8_t p = op->line[op->offset]; - - op->color->a = FETCH_A (p, op->format->masks.alpha_mask); - op->color->r = FETCH (p, op->format->masks.red_mask); - op->color->g = FETCH (p, op->format->masks.green_mask); - op->color->b = FETCH (p, op->format->masks.blue_mask); + uint8_t p = op->line[op->offset]; + + op->color->a = FETCH_A (p, op->format->masks.alpha_mask); + op->color->r = FETCH (p, op->format->masks.red_mask); + op->color->g = FETCH (p, op->format->masks.green_mask); + op->color->b = FETCH (p, op->format->masks.blue_mask); } static void _fetch_16 (glitz_pixel_transform_op_t *op) { - uint16_t p = ((uint16_t *) op->line)[op->offset]; - - op->color->a = FETCH_A (p, op->format->masks.alpha_mask); - op->color->r = FETCH (p, op->format->masks.red_mask); - op->color->g = FETCH (p, op->format->masks.green_mask); - op->color->b = FETCH (p, op->format->masks.blue_mask); + uint16_t p = ((uint16_t *) op->line)[op->offset]; + + op->color->a = FETCH_A (p, op->format->masks.alpha_mask); + op->color->r = FETCH (p, op->format->masks.red_mask); + op->color->g = FETCH (p, op->format->masks.green_mask); + op->color->b = FETCH (p, op->format->masks.blue_mask); } static void _fetch_24 (glitz_pixel_transform_op_t *op) { - uint8_t *l = (uint8_t *) &op->line[op->offset * 3]; - uint32_t p; - + uint8_t *l = (uint8_t *) &op->line[op->offset * 3]; + uint32_t p; + #if IMAGE_BYTE_ORDER == MSBFirst - p = 0xff000000 | (l[2] << 16) | (l[1] << 8) | (l[0]); + p = 0xff000000 | (l[2] << 16) | (l[1] << 8) | (l[0]); #else - p = 0xff000000 | (l[0] << 16) | (l[1] << 8) | (l[2]); + p = 0xff000000 | (l[0] << 16) | (l[1] << 8) | (l[2]); #endif - op->color->a = FETCH_A (p, op->format->masks.alpha_mask); - op->color->r = FETCH (p, op->format->masks.red_mask); - op->color->g = FETCH (p, op->format->masks.green_mask); - op->color->b = FETCH (p, op->format->masks.blue_mask); + op->color->a = FETCH_A (p, op->format->masks.alpha_mask); + op->color->r = FETCH (p, op->format->masks.red_mask); + op->color->g = FETCH (p, op->format->masks.green_mask); + op->color->b = FETCH (p, op->format->masks.blue_mask); } static void _fetch_32 (glitz_pixel_transform_op_t *op) { - uint32_t p = ((uint32_t *) op->line)[op->offset]; - - op->color->a = FETCH_A (p, op->format->masks.alpha_mask); - op->color->r = FETCH (p, op->format->masks.red_mask); - op->color->g = FETCH (p, op->format->masks.green_mask); - op->color->b = FETCH (p, op->format->masks.blue_mask); + uint32_t p = ((uint32_t *) op->line)[op->offset]; + + op->color->a = FETCH_A (p, op->format->masks.alpha_mask); + op->color->r = FETCH (p, op->format->masks.red_mask); + op->color->g = FETCH (p, op->format->masks.green_mask); + op->color->b = FETCH (p, op->format->masks.blue_mask); } typedef void (*glitz_pixel_store_function_t) (glitz_pixel_transform_op_t *op); -#define STORE(v, mask) \ - (((uint32_t) (((v) * (uint64_t) (mask)) / 0xffffffff)) & (mask)) +#define STORE(v, mask) \ + (((uint32_t) (((v) * (uint64_t) (mask)) / 0xffffffff)) & (mask)) static void _store_1 (glitz_pixel_transform_op_t *op) { - uint8_t *p = (uint8_t *) &op->line[op->offset / 8]; - uint32_t offset; + uint8_t *p = (uint8_t *) &op->line[op->offset / 8]; + uint32_t offset; #if BITMAP_BIT_ORDER == MSBFirst offset = 7 - (op->offset % 8); @@ -254,70 +254,70 @@ _store_1 (glitz_pixel_transform_op_t *op) offset = op->offset % 8; #endif - *p |= - ((STORE (op->color->a, op->format->masks.alpha_mask) | - STORE (op->color->r, op->format->masks.red_mask) | - STORE (op->color->g, op->format->masks.green_mask) | - STORE (op->color->b, op->format->masks.blue_mask)) & 0x1) << offset; + *p |= + ((STORE (op->color->a, op->format->masks.alpha_mask) | + STORE (op->color->r, op->format->masks.red_mask) | + STORE (op->color->g, op->format->masks.green_mask) | + STORE (op->color->b, op->format->masks.blue_mask)) & 0x1) << offset; } static void _store_8 (glitz_pixel_transform_op_t *op) { - uint8_t *p = (uint8_t *) &op->line[op->offset]; - - *p = (uint8_t) - STORE (op->color->a, op->format->masks.alpha_mask) | - STORE (op->color->r, op->format->masks.red_mask) | - STORE (op->color->g, op->format->masks.green_mask) | - STORE (op->color->b, op->format->masks.blue_mask); + uint8_t *p = (uint8_t *) &op->line[op->offset]; + + *p = (uint8_t) + STORE (op->color->a, op->format->masks.alpha_mask) | + STORE (op->color->r, op->format->masks.red_mask) | + STORE (op->color->g, op->format->masks.green_mask) | + STORE (op->color->b, op->format->masks.blue_mask); } static void _store_16 (glitz_pixel_transform_op_t *op) { - uint16_t *p = &((uint16_t *) op->line)[op->offset]; + uint16_t *p = &((uint16_t *) op->line)[op->offset]; - *p = (uint16_t) - STORE (op->color->a, op->format->masks.alpha_mask) | - STORE (op->color->r, op->format->masks.red_mask) | - STORE (op->color->g, op->format->masks.green_mask) | - STORE (op->color->b, op->format->masks.blue_mask); + *p = (uint16_t) + STORE (op->color->a, op->format->masks.alpha_mask) | + STORE (op->color->r, op->format->masks.red_mask) | + STORE (op->color->g, op->format->masks.green_mask) | + STORE (op->color->b, op->format->masks.blue_mask); } static void _store_24 (glitz_pixel_transform_op_t *op) { - uint8_t *l = (uint8_t *) &op->line[op->offset * 3]; - - uint32_t p = - STORE (op->color->a, op->format->masks.alpha_mask) | - STORE (op->color->r, op->format->masks.red_mask) | - STORE (op->color->g, op->format->masks.green_mask) | - STORE (op->color->b, op->format->masks.blue_mask); - + uint8_t *l = (uint8_t *) &op->line[op->offset * 3]; + + uint32_t p = + STORE (op->color->a, op->format->masks.alpha_mask) | + STORE (op->color->r, op->format->masks.red_mask) | + STORE (op->color->g, op->format->masks.green_mask) | + STORE (op->color->b, op->format->masks.blue_mask); + #if IMAGE_BYTE_ORDER == MSBFirst - l[2] = p >> 16; - l[1] = p >> 8; - l[0] = p; + l[2] = p >> 16; + l[1] = p >> 8; + l[0] = p; #else - l[0] = p >> 16; - l[1] = p >> 8; - l[2] = p; + l[0] = p >> 16; + l[1] = p >> 8; + l[2] = p; #endif - + } static void _store_32 (glitz_pixel_transform_op_t *op) { - uint32_t *p = &((uint32_t *) op->line)[op->offset]; - - *p = - STORE (op->color->a, op->format->masks.alpha_mask) | - STORE (op->color->r, op->format->masks.red_mask) | - STORE (op->color->g, op->format->masks.green_mask) | - STORE (op->color->b, op->format->masks.blue_mask); + uint32_t *p = &((uint32_t *) op->line)[op->offset]; + + *p = + STORE (op->color->a, op->format->masks.alpha_mask) | + STORE (op->color->r, op->format->masks.red_mask) | + STORE (op->color->g, op->format->masks.green_mask) | + STORE (op->color->b, op->format->masks.blue_mask); } #define GLITZ_TRANSFORM_PIXELS_MASK (1L << 0) @@ -325,270 +325,284 @@ _store_32 (glitz_pixel_transform_op_t *op) #define GLITZ_TRANSFORM_COPY_BOX_MASK (1L << 2) typedef struct _glitz_image { - char *data; - glitz_pixel_format_t *format; - int width; - int height; + char *data; + glitz_pixel_format_t *format; + int width; + int height; } glitz_image_t; static void _glitz_pixel_transform (unsigned long transform, - glitz_image_t *src, - glitz_image_t *dst, - int x_src, - int y_src, - int x_dst, - int y_dst, - int width, - int height) + glitz_image_t *src, + glitz_image_t *dst, + int x_src, + int y_src, + int x_dst, + int y_dst, + int width, + int height) { - int src_stride, dst_stride; - int x, y, bytes_per_pixel = 0; - glitz_pixel_fetch_function_t fetch; - glitz_pixel_store_function_t store; - glitz_pixel_color_t color; - glitz_pixel_transform_op_t src_op, dst_op; - - switch (src->format->masks.bpp) { - case 1: - fetch = _fetch_1; - break; - case 8: - fetch = _fetch_8; - break; - case 16: - fetch = _fetch_16; - break; - case 24: - fetch = _fetch_24; - break; - case 32: - default: - fetch = _fetch_32; - break; - } - - switch (dst->format->masks.bpp) { - case 1: - store = _store_1; - break; - case 8: - store = _store_8; - break; - case 16: - store = _store_16; - break; - case 24: - store = _store_24; - break; - case 32: - default: - store = _store_32; - break; - } - - src_stride = (src->format->bytes_per_line)? src->format->bytes_per_line: - (((src->width * src->format->masks.bpp) / 8) + 3) & -4; - if (src_stride == 0) - src_stride = 1; - src_op.format = src->format; - src_op.color = &color; - - dst_stride = (dst->format->bytes_per_line)? dst->format->bytes_per_line: - (((dst->width * dst->format->masks.bpp) / 8) + 3) & -4; - if (dst_stride == 0) - dst_stride = 1; - dst_op.format = dst->format; - dst_op.color = &color; - - for (y = 0; y < height; y++) { - if (src->format->scanline_order != dst->format->scanline_order) - src_op.line = &src->data[(src->height - (y + y_src) - 1) * src_stride]; - else - src_op.line = &src->data[(y + y_src) * src_stride]; - - dst_op.line = &dst->data[(y + y_dst) * dst_stride]; - - if (transform & GLITZ_TRANSFORM_PIXELS_MASK) { - for (x = 0; x < width; x++) { - src_op.offset = x_src + x; - dst_op.offset = x_dst + x; - - fetch (&src_op); - store (&dst_op); - } - } else { - /* This only works for bpp >= 8, but it shouldn't be a problem as - it will never be used for bitmaps */ - if (bytes_per_pixel == 0) - bytes_per_pixel = src->format->masks.bpp / 8; - - memcpy (&dst_op.line[x_dst * bytes_per_pixel], - &src_op.line[x_src * bytes_per_pixel], - width * bytes_per_pixel); + int src_stride, dst_stride; + int x, y, bytes_per_pixel = 0; + glitz_pixel_fetch_function_t fetch; + glitz_pixel_store_function_t store; + glitz_pixel_color_t color; + glitz_pixel_transform_op_t src_op, dst_op; + + switch (src->format->masks.bpp) { + case 1: + fetch = _fetch_1; + break; + case 8: + fetch = _fetch_8; + break; + case 16: + fetch = _fetch_16; + break; + case 24: + fetch = _fetch_24; + break; + case 32: + default: + fetch = _fetch_32; + break; + } + + switch (dst->format->masks.bpp) { + case 1: + store = _store_1; + break; + case 8: + store = _store_8; + break; + case 16: + store = _store_16; + break; + case 24: + store = _store_24; + break; + case 32: + default: + store = _store_32; + break; + } + + src_stride = (src->format->bytes_per_line)? src->format->bytes_per_line: + (((src->width * src->format->masks.bpp) / 8) + 3) & -4; + if (src_stride == 0) + src_stride = 1; + src_op.format = src->format; + src_op.color = &color; + + dst_stride = (dst->format->bytes_per_line)? dst->format->bytes_per_line: + (((dst->width * dst->format->masks.bpp) / 8) + 3) & -4; + if (dst_stride == 0) + dst_stride = 1; + dst_op.format = dst->format; + dst_op.color = &color; + + for (y = 0; y < height; y++) { + if (src->format->scanline_order != dst->format->scanline_order) + src_op.line = &src->data[(src->height - (y + y_src) - 1) * + src_stride]; + else + src_op.line = &src->data[(y + y_src) * src_stride]; + + dst_op.line = &dst->data[(y + y_dst) * dst_stride]; + + if (transform & GLITZ_TRANSFORM_PIXELS_MASK) + { + for (x = 0; x < width; x++) + { + src_op.offset = x_src + x; + dst_op.offset = x_dst + x; + + fetch (&src_op); + store (&dst_op); + } + } + else + { + /* This only works for bpp >= 8, but it shouldn't be a problem as + it will never be used for bitmaps */ + if (bytes_per_pixel == 0) + bytes_per_pixel = src->format->masks.bpp / 8; + + memcpy (&dst_op.line[x_dst * bytes_per_pixel], + &src_op.line[x_src * bytes_per_pixel], + width * bytes_per_pixel); + } } - } } static glitz_bool_t -_glitz_format_match (glitz_pixel_masks_t *masks1, - glitz_pixel_masks_t *masks2, - glitz_color_format_t *internal_color) +_glitz_format_match (glitz_pixel_masks_t *masks1, + glitz_pixel_masks_t *masks2, + unsigned long mask) { - if (masks1->bpp != masks2->bpp) - return 0; - - if (internal_color->red_size) - if (masks1->red_mask != masks2->red_mask) - return 0; - - if (internal_color->green_size) - if (masks1->green_mask != masks2->green_mask) - return 0; - - if (internal_color->blue_size) - if (masks1->blue_mask != masks2->blue_mask) - return 0; - - if (internal_color->alpha_size) - if (masks1->alpha_mask != masks2->alpha_mask) - return 0; - - return 1; + if (masks1->bpp != masks2->bpp) + return 0; + + if (mask & GLITZ_FORMAT_RED_SIZE_MASK) + if (masks1->red_mask != masks2->red_mask) + return 0; + + if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK) + if (masks1->green_mask != masks2->green_mask) + return 0; + + if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK) + if (masks1->blue_mask != masks2->blue_mask) + return 0; + + if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK) + if (masks1->alpha_mask != masks2->alpha_mask) + return 0; + + return 1; } static glitz_gl_pixel_format_t * _glitz_find_gl_pixel_format (glitz_pixel_format_t *format, - glitz_color_format_t *internal_color, - unsigned long feature_mask) + unsigned long color_mask, + unsigned long feature_mask) { - int i, n_formats; - - n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t); - for (i = 0; i < n_formats; i++) { - if (_glitz_format_match (&_gl_pixel_formats[i].pixel.masks, &format->masks, - internal_color)) - return &_gl_pixel_formats[i]; - } - - if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK) { - n_formats = sizeof (_gl_packed_pixel_formats) / - sizeof (glitz_gl_pixel_format_t); - - for (i = 0; i < n_formats; i++) { - if (_glitz_format_match (&_gl_packed_pixel_formats[i].pixel.masks, - &format->masks, - internal_color)) - return &_gl_packed_pixel_formats[i]; + int i, n_formats; + + n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t); + for (i = 0; i < n_formats; i++) + { + if (_glitz_format_match (&_gl_pixel_formats[i].pixel.masks, + &format->masks, color_mask)) + return &_gl_pixel_formats[i]; } - } - - return NULL; + + if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK) + { + n_formats = sizeof (_gl_packed_pixel_formats) / + sizeof (glitz_gl_pixel_format_t); + + for (i = 0; i < n_formats; i++) + { + if (_glitz_format_match (&_gl_packed_pixel_formats[i].pixel.masks, + &format->masks, color_mask)) + return &_gl_packed_pixel_formats[i]; + } + } + + return NULL; } static int _component_size (unsigned long mask) { - unsigned long y; - - /* HACKMEM 169 */ - y = (mask >> 1) & 033333333333; - y = mask - y - ((y >> 1) & 033333333333); - return (((y + (y >> 3)) & 030707070707) % 077); + unsigned long y; + + /* HACKMEM 169 */ + y = (mask >> 1) & 033333333333; + y = mask - y - ((y >> 1) & 033333333333); + return (((y + (y >> 3)) & 030707070707) % 077); } static glitz_bool_t _glitz_format_diff (glitz_pixel_masks_t *masks, - glitz_color_format_t *pixel_color, - glitz_color_format_t *internal_color, - int *diff) + glitz_color_format_t *pixel_color, + glitz_color_format_t *internal_color, + int *diff) { - int size; - - *diff = 0; - - size = _component_size (masks->red_mask); - if (size < pixel_color->red_size && size < internal_color->red_size) - return 0; - - *diff += abs (size - internal_color->red_size); - - size = _component_size (masks->green_mask); - if (size < pixel_color->green_size && size < internal_color->green_size) - return 0; - - *diff += abs (size - internal_color->green_size); - - size = _component_size (masks->blue_mask); - if (size < pixel_color->blue_size && size < internal_color->blue_size) - return 0; - - *diff += abs (size - internal_color->blue_size); - - size = _component_size (masks->alpha_mask); - if (size < pixel_color->alpha_size && size < internal_color->alpha_size) - return 0; - - *diff += abs (size - internal_color->alpha_size); - - return 1; + int size; + + *diff = 0; + + size = _component_size (masks->red_mask); + if (size < pixel_color->red_size && size < internal_color->red_size) + return 0; + + *diff += abs (size - internal_color->red_size); + + size = _component_size (masks->green_mask); + if (size < pixel_color->green_size && size < internal_color->green_size) + return 0; + + *diff += abs (size - internal_color->green_size); + + size = _component_size (masks->blue_mask); + if (size < pixel_color->blue_size && size < internal_color->blue_size) + return 0; + + *diff += abs (size - internal_color->blue_size); + + size = _component_size (masks->alpha_mask); + if (size < pixel_color->alpha_size && size < internal_color->alpha_size) + return 0; + + *diff += abs (size - internal_color->alpha_size); + + return 1; } static glitz_gl_pixel_format_t * _glitz_find_best_gl_pixel_format (glitz_pixel_format_t *format, - glitz_color_format_t *internal_color, - unsigned long feature_mask) + glitz_color_format_t *internal_color, + unsigned long feature_mask) { - glitz_gl_pixel_format_t *best = NULL; - glitz_color_format_t color; - int i, n_formats, diff, best_diff = MAXSHORT; - - color.red_size = _component_size (format->masks.red_mask); - color.green_size = _component_size (format->masks.green_mask); - color.blue_size = _component_size (format->masks.blue_mask); - color.alpha_size = _component_size (format->masks.alpha_mask); - - n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t); - for (i = 0; best_diff > 0 && i < n_formats; i++) { - if (_glitz_format_diff (&_gl_pixel_formats[i].pixel.masks, - &color, - internal_color, - &diff)) { - if (diff < best_diff) { - best = &_gl_pixel_formats[i]; - best_diff = diff; - } + glitz_gl_pixel_format_t *best = NULL; + glitz_color_format_t color; + int i, n_formats, diff, best_diff = MAXSHORT; + + color.red_size = _component_size (format->masks.red_mask); + color.green_size = _component_size (format->masks.green_mask); + color.blue_size = _component_size (format->masks.blue_mask); + color.alpha_size = _component_size (format->masks.alpha_mask); + + n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t); + for (i = 0; best_diff > 0 && i < n_formats; i++) + { + if (_glitz_format_diff (&_gl_pixel_formats[i].pixel.masks, + &color, + internal_color, + &diff)) + { + if (diff < best_diff) + { + best = &_gl_pixel_formats[i]; + best_diff = diff; + } + } } - } - - if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK) { - n_formats = sizeof (_gl_packed_pixel_formats) / - sizeof (glitz_gl_pixel_format_t); - - for (i = 0; best_diff > 0 && i < n_formats; i++) { - if (_glitz_format_diff (&_gl_packed_pixel_formats[i].pixel.masks, - &color, - internal_color, - &diff)) { - if (diff < best_diff) { - best = &_gl_packed_pixel_formats[i]; - best_diff = diff; - } - } + + if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK) + { + n_formats = sizeof (_gl_packed_pixel_formats) / + sizeof (glitz_gl_pixel_format_t); + + for (i = 0; best_diff > 0 && i < n_formats; i++) + { + if (_glitz_format_diff (&_gl_packed_pixel_formats[i].pixel.masks, + &color, + internal_color, + &diff)) + { + if (diff < best_diff) + { + best = &_gl_packed_pixel_formats[i]; + best_diff = diff; + } + } + } } - } - return best; + return best; } void glitz_set_pixels (glitz_surface_t *dst, - int x_dst, - int y_dst, - int width, - int height, - glitz_pixel_format_t *format, - glitz_buffer_t *buffer) + int x_dst, + int y_dst, + int width, + int height, + glitz_pixel_format_t *format, + glitz_buffer_t *buffer) { glitz_box_t *clip = dst->clip; int n_clip = dst->n_clip; @@ -601,142 +615,155 @@ glitz_set_pixels (glitz_surface_t *dst, glitz_bool_t bound = 0; int bytes_per_line = 0, bytes_per_pixel = 0; glitz_image_t src_image, dst_image; + unsigned long color_mask; glitz_box_t box; - + GLITZ_GL_SURFACE (dst); - + if (x_dst < 0 || x_dst > (dst->box.x2 - width) || - y_dst < 0 || y_dst > (dst->box.y2 - height)) { - glitz_surface_status_add (dst, GLITZ_STATUS_BAD_COORDINATE_MASK); - return; + y_dst < 0 || y_dst > (dst->box.y2 - height)) + { + glitz_surface_status_add (dst, GLITZ_STATUS_BAD_COORDINATE_MASK); + return; } if (SURFACE_SOLID (dst)) { - glitz_color_t old = dst->solid; - - while (n_clip--) - { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (x_dst > box.x1) - box.x1 = x_dst; - if (y_dst > box.y1) - box.y1 = y_dst; - if (x_dst + width < box.x2) - box.x2 = x_dst + width; - if (y_dst + height < box.y2) - box.y2 = y_dst + height; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - dst_image.width = dst_image.height = 1; - - src_image.data = - glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_READ_ONLY); - src_image.data += format->skip_lines * format->bytes_per_line; - src_image.format = format; - src_image.width = src_image.height = 1; - - if (format->masks.alpha_mask && dst->format->color.alpha_size) - { - dst_image.data = (void *) &dst->solid.alpha; - dst_image.format = &_solid_format[SOLID_ALPHA]; - - _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, - &src_image, &dst_image, - format->xoffset, 0, 0, 0, 1, 1); - } else - dst->solid.alpha = 0xffff; - - if (format->masks.red_mask && dst->format->color.red_size) - { - dst_image.data = (void *) &dst->solid.red; - dst_image.format = &_solid_format[SOLID_RED]; - - _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, - &src_image, &dst_image, - format->xoffset, 0, 0, 0, 1, 1); - } else - dst->solid.red = 0; - - if (format->masks.green_mask && dst->format->color.green_size) - { - dst_image.data = (void *) &dst->solid.green; - dst_image.format = &_solid_format[SOLID_GREEN]; - - _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, - &src_image, &dst_image, - format->xoffset, 0, 0, 0, 1, 1); - } else - dst->solid.green = 0; - - if (format->masks.blue_mask && dst->format->color.blue_size) - { - dst_image.data = (void *) &dst->solid.blue; - dst_image.format = &_solid_format[SOLID_BLUE]; - - _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, - &src_image, &dst_image, - format->xoffset, 0, 0, 0, 1, 1); - } else - dst->solid.blue = 0; - - glitz_buffer_unmap (buffer); - - if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK) - { - dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_DRAWABLE_MASK); - } - else - { - if (dst->solid.red != old.red || - dst->solid.green != old.green || - dst->solid.blue != old.blue || - dst->solid.alpha != old.alpha) - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_DRAWABLE_MASK); - } - break; - } - } - return; + glitz_color_t old = dst->solid; + + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (x_dst > box.x1) + box.x1 = x_dst; + if (y_dst > box.y1) + box.y1 = y_dst; + if (x_dst + width < box.x2) + box.x2 = x_dst + width; + if (y_dst + height < box.y2) + box.y2 = y_dst + height; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + dst_image.width = dst_image.height = 1; + + src_image.data = + glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_READ_ONLY); + src_image.data += format->skip_lines * format->bytes_per_line; + src_image.format = format; + src_image.width = src_image.height = 1; + + if (format->masks.alpha_mask && dst->format->color.alpha_size) + { + dst_image.data = (void *) &dst->solid.alpha; + dst_image.format = &_solid_format[SOLID_ALPHA]; + + _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, + &src_image, &dst_image, + format->xoffset, 0, 0, 0, 1, 1); + } else + dst->solid.alpha = 0xffff; + + if (format->masks.red_mask && dst->format->color.red_size) + { + dst_image.data = (void *) &dst->solid.red; + dst_image.format = &_solid_format[SOLID_RED]; + + _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, + &src_image, &dst_image, + format->xoffset, 0, 0, 0, 1, 1); + } else + dst->solid.red = 0; + + if (format->masks.green_mask && dst->format->color.green_size) + { + dst_image.data = (void *) &dst->solid.green; + dst_image.format = &_solid_format[SOLID_GREEN]; + + _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, + &src_image, &dst_image, + format->xoffset, 0, 0, 0, 1, 1); + } else + dst->solid.green = 0; + + if (format->masks.blue_mask && dst->format->color.blue_size) + { + dst_image.data = (void *) &dst->solid.blue; + dst_image.format = &_solid_format[SOLID_BLUE]; + + _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, + &src_image, &dst_image, + format->xoffset, 0, 0, 0, 1, 1); + } else + dst->solid.blue = 0; + + glitz_buffer_unmap (buffer); + + if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK) + { + dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_DRAWABLE_MASK); + } + else + { + if (dst->solid.red != old.red || + dst->solid.green != old.green || + dst->solid.blue != old.blue || + dst->solid.alpha != old.alpha) + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_DRAWABLE_MASK); + } + break; + } + clip++; + } + return; } - + + color_mask = 0; + if (dst->format->color.red_size) + color_mask |= GLITZ_FORMAT_RED_SIZE_MASK; + if (dst->format->color.green_size) + color_mask |= GLITZ_FORMAT_GREEN_SIZE_MASK; + if (dst->format->color.blue_size) + color_mask |= GLITZ_FORMAT_BLUE_SIZE_MASK; + if (dst->format->color.alpha_size) + color_mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK; + /* find direct format */ gl_format = - _glitz_find_gl_pixel_format (format, - &dst->format->color, - dst->drawable->backend->feature_mask); + _glitz_find_gl_pixel_format (format, + color_mask, + dst->drawable->backend->feature_mask); if (gl_format == NULL) { - unsigned long feature_mask; - - feature_mask = dst->drawable->backend->feature_mask; - transform |= GLITZ_TRANSFORM_PIXELS_MASK; - gl_format = - _glitz_find_best_gl_pixel_format (format, - &dst->format->color, - feature_mask); + unsigned long feature_mask; + + feature_mask = dst->drawable->backend->feature_mask; + transform |= GLITZ_TRANSFORM_PIXELS_MASK; + gl_format = + _glitz_find_best_gl_pixel_format (format, + &dst->format->color, + feature_mask); } glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); texture = glitz_surface_get_texture (dst, 1); if (!texture) { - glitz_surface_pop_current (dst); - return; + glitz_surface_pop_current (dst); + return; } if (height > 1) { - if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) - transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK; + if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) + transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK; } glitz_texture_bind (gl, texture); @@ -746,367 +773,483 @@ glitz_set_pixels (glitz_surface_t *dst, while (n_clip--) { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (x_dst > box.x1) - box.x1 = x_dst; - if (y_dst > box.y1) - box.y1 = y_dst; - if (x_dst + width < box.x2) - box.x2 = x_dst + width; - if (y_dst + height < box.y2) - box.y2 = y_dst + height; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - if (transform) - { - if (!data) - { - int stride, bpp; - - bpp = gl_format->pixel.masks.bpp; - stride = (((width * bpp) / 8) + 3) & -4; - data = malloc (stride * height); - if (!data) - { - glitz_surface_status_add (dst, - GLITZ_STATUS_NO_MEMORY_MASK); - goto BAIL; - } - - dst_image.data = pixels = data; - dst_image.format = &gl_format->pixel; - - ptr = - glitz_buffer_map (buffer, - GLITZ_BUFFER_ACCESS_READ_ONLY); - src_image.format = format; - - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 4); - gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); - } - - dst_image.width = box.x2 - box.x1; - dst_image.height = box.y2 - box.y1; - - src_image.width = box.x2 - box.x1; - src_image.height = box.y2 - box.y1; - - src_image.data = ptr + (format->skip_lines + box.y1 - y_dst) * - format->bytes_per_line; - - _glitz_pixel_transform (transform, - &src_image, - &dst_image, - format->xoffset + box.x1 - x_dst, 0, - 0, 0, - box.x2 - box.x1, box.y2 - box.y1); - } - else - { - if (!bound) - { - ptr = glitz_buffer_bind (buffer, - GLITZ_GL_PIXEL_UNPACK_BUFFER); - - bytes_per_line = format->bytes_per_line; - bytes_per_pixel = format->masks.bpp / 8; - if (bytes_per_line) - { - if ((bytes_per_line % 4) == 0) - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 4); - else if ((bytes_per_line % 2) == 0) - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 2); - else - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1); - - gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, - bytes_per_line / bytes_per_pixel); - } - else - { - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1); - gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, width); - bytes_per_line = width * bytes_per_pixel; - } - bound = 1; - } - - pixels = ptr + - (format->skip_lines + y_dst + height - box.y2) * - bytes_per_line + - (format->xoffset + box.x1 - x_dst) * bytes_per_pixel; - } - - gl->tex_sub_image_2d (texture->target, 0, - texture->box.x1 + box.x1, - texture->box.y2 - box.y2, - box.x2 - box.x1, box.y2 - box.y1, - gl_format->format, gl_format->type, - pixels); - - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_DRAWABLE_MASK | - GLITZ_DAMAGE_SOLID_MASK); - } - clip++; + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (x_dst > box.x1) + box.x1 = x_dst; + if (y_dst > box.y1) + box.y1 = y_dst; + if (x_dst + width < box.x2) + box.x2 = x_dst + width; + if (y_dst + height < box.y2) + box.y2 = y_dst + height; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + if (transform) + { + if (!data) + { + int stride, bpp; + + bpp = gl_format->pixel.masks.bpp; + stride = (((width * bpp) / 8) + 3) & -4; + data = malloc (stride * height); + if (!data) + { + glitz_surface_status_add (dst, + GLITZ_STATUS_NO_MEMORY_MASK); + goto BAIL; + } + + dst_image.data = pixels = data; + dst_image.format = &gl_format->pixel; + + ptr = + glitz_buffer_map (buffer, + GLITZ_BUFFER_ACCESS_READ_ONLY); + src_image.format = format; + + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 4); + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); + } + + dst_image.width = box.x2 - box.x1; + dst_image.height = box.y2 - box.y1; + + src_image.width = box.x2 - box.x1; + src_image.height = box.y2 - box.y1; + + src_image.data = ptr + (format->skip_lines + box.y1 - y_dst) * + format->bytes_per_line; + + _glitz_pixel_transform (transform, + &src_image, + &dst_image, + format->xoffset + box.x1 - x_dst, 0, + 0, 0, + box.x2 - box.x1, box.y2 - box.y1); + } + else + { + if (!bound) + { + ptr = glitz_buffer_bind (buffer, + GLITZ_GL_PIXEL_UNPACK_BUFFER); + + bytes_per_line = format->bytes_per_line; + bytes_per_pixel = format->masks.bpp / 8; + if (bytes_per_line) + { + if ((bytes_per_line % 4) == 0) + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 4); + else if ((bytes_per_line % 2) == 0) + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 2); + else + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1); + + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, + bytes_per_line / bytes_per_pixel); + } + else + { + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1); + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, width); + bytes_per_line = width * bytes_per_pixel; + } + bound = 1; + } + + pixels = ptr + + (format->skip_lines + y_dst + height - box.y2) * + bytes_per_line + + (format->xoffset + box.x1 - x_dst) * bytes_per_pixel; + } + + gl->tex_sub_image_2d (texture->target, 0, + texture->box.x1 + box.x1, + texture->box.y2 - box.y2, + box.x2 - box.x1, box.y2 - box.y1, + gl_format->format, gl_format->type, + pixels); + + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_DRAWABLE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + clip++; } if (transform) { - free (data); - glitz_buffer_unmap (buffer); + free (data); + glitz_buffer_unmap (buffer); } else - glitz_buffer_unbind (buffer); + glitz_buffer_unbind (buffer); - BAIL: +BAIL: glitz_texture_unbind (gl, texture); glitz_surface_pop_current (dst); } void glitz_get_pixels (glitz_surface_t *src, - int x_src, - int y_src, - int width, - int height, - glitz_pixel_format_t *format, - glitz_buffer_t *buffer) + int x_src, + int y_src, + int width, + int height, + glitz_pixel_format_t *format, + glitz_buffer_t *buffer) { - glitz_bool_t from_drawable; - glitz_texture_t *texture = NULL; - char *pixels, *data = NULL; - glitz_gl_pixel_format_t *gl_format = NULL; - unsigned long transform = 0; - int src_x = 0, src_y = 0, src_w = width, src_h = height; - int xoffset, bytes_per_line, bpp; - glitz_color_format_t *color; - - GLITZ_GL_SURFACE (src); - - if (x_src < 0 || x_src > (src->box.x2 - width) || - y_src < 0 || y_src > (src->box.y2 - height)) { - glitz_surface_status_add (src, GLITZ_STATUS_BAD_COORDINATE_MASK); - return; - } - - if (SURFACE_SOLID (src)) { - glitz_image_t src_image, dst_image; - glitz_pixel_format_t dst_format; - - if (SURFACE_SOLID_DAMAGE (src)) { - glitz_surface_push_current (src, GLITZ_ANY_CONTEXT_CURRENT); - glitz_surface_sync_solid (src); - glitz_surface_pop_current (src); - } - - src_image.width = src_image.height = 1; - - dst_format = *format; - - dst_image.data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); - dst_image.data += format->skip_lines * format->bytes_per_line; - dst_image.format = &dst_format; - dst_image.width = dst_image.height = 1; - - if (format->masks.alpha_mask) { - src_image.data = (void *) &src->solid.alpha; - src_image.format = &_solid_format[SOLID_ALPHA]; + glitz_box_t *clip = src->clip; + int n_clip = src->n_clip; + glitz_bool_t from_drawable; + glitz_texture_t *texture = NULL; + char *pixels, *data = NULL; + glitz_gl_pixel_format_t *gl_format = NULL; + unsigned long transform = 0; + int src_x = 0, src_y = 0; + int src_w = width, src_h = height; + int bytes_per_line, bytes_per_pixel; + glitz_color_format_t *color; + unsigned long color_mask; + glitz_box_t box; - dst_format.masks.alpha_mask = format->masks.alpha_mask; - dst_format.masks.red_mask = 0; - dst_format.masks.green_mask = 0; - dst_format.masks.blue_mask = 0; + GLITZ_GL_SURFACE (src); - _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, - &src_image, &dst_image, - 0, 0, format->xoffset, 0, 1, 1); + if (x_src < 0 || x_src > (src->box.x2 - width) || + y_src < 0 || y_src > (src->box.y2 - height)) + { + glitz_surface_status_add (src, GLITZ_STATUS_BAD_COORDINATE_MASK); + return; } - if (format->masks.red_mask) { - src_image.data = (void *) &src->solid.red; - src_image.format = &_solid_format[SOLID_RED]; + if (SURFACE_SOLID (src)) + { + glitz_image_t src_image, dst_image; + glitz_pixel_format_t dst_format; + + while (n_clip--) + { + box.x1 = clip->x1 + src->x_clip; + box.y1 = clip->y1 + src->y_clip; + box.x2 = clip->x2 + src->x_clip; + box.y2 = clip->y2 + src->y_clip; + if (x_src > box.x1) + box.x1 = x_src; + if (y_src > box.y1) + box.y1 = y_src; + if (x_src + width < box.x2) + box.x2 = x_src + width; + if (y_src + height < box.y2) + box.y2 = y_src + height; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + if (SURFACE_SOLID_DAMAGE (src)) + { + glitz_surface_push_current (src, + GLITZ_ANY_CONTEXT_CURRENT); + glitz_surface_sync_solid (src); + glitz_surface_pop_current (src); + } + + src_image.width = src_image.height = 1; + + dst_format = *format; + + dst_image.data = + glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + dst_image.data += format->skip_lines * format->bytes_per_line; + dst_image.format = &dst_format; + dst_image.width = dst_image.height = 1; + + if (format->masks.alpha_mask) + { + src_image.data = (void *) &src->solid.alpha; + src_image.format = &_solid_format[SOLID_ALPHA]; + + dst_format.masks.alpha_mask = format->masks.alpha_mask; + dst_format.masks.red_mask = 0; + dst_format.masks.green_mask = 0; + dst_format.masks.blue_mask = 0; + + _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, + &src_image, &dst_image, + 0, 0, format->xoffset, 0, 1, 1); + } + + if (format->masks.red_mask) + { + src_image.data = (void *) &src->solid.red; + src_image.format = &_solid_format[SOLID_RED]; + + dst_format.masks.alpha_mask = 0; + dst_format.masks.red_mask = format->masks.red_mask; + dst_format.masks.green_mask = 0; + dst_format.masks.blue_mask = 0; + + _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, + &src_image, &dst_image, + 0, 0, format->xoffset, 0, 1, 1); + } + + if (format->masks.green_mask) + { + src_image.data = (void *) &src->solid.green; + src_image.format = &_solid_format[SOLID_GREEN]; + + dst_format.masks.alpha_mask = 0; + dst_format.masks.red_mask = 0; + dst_format.masks.green_mask = format->masks.green_mask; + dst_format.masks.blue_mask = 0; + + _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, + &src_image, &dst_image, + 0, 0, format->xoffset, 0, 1, 1); + } + + if (format->masks.blue_mask) + { + src_image.data = (void *) &src->solid.blue; + src_image.format = &_solid_format[SOLID_BLUE]; + + dst_format.masks.alpha_mask = 0; + dst_format.masks.red_mask = 0; + dst_format.masks.green_mask = 0; + dst_format.masks.blue_mask = format->masks.blue_mask; + + _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, + &src_image, &dst_image, + 0, 0, format->xoffset, 0, 1, 1); + } + + glitz_buffer_unmap (buffer); + + break; + } + clip++; + } + + return; + } - dst_format.masks.alpha_mask = 0; - dst_format.masks.red_mask = format->masks.red_mask; - dst_format.masks.green_mask = 0; - dst_format.masks.blue_mask = 0; + color = &src->format->color; + from_drawable = glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT); + if (from_drawable) + { + if (src->attached) + color = &src->attached->format->d.color; + } + else + { + texture = glitz_surface_get_texture (src, 0); + if (!texture) + { + glitz_surface_pop_current (src); + return; + } + + if (texture->width > width || texture->height > height) + transform |= GLITZ_TRANSFORM_COPY_BOX_MASK; + + if (src->n_clip > 1 || + clip->x1 + src->x_clip > x_src || + clip->y1 + src->y_clip > y_src || + clip->x2 + src->x_clip < x_src + width || + clip->y2 + src->y_clip < y_src + height) + transform |= GLITZ_TRANSFORM_COPY_BOX_MASK; + } - _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, - &src_image, &dst_image, - 0, 0, format->xoffset, 0, 1, 1); + if (transform || height > 1) + { + if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) + transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK; } - if (format->masks.green_mask) { - src_image.data = (void *) &src->solid.green; - src_image.format = &_solid_format[SOLID_GREEN]; + color_mask = 0; + if (format->masks.red_mask) + color_mask |= GLITZ_FORMAT_RED_SIZE_MASK; + if (format->masks.green_mask) + color_mask |= GLITZ_FORMAT_GREEN_SIZE_MASK; + if (format->masks.blue_mask) + color_mask |= GLITZ_FORMAT_BLUE_SIZE_MASK; + if (format->masks.alpha_mask) + color_mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK; + + /* find direct format */ + gl_format = + _glitz_find_gl_pixel_format (format, color_mask, + src->drawable->backend->feature_mask); + if (gl_format == NULL) + { + unsigned int features; - dst_format.masks.alpha_mask = 0; - dst_format.masks.red_mask = 0; - dst_format.masks.green_mask = format->masks.green_mask; - dst_format.masks.blue_mask = 0; + transform |= GLITZ_TRANSFORM_PIXELS_MASK; + features = src->drawable->backend->feature_mask; - _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, - &src_image, &dst_image, - 0, 0, format->xoffset, 0, 1, 1); + gl_format = _glitz_find_best_gl_pixel_format (format, color, features); } - if (format->masks.blue_mask) { - src_image.data = (void *) &src->solid.blue; - src_image.format = &_solid_format[SOLID_BLUE]; - - dst_format.masks.alpha_mask = 0; - dst_format.masks.red_mask = 0; - dst_format.masks.green_mask = 0; - dst_format.masks.blue_mask = format->masks.blue_mask; - - _glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK, - &src_image, &dst_image, - 0, 0, format->xoffset, 0, 1, 1); + /* should not happen */ + if (gl_format == NULL) + { + glitz_surface_pop_current (src); + return; } - glitz_buffer_unmap (buffer); - - return; - } - - color = &src->format->color; - from_drawable = glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT); - if (from_drawable) { - if (src->attached) - color = &src->attached->format->color; - } else { - texture = glitz_surface_get_texture (src, 0); - if (!texture) { - glitz_surface_pop_current (src); - return; + if (transform) + { + int stride; + + if (transform & GLITZ_TRANSFORM_COPY_BOX_MASK) + { + if (texture) + { + src_w = texture->width; + src_h = texture->height; + src_x = src->texture.box.x1; + src_y = src->texture.box.y1; + } + } + + stride = (((src_w * gl_format->pixel.masks.bpp) / 8) + 3) & -4; + + data = malloc (stride * src_h); + if (!data) + { + glitz_surface_status_add (src, GLITZ_STATUS_NO_MEMORY_MASK); + return; + } + + pixels = data; + bytes_per_pixel = gl_format->pixel.masks.bpp / 8; + bytes_per_line = stride; } - - if (texture->width > width || texture->height > height) - transform |= GLITZ_TRANSFORM_COPY_BOX_MASK; - } - - if (transform || height > 1) { - if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) - transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK; - } - - /* find direct format */ - gl_format = - _glitz_find_gl_pixel_format (format, color, - src->drawable->backend->feature_mask); - if (gl_format == NULL) { - transform |= GLITZ_TRANSFORM_PIXELS_MASK; - - gl_format = - _glitz_find_best_gl_pixel_format (format, color, - src->drawable->backend->feature_mask); - } - - /* should not happen */ - if (gl_format == NULL) { - glitz_surface_pop_current (src); - return; - } - - if (transform) { - int stride; - - if (transform & GLITZ_TRANSFORM_COPY_BOX_MASK) { - src_w = texture->width; - src_h = texture->height; - src_x = x_src + src->texture.box.x1; - src_y = y_src + src->texture.box.y1; + else + { + bytes_per_pixel = format->masks.bpp / 8; + bytes_per_line = format->bytes_per_line; + if (!bytes_per_line) + bytes_per_line = width * bytes_per_pixel; + + pixels = glitz_buffer_bind (buffer, GLITZ_GL_PIXEL_PACK_BUFFER); + pixels += format->skip_lines * bytes_per_line; + pixels += format->xoffset * bytes_per_pixel; } - stride = (((src_w * gl_format->pixel.masks.bpp) / 8) + 3) & -4; + gl->pixel_store_i (GLITZ_GL_PACK_SKIP_ROWS, 0); + gl->pixel_store_i (GLITZ_GL_PACK_SKIP_PIXELS, 0); - data = malloc (stride * src_h); - if (!data) { - glitz_surface_status_add (src, GLITZ_STATUS_NO_MEMORY_MASK); - return; - } - pixels = data; - xoffset = 0; - bytes_per_line = stride; - bpp = gl_format->pixel.masks.bpp; - } else { - xoffset = format->xoffset; - bytes_per_line = format->bytes_per_line; - bpp = format->masks.bpp; - pixels = glitz_buffer_bind (buffer, GLITZ_GL_PIXEL_PACK_BUFFER); - pixels += format->skip_lines * bytes_per_line; - } - - gl->pixel_store_i (GLITZ_GL_PACK_SKIP_ROWS, 0); - gl->pixel_store_i (GLITZ_GL_PACK_SKIP_PIXELS, xoffset); - - if (bytes_per_line) { if ((bytes_per_line % 4) == 0) - gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 4); + gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 4); else if ((bytes_per_line % 2) == 0) - gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 2); + gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 2); else - gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 1); - - gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, bytes_per_line / (bpp / 8)); - } else { - gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 1); - gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, 0); - } - - if (from_drawable) { - gl->read_buffer (src->buffer); - - gl->disable (GLITZ_GL_SCISSOR_TEST); - - gl->read_pixels (x_src + src->x, - SURFACE_DRAWABLE_HEIGHT (src) - (y_src + src->y) - height, - width, height, - gl_format->format, gl_format->type, - pixels); - - gl->enable (GLITZ_GL_SCISSOR_TEST); - } else { - glitz_texture_bind (gl, texture); - gl->get_tex_image (texture->target, 0, - gl_format->format, gl_format->type, - pixels); - glitz_texture_unbind (gl, texture); - } - - if (transform) { - glitz_image_t src_image, dst_image; - - src_image.data = data; - src_image.format = &gl_format->pixel; - src_image.width = src_w; - src_image.height = src_h; - - dst_image.data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); - dst_image.format = format; - dst_image.width = width; - dst_image.height = height; + gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 1); - if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP) - src_y = src_h - src_y - height; + gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, + bytes_per_line / bytes_per_pixel); - _glitz_pixel_transform (transform, - &src_image, - &dst_image, - src_x, src_y, - format->xoffset, format->skip_lines, - width, height); + if (from_drawable) + { + gl->read_buffer (src->buffer); + + gl->disable (GLITZ_GL_SCISSOR_TEST); + + while (n_clip--) + { + box.x1 = clip->x1 + src->x_clip; + box.y1 = clip->y1 + src->y_clip; + box.x2 = clip->x2 + src->x_clip; + box.y2 = clip->y2 + src->y_clip; + if (x_src > box.x1) + box.x1 = x_src; + if (y_src > box.y1) + box.y1 = y_src; + if (x_src + width < box.x2) + box.x2 = x_src + width; + if (y_src + height < box.y2) + box.y2 = y_src + height; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->read_pixels (box.x1 + src->x, + src->attached->height - (box.y2 + src->y), + box.x2 - box.x1, box.y2 - box.y1, + gl_format->format, gl_format->type, + pixels + + (y_src + height - box.y2) * bytes_per_line + + (box.x1 - x_src) * bytes_per_pixel); + } + clip++; + } + + gl->enable (GLITZ_GL_SCISSOR_TEST); + } + else + { + glitz_texture_bind (gl, texture); + gl->get_tex_image (texture->target, 0, + gl_format->format, gl_format->type, + pixels); + glitz_texture_unbind (gl, texture); + } - glitz_buffer_unmap (buffer); - } else - glitz_buffer_unbind (buffer); + if (transform) + { + glitz_image_t src_image, dst_image; + + src_image.data = data; + src_image.format = &gl_format->pixel; + src_image.width = src_w; + src_image.height = src_h; + + dst_image.data = glitz_buffer_map (buffer, + GLITZ_BUFFER_ACCESS_WRITE_ONLY); + dst_image.format = format; + dst_image.width = width; + dst_image.height = height; + + clip = src->clip; + n_clip = src->n_clip; + + while (n_clip--) + { + box.x1 = clip->x1 + src->x_clip; + box.y1 = clip->y1 + src->y_clip; + box.x2 = clip->x2 + src->x_clip; + box.y2 = clip->y2 + src->y_clip; + if (x_src > box.x1) + box.x1 = x_src; + if (y_src > box.y1) + box.y1 = y_src; + if (x_src + width < box.x2) + box.x2 = x_src + width; + if (y_src + height < box.y2) + box.y2 = y_src + height; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + _glitz_pixel_transform (transform, + &src_image, + &dst_image, + box.x1 - x_src, box.y1 - y_src, + format->xoffset + box.x1 - x_src, + format->skip_lines + box.y1 - y_src, + box.x2 - box.x1, box.y2 - box.y1); + } + clip++; + } + + glitz_buffer_unmap (buffer); + } else + glitz_buffer_unbind (buffer); - glitz_surface_pop_current (src); + glitz_surface_pop_current (src); - if (data) - free (data); + if (data) + free (data); } diff --git a/src/glitz_program.c b/src/glitz_program.c index b5d0239..7caebc1 100644 --- a/src/glitz_program.c +++ b/src/glitz_program.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -36,36 +36,36 @@ #define EXPAND_RECT "RECT" #define EXPAND_NA "NA" -#define EXPAND_X_IN_SOLID_OP \ - { "", "", "MUL result.color, color, fragment.color.a;" } +#define EXPAND_X_IN_SOLID_OP \ + { "", "", "MUL result.color, color, fragment.color.a;" } + +#define EXPAND_SOLID_IN_X_OP \ + { "", "", "MUL result.color, fragment.color, color.a;" } -#define EXPAND_SOLID_IN_X_OP \ - { "", "", "MUL result.color, fragment.color, color.a;" } - #define EXPAND_SRC_DECL "TEMP src;" -#define EXPAND_SRC_2D_IN_OP \ - { "TXP src, fragment.texcoord[1], texture[1], 2D;", \ - "DP4 color.a, color, fragment.color;", \ - "MUL result.color, src, color.a;" } - -#define EXPAND_SRC_RECT_IN_OP \ - { "TXP src, fragment.texcoord[1], texture[1], RECT;", \ - "DP4 color.a, color, fragment.color;", \ - "MUL result.color, src, color.a;" } +#define EXPAND_SRC_2D_IN_OP \ + { "TXP src, fragment.texcoord[1], texture[1], 2D;", \ + "DP4 color.a, color, fragment.color;", \ + "MUL result.color, src, color.a;" } + +#define EXPAND_SRC_RECT_IN_OP \ + { "TXP src, fragment.texcoord[1], texture[1], RECT;", \ + "DP4 color.a, color, fragment.color;", \ + "MUL result.color, src, color.a;" } #define EXPAND_MASK_DECL "TEMP mask;" -#define EXPAND_MASK_2D_IN_OP \ - { "TXP mask, fragment.texcoord[0], texture[0], 2D;", \ - "DP4 mask.a, mask, fragment.color;", \ - "MUL result.color, color, mask.a;" } +#define EXPAND_MASK_2D_IN_OP \ + { "TXP mask, fragment.texcoord[0], texture[0], 2D;", \ + "DP4 mask.a, mask, fragment.color;", \ + "MUL result.color, color, mask.a;" } -#define EXPAND_MASK_RECT_IN_OP \ - { "TXP mask, fragment.texcoord[0], texture[0], RECT;", \ - "DP4 mask.a, mask, fragment.color;", \ - "MUL result.color, color, mask.a;" } +#define EXPAND_MASK_RECT_IN_OP \ + { "TXP mask, fragment.texcoord[0], texture[0], RECT;", \ + "DP4 mask.a, mask, fragment.color;", \ + "MUL result.color, color, mask.a;" } -#define EXPAND_IN_NA \ - { "NA", "NA", "NA" } +#define EXPAND_IN_NA \ + { "NA", "NA", "NA" } typedef struct _glitz_program_expand_t glitz_program_expand_t; @@ -76,98 +76,98 @@ typedef struct _glitz_inop { } glitz_in_op_t; static const struct _glitz_program_expand_t { - char *texture; - char *declarations; - glitz_in_op_t in; + char *texture; + char *declarations; + glitz_in_op_t in; } _program_expand_map[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST][2] = { - { - /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_NONE] */ - { - { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }, - { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA } - }, - - /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_2D] */ { - { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }, - { EXPAND_2D, EXPAND_NONE, EXPAND_SOLID_IN_X_OP } - }, - - /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_RECT] */ - { - { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }, - { EXPAND_RECT, EXPAND_NONE, EXPAND_SOLID_IN_X_OP } + /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_NONE] */ + { + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }, + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA } + }, + + /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_2D] */ + { + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }, + { EXPAND_2D, EXPAND_NONE, EXPAND_SOLID_IN_X_OP } + }, + + /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_RECT] */ + { + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }, + { EXPAND_RECT, EXPAND_NONE, EXPAND_SOLID_IN_X_OP } + } + }, { + + /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_NONE] */ + { + { EXPAND_2D, EXPAND_NONE, EXPAND_X_IN_SOLID_OP }, + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA } + }, + + /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_2D] */ + { + { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP }, + { EXPAND_2D, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP } + }, + + /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_RECT] */ + { + { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP }, + { EXPAND_RECT, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP } + } + }, { + + /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_NONE] */ + { + { EXPAND_RECT, EXPAND_NONE, EXPAND_X_IN_SOLID_OP }, + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA } + }, + + /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_2D] */ + { + { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP }, + { EXPAND_2D, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP } + }, + + /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_RECT] */ + { + { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP }, + { EXPAND_RECT, EXPAND_SRC_DECL, EXPAND_SRC_RECT_IN_OP } + } } - }, { - - /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_NONE] */ - { - { EXPAND_2D, EXPAND_NONE, EXPAND_X_IN_SOLID_OP }, - { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA } - }, - - /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_2D] */ - { - { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP }, - { EXPAND_2D, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP } - }, - - /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_RECT] */ - { - { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP }, - { EXPAND_RECT, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP } - } - }, { - - /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_NONE] */ - { - { EXPAND_RECT, EXPAND_NONE, EXPAND_X_IN_SOLID_OP }, - { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA } - }, - - /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_2D] */ - { - { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP }, - { EXPAND_2D, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP } - }, - - /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_RECT] */ - { - { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP }, - { EXPAND_RECT, EXPAND_SRC_DECL, EXPAND_SRC_RECT_IN_OP } - } - } }; /* * general convolution filter. */ static const char *_convolution_header[] = { - "PARAM p[%d] = { program.local[0..%d] };", - "ATTRIB pos = fragment.texcoord[%s];", - "TEMP color, in, coord, position;", - - /* extra declarations */ - "%s" - - /* perspective divide */ - "RCP position.w, pos.w;", - "MUL position, pos, position.w;", NULL + "PARAM p[%d] = { program.local[0..%d] };", + "ATTRIB pos = fragment.texcoord[%s];", + "TEMP color, in, coord, position;", + + /* extra declarations */ + "%s" + + /* perspective divide */ + "RCP position.w, pos.w;", + "MUL position, pos, position.w;", NULL }; static const char *_convolution_sample_first[] = { - "MOV coord, 0.0;", - "ADD coord.x, position.x, p[0].x;", - "ADD coord.y, position.y, p[0].y;", - "TEX in, coord, texture[%s], %s;", - "MUL color, in, p[0].z;", NULL + "MOV coord, 0.0;", + "ADD coord.x, position.x, p[0].x;", + "ADD coord.y, position.y, p[0].y;", + "TEX in, coord, texture[%s], %s;", + "MUL color, in, p[0].z;", NULL }; static const char *_convolution_sample[] = { - "ADD coord.x, position.x, p[%d].x;", - "ADD coord.y, position.y, p[%d].y;", - "TEX in, coord, texture[%s], %s;", - "MAD color, in, p[%d].z, color;", NULL + "ADD coord.x, position.x, p[%d].x;", + "ADD coord.y, position.y, p[%d].y;", + "TEX in, coord, texture[%s], %s;", + "MAD color, in, p[%d].z, color;", NULL }; @@ -175,17 +175,17 @@ static const char *_convolution_sample[] = { * gradient filters. */ static const char *_gradient_header[] = { - "PARAM gradient = program.local[0];", - "PARAM stops[%d] = { program.local[1..%d] };", - "ATTRIB pos = fragment.texcoord[%s];", - "TEMP color, second_color, stop0, stop1, position;", + "PARAM gradient = program.local[0];", + "PARAM stops[%d] = { program.local[1..%d] };", + "ATTRIB pos = fragment.texcoord[%s];", + "TEMP color, second_color, stop0, stop1, position;", - /* extra declarations */ - "%s", + /* extra declarations */ + "%s", - /* perspective divide */ - "RCP position.w, pos.w;", - "MUL position, pos, position.w;", NULL + /* perspective divide */ + "RCP position.w, pos.w;", + "MUL position, pos, position.w;", NULL }; /* @@ -197,10 +197,10 @@ static const char *_gradient_header[] = { * gradient.w = -sin (angle) */ static const char *_linear_gradient_calculations[] = { - "MUL position.x, gradient.z, position.x;", - "MAD position.x, gradient.w, position.y, position.x;", - "SUB position.z, position.x, gradient.x;", - "MUL position.z, position.z, gradient.y;", NULL + "MUL position.x, gradient.z, position.x;", + "MAD position.x, gradient.w, position.y, position.x;", + "SUB position.z, position.x, gradient.x;", + "MUL position.z, position.z, gradient.y;", NULL }; /* @@ -212,171 +212,172 @@ static const char *_linear_gradient_calculations[] = { * gradient.w = 1 / (radius1 - radius0) */ static const char *_radial_gradient_calculations[] = { - "SUB position, position, gradient;", - "MUL position.x, position.x, position.x;", - "MAD position.x, position.y, position.y, position.x;", - "RSQ position.y, position.x;", - "RCP position.x, position.y;", - "MUL position.x, position.x, position.x;", - "MUL position.x, position.x, position.y;", - "SUB position.x, position.x, gradient.z;", - "MUL position.z, position.x, gradient.w;", NULL + "SUB position, position, gradient;", + "MUL position.x, position.x, position.x;", + "MAD position.x, position.y, position.y, position.x;", + "RSQ position.y, position.x;", + "RCP position.x, position.y;", + "MUL position.x, position.x, position.x;", + "MUL position.x, position.x, position.y;", + "SUB position.x, position.x, gradient.z;", + "MUL position.z, position.x, gradient.w;", NULL }; static const char *_gradient_fill_repeat[] = { - "FRC position.z, position.z;", NULL + "FRC position.z, position.z;", NULL }; static const char *_gradient_fill_reflect[] = { - "FLR position.w, position.z;", - "MUL position.w, position.w, 0.5;", - "FLR position.w, position.w;", - "MUL position.y, position.w, 2.0;", - "FLR position.x, position.z;", - "SUB position.y, position.x, position.y;", - "FRC position.x, position.z;", - "SUB position.x, position.x, position.y;", - "ABS position.z, position.x;", NULL + "FLR position.w, position.z;", + "MUL position.w, position.w, 0.5;", + "FLR position.w, position.w;", + "MUL position.y, position.w, 2.0;", + "FLR position.x, position.z;", + "SUB position.y, position.x, position.y;", + "FRC position.x, position.z;", + "SUB position.x, position.x, position.y;", + "ABS position.z, position.x;", NULL }; static const char *_gradient_init_stops[] = { - "MOV stop0, stops[0];", - "MOV stop1, stops[%d];", NULL + "MOV stop0, stops[0];", + "MOV stop1, stops[%d];", NULL }; static const char *_gradient_lower_stop[] = { - "SLT position.x, stops[%d].z, position.z;", - "CMP stop0, -position.x, stops[%d], stop0;", NULL + "SLT position.x, stops[%d].z, position.z;", + "CMP stop0, -position.x, stops[%d], stop0;", NULL }; static const char *_gradient_higher_stop[] = { - "SLT position.x, position.z, stops[%d].z;", - "CMP stop1, -position.x, stops[%d], stop1;", NULL + "SLT position.x, position.z, stops[%d].z;", + "CMP stop1, -position.x, stops[%d], stop1;", NULL }; static const char *_gradient_fetch_and_interpolate[] = { - "TEX color, stop0, texture[%s], %s;", - "TEX second_color, stop1, texture[%s], %s;", + "TEX color, stop0, texture[%s], %s;", + "TEX second_color, stop1, texture[%s], %s;", - /* normalize gradient offset to color stop span */ - "SUB position.z, position.z, stop0.z;", - "MUL_SAT position.z, position.z, stop0.w;", + /* normalize gradient offset to color stop span */ + "SUB position.z, position.z, stop0.z;", + "MUL_SAT position.z, position.z, stop0.w;", - /* linear interpolation */ - "LRP color, position.z, second_color, color;", NULL + /* linear interpolation */ + "LRP color, position.z, second_color, color;", NULL }; static struct _glitz_program_query { - glitz_gl_enum_t query; - glitz_gl_enum_t max_query; - glitz_gl_int_t min; + glitz_gl_enum_t query; + glitz_gl_enum_t max_query; + glitz_gl_int_t min; } _program_limits[] = { - { GLITZ_GL_PROGRAM_INSTRUCTIONS, - GLITZ_GL_MAX_PROGRAM_INSTRUCTIONS, 1 }, - { GLITZ_GL_PROGRAM_NATIVE_INSTRUCTIONS, - GLITZ_GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS, 1 }, - { GLITZ_GL_PROGRAM_PARAMETERS, - GLITZ_GL_MAX_PROGRAM_PARAMETERS, 1 }, - { GLITZ_GL_PROGRAM_NATIVE_PARAMETERS, - GLITZ_GL_MAX_PROGRAM_NATIVE_PARAMETERS, 1 }, - { GLITZ_GL_PROGRAM_ALU_INSTRUCTIONS, - GLITZ_GL_MAX_PROGRAM_ALU_INSTRUCTIONS, 0 }, - { GLITZ_GL_PROGRAM_TEX_INSTRUCTIONS, - GLITZ_GL_MAX_PROGRAM_TEX_INSTRUCTIONS, 1 }, - { GLITZ_GL_PROGRAM_TEX_INDIRECTIONS, - GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS, 0 }, - { GLITZ_GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS, - GLITZ_GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS, 0 }, - { GLITZ_GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS, - GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS, 0 }, - { GLITZ_GL_PROGRAM_NATIVE_TEX_INDIRECTIONS, - GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS, 0 }, + { GLITZ_GL_PROGRAM_INSTRUCTIONS, + GLITZ_GL_MAX_PROGRAM_INSTRUCTIONS, 1 }, + { GLITZ_GL_PROGRAM_NATIVE_INSTRUCTIONS, + GLITZ_GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS, 1 }, + { GLITZ_GL_PROGRAM_PARAMETERS, + GLITZ_GL_MAX_PROGRAM_PARAMETERS, 1 }, + { GLITZ_GL_PROGRAM_NATIVE_PARAMETERS, + GLITZ_GL_MAX_PROGRAM_NATIVE_PARAMETERS, 1 }, + { GLITZ_GL_PROGRAM_ALU_INSTRUCTIONS, + GLITZ_GL_MAX_PROGRAM_ALU_INSTRUCTIONS, 0 }, + { GLITZ_GL_PROGRAM_TEX_INSTRUCTIONS, + GLITZ_GL_MAX_PROGRAM_TEX_INSTRUCTIONS, 1 }, + { GLITZ_GL_PROGRAM_TEX_INDIRECTIONS, + GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS, 0 }, + { GLITZ_GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS, + GLITZ_GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS, 0 }, + { GLITZ_GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS, + GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS, 0 }, + { GLITZ_GL_PROGRAM_NATIVE_TEX_INDIRECTIONS, + GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS, 0 }, }; static glitz_bool_t _glitz_program_under_limits (glitz_gl_proc_address_list_t *gl) { - int i, n_limits; + int i, n_limits; + + n_limits = sizeof (_program_limits) / + (sizeof (struct _glitz_program_query)); - n_limits = sizeof (_program_limits) / (sizeof (struct _glitz_program_query)); + for (i = 0; i < n_limits; i++) { + glitz_gl_int_t value, max; - for (i = 0; i < n_limits; i++) { - glitz_gl_int_t value, max; + gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM, + _program_limits[i].query, &value); + gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM, + _program_limits[i].max_query, &max); - gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM, - _program_limits[i].query, &value); - gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM, - _program_limits[i].max_query, &max); + if (value < _program_limits[i].min) + return 0; - if (value < _program_limits[i].min) - return 0; - - if (value >= max) - return 0; - } + if (value >= max) + return 0; + } - return 1; + return 1; } static glitz_gl_int_t _glitz_compile_arb_fragment_program (glitz_gl_proc_address_list_t *gl, - char *program_string, - int n_parameters) + char *program_string, + int n_parameters) { - glitz_gl_int_t error, pid = -1; - glitz_gl_uint_t program; - - /* clear error flags */ - while (gl->get_error () != GLITZ_GL_NO_ERROR); - - gl->gen_programs (1, &program); - gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, program); - gl->program_string (GLITZ_GL_FRAGMENT_PROGRAM, - GLITZ_GL_PROGRAM_FORMAT_ASCII, - strlen (program_string), - program_string); - if (gl->get_error () == GLITZ_GL_NO_ERROR) { - gl->get_integer_v (GLITZ_GL_PROGRAM_ERROR_POSITION, &error); - - if (error == -1) { - glitz_gl_int_t value; - - gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM, - GLITZ_GL_PROGRAM_UNDER_NATIVE_LIMITS, - &value); - - if (value == GLITZ_GL_TRUE) { - gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM, - GLITZ_GL_MAX_PROGRAM_LOCAL_PARAMETERS, - &value); - - if (value >= n_parameters) { - if (_glitz_program_under_limits (gl)) - pid = program; - } - } + glitz_gl_int_t error, pid = -1; + glitz_gl_uint_t program; + + /* clear error flags */ + while (gl->get_error () != GLITZ_GL_NO_ERROR); + + gl->gen_programs (1, &program); + gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, program); + gl->program_string (GLITZ_GL_FRAGMENT_PROGRAM, + GLITZ_GL_PROGRAM_FORMAT_ASCII, + strlen (program_string), + program_string); + if (gl->get_error () == GLITZ_GL_NO_ERROR) { + gl->get_integer_v (GLITZ_GL_PROGRAM_ERROR_POSITION, &error); + + if (error == -1) { + glitz_gl_int_t value; + + gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM, + GLITZ_GL_PROGRAM_UNDER_NATIVE_LIMITS, + &value); + + if (value == GLITZ_GL_TRUE) { + gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM, + GLITZ_GL_MAX_PROGRAM_LOCAL_PARAMETERS, + &value); + + if (value >= n_parameters) { + if (_glitz_program_under_limits (gl)) + pid = program; + } + } + } } - } - - if (pid == -1) { - gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, 0); - gl->delete_programs (1, &program); - } - - return pid; + + if (pid == -1) { + gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, 0); + gl->delete_programs (1, &program); + } + + return pid; } static void _string_array_to_char_array (char *dst, const char *src[]) { - int i, n; - - for (i = 0; src[i]; i++) { - n = strlen (src[i]); - memcpy (dst, src[i], n); - dst += n; - } - *dst = '\0'; + int i, n; + + for (i = 0; src[i]; i++) { + n = strlen (src[i]); + memcpy (dst, src[i], n); + dst += n; + } + *dst = '\0'; } /* these should be more than enough */ @@ -388,231 +389,234 @@ _string_array_to_char_array (char *dst, const char *src[]) static glitz_gl_uint_t _glitz_create_fragment_program (glitz_composite_op_t *op, - int fp_type, - int id, - const glitz_program_expand_t *expand) + int fp_type, + int id, + const glitz_program_expand_t *expand) { - char buffer[1024], *program = NULL, *tex, *p = NULL; - char *texture_type, *extra_declarations; - const glitz_in_op_t *in; - glitz_gl_uint_t fp; - int i; - - switch (op->type) { - case GLITZ_COMBINE_TYPE_ARGBF: - case GLITZ_COMBINE_TYPE_ARGBF_SOLID: - case GLITZ_COMBINE_TYPE_ARGBF_SOLIDC: - i = 0; - tex = "0"; - break; - case GLITZ_COMBINE_TYPE_ARGB_ARGBF: - case GLITZ_COMBINE_TYPE_SOLID_ARGBF: - i = 1; - tex = "0"; - break; - case GLITZ_COMBINE_TYPE_ARGBF_ARGB: - case GLITZ_COMBINE_TYPE_ARGBF_ARGBC: - i = 0; - tex = "1"; - break; - default: - return 0; - } - - texture_type = expand[i].texture; - extra_declarations = expand[i].declarations; - in = &expand[i].in; - - switch (fp_type) { - case GLITZ_FP_CONVOLUTION: - program = malloc (CONVOLUTION_BASE_SIZE + CONVOLUTION_SAMPLE_SIZE * id); - if (program == NULL) - return 0; - - p = program; - - p += sprintf (p, "!!ARBfp1.0"); - - _string_array_to_char_array (buffer, _convolution_header); - p += sprintf (p, buffer, id, id - 1, tex, extra_declarations); - - _string_array_to_char_array (buffer, _convolution_sample_first); - p += sprintf (p, buffer, tex, texture_type); - - _string_array_to_char_array (buffer, _convolution_sample); - for (i = 1; i < id; i++) - p += sprintf (p, buffer, i, i, tex, texture_type, i); - - break; - case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT: - case GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT: - id += 2; - /* fall-through */ - case GLITZ_FP_LINEAR_GRADIENT_NEAREST: - case GLITZ_FP_LINEAR_GRADIENT_REPEAT: - case GLITZ_FP_LINEAR_GRADIENT_REFLECT: - case GLITZ_FP_RADIAL_GRADIENT_NEAREST: - case GLITZ_FP_RADIAL_GRADIENT_REPEAT: - case GLITZ_FP_RADIAL_GRADIENT_REFLECT: - program = malloc (GRADIENT_BASE_SIZE + GRADIENT_STOP_SIZE * id); - if (program == NULL) - return 0; - - p = program; - - p += sprintf (p, "!!ARBfp1.0"); - - _string_array_to_char_array (buffer, _gradient_header); - p += sprintf (p, buffer, id, id, tex, extra_declarations); - - switch (fp_type) { - case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT: - case GLITZ_FP_LINEAR_GRADIENT_NEAREST: - case GLITZ_FP_LINEAR_GRADIENT_REPEAT: - case GLITZ_FP_LINEAR_GRADIENT_REFLECT: - _string_array_to_char_array (buffer, _linear_gradient_calculations); - break; + char buffer[1024], *program = NULL, *tex, *p = NULL; + char *texture_type, *extra_declarations; + const glitz_in_op_t *in; + glitz_gl_uint_t fp; + int i; + + switch (op->type) { + case GLITZ_COMBINE_TYPE_ARGBF: + case GLITZ_COMBINE_TYPE_ARGBF_SOLID: + case GLITZ_COMBINE_TYPE_ARGBF_SOLIDC: + i = 0; + tex = "0"; + break; + case GLITZ_COMBINE_TYPE_ARGB_ARGBF: + case GLITZ_COMBINE_TYPE_SOLID_ARGBF: + i = 1; + tex = "0"; + break; + case GLITZ_COMBINE_TYPE_ARGBF_ARGB: + case GLITZ_COMBINE_TYPE_ARGBF_ARGBC: + i = 0; + tex = "1"; + break; default: - _string_array_to_char_array (buffer, _radial_gradient_calculations); - break; + return 0; } - p += sprintf (p, buffer); - + texture_type = expand[i].texture; + extra_declarations = expand[i].declarations; + in = &expand[i].in; + switch (fp_type) { + case GLITZ_FP_CONVOLUTION: + program = malloc (CONVOLUTION_BASE_SIZE + + CONVOLUTION_SAMPLE_SIZE * id); + if (program == NULL) + return 0; + + p = program; + + p += sprintf (p, "!!ARBfp1.0"); + + _string_array_to_char_array (buffer, _convolution_header); + p += sprintf (p, buffer, id, id - 1, tex, extra_declarations); + + _string_array_to_char_array (buffer, _convolution_sample_first); + p += sprintf (p, buffer, tex, texture_type); + + _string_array_to_char_array (buffer, _convolution_sample); + for (i = 1; i < id; i++) + p += sprintf (p, buffer, i, i, tex, texture_type, i); + + break; + case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT: + case GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT: + id += 2; + /* fall-through */ + case GLITZ_FP_LINEAR_GRADIENT_NEAREST: case GLITZ_FP_LINEAR_GRADIENT_REPEAT: - case GLITZ_FP_RADIAL_GRADIENT_REPEAT: - _string_array_to_char_array (buffer, _gradient_fill_repeat); - p += sprintf (p, buffer); - break; case GLITZ_FP_LINEAR_GRADIENT_REFLECT: + case GLITZ_FP_RADIAL_GRADIENT_NEAREST: + case GLITZ_FP_RADIAL_GRADIENT_REPEAT: case GLITZ_FP_RADIAL_GRADIENT_REFLECT: - _string_array_to_char_array (buffer, _gradient_fill_reflect); - p += sprintf (p, buffer); - break; + program = malloc (GRADIENT_BASE_SIZE + GRADIENT_STOP_SIZE * id); + if (program == NULL) + return 0; + + p = program; + + p += sprintf (p, "!!ARBfp1.0"); + + _string_array_to_char_array (buffer, _gradient_header); + p += sprintf (p, buffer, id, id, tex, extra_declarations); + + switch (fp_type) { + case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT: + case GLITZ_FP_LINEAR_GRADIENT_NEAREST: + case GLITZ_FP_LINEAR_GRADIENT_REPEAT: + case GLITZ_FP_LINEAR_GRADIENT_REFLECT: + _string_array_to_char_array (buffer, + _linear_gradient_calculations); + break; + default: + _string_array_to_char_array (buffer, + _radial_gradient_calculations); + break; + } + + p += sprintf (p, buffer); + + switch (fp_type) { + case GLITZ_FP_LINEAR_GRADIENT_REPEAT: + case GLITZ_FP_RADIAL_GRADIENT_REPEAT: + _string_array_to_char_array (buffer, _gradient_fill_repeat); + p += sprintf (p, buffer); + break; + case GLITZ_FP_LINEAR_GRADIENT_REFLECT: + case GLITZ_FP_RADIAL_GRADIENT_REFLECT: + _string_array_to_char_array (buffer, _gradient_fill_reflect); + p += sprintf (p, buffer); + break; + default: + break; + } + + _string_array_to_char_array (buffer, _gradient_init_stops); + p += sprintf (p, buffer, id - 1); + + _string_array_to_char_array (buffer, _gradient_lower_stop); + for (i = 1; i < (id - 1); i++) + p += sprintf (p, buffer, i, i); + + _string_array_to_char_array (buffer, _gradient_higher_stop); + for (i = 1; i < (id - 1); i++) + p += sprintf (p, buffer, id - i - 1, id - i - 1); + + _string_array_to_char_array (buffer, _gradient_fetch_and_interpolate); + p += sprintf (p, buffer, tex, texture_type, tex, texture_type); + + id++; + break; default: - break; + return 0; } - - _string_array_to_char_array (buffer, _gradient_init_stops); - p += sprintf (p, buffer, id - 1); - - _string_array_to_char_array (buffer, _gradient_lower_stop); - for (i = 1; i < (id - 1); i++) - p += sprintf (p, buffer, i, i); - - _string_array_to_char_array (buffer, _gradient_higher_stop); - for (i = 1; i < (id - 1); i++) - p += sprintf (p, buffer, id - i - 1, id - i - 1); - - _string_array_to_char_array (buffer, _gradient_fetch_and_interpolate); - p += sprintf (p, buffer, tex, texture_type, tex, texture_type); - - id++; - break; - default: - return 0; - } - - if (program == NULL) - return 0; - - p += sprintf (p, "%s", in->fetch); - if (op->per_component) - p += sprintf (p, "%s", in->dot_product); - p += sprintf (p, "%s", in->mult); - sprintf (p, "END"); - - fp = _glitz_compile_arb_fragment_program (op->gl, program, id); - - free (program); - - return fp; + + if (program == NULL) + return 0; + + p += sprintf (p, "%s", in->fetch); + if (op->per_component) + p += sprintf (p, "%s", in->dot_product); + p += sprintf (p, "%s", in->mult); + sprintf (p, "END"); + + fp = _glitz_compile_arb_fragment_program (op->gl, program, id); + + free (program); + + return fp; } - + void glitz_program_map_init (glitz_program_map_t *map) { - memset (map, 0, sizeof (glitz_program_map_t)); + memset (map, 0, sizeof (glitz_program_map_t)); } void glitz_program_map_fini (glitz_gl_proc_address_list_t *gl, - glitz_program_map_t *map) + glitz_program_map_t *map) { - glitz_gl_uint_t program; - int i, j, k, x, y; - - for (i = 0; i < GLITZ_COMBINE_TYPES; i++) { - for (j = 0; j < GLITZ_FP_TYPES; j++) { - for (x = 0; x < GLITZ_TEXTURE_LAST; x++) { - for (y = 0; y < GLITZ_TEXTURE_LAST; y++) { - glitz_program_t *p = &map->filters[i][j].fp[x][y]; - - if (p->name) { - for (k = 0; k < p->size; k++) - if (p->name[k] > 0) { - program = p->name[k]; - gl->delete_programs (1, &program); - } - - free (p->name); - } - } - } + glitz_gl_uint_t program; + int i, j, k, x, y; + + for (i = 0; i < GLITZ_COMBINE_TYPES; i++) { + for (j = 0; j < GLITZ_FP_TYPES; j++) { + for (x = 0; x < GLITZ_TEXTURE_LAST; x++) { + for (y = 0; y < GLITZ_TEXTURE_LAST; y++) { + glitz_program_t *p = &map->filters[i][j].fp[x][y]; + + if (p->name) { + for (k = 0; k < p->size; k++) + if (p->name[k] > 0) { + program = p->name[k]; + gl->delete_programs (1, &program); + } + + free (p->name); + } + } + } + } } - } } -#define TEXTURE_INDEX(surface) \ - ((surface)? \ - (((surface)->texture.target == GLITZ_GL_TEXTURE_2D)? \ - GLITZ_TEXTURE_2D: \ - GLITZ_TEXTURE_RECT \ - ) : \ - GLITZ_TEXTURE_NONE \ - ) +#define TEXTURE_INDEX(surface) \ + ((surface)? \ + (((surface)->texture.target == GLITZ_GL_TEXTURE_2D)? \ + GLITZ_TEXTURE_2D: \ + GLITZ_TEXTURE_RECT \ + ) : \ + GLITZ_TEXTURE_NONE \ + ) glitz_gl_uint_t glitz_get_fragment_program (glitz_composite_op_t *op, - int fp_type, - int id) + int fp_type, + int id) { - glitz_program_map_t *map; - glitz_program_t *program; - int t0 = TEXTURE_INDEX (op->src); - int t1 = TEXTURE_INDEX (op->mask); - - map = op->dst->drawable->backend->program_map; - program = &map->filters[op->type][fp_type].fp[t0][t1]; - - if (program->size < id) { - int old_size; - - program->name = realloc (program->name, - id * sizeof (glitz_gl_uint_t)); - if (program->name == NULL) { - glitz_surface_status_add (op->dst, GLITZ_STATUS_NO_MEMORY_MASK); - return 0; + glitz_program_map_t *map; + glitz_program_t *program; + int t0 = TEXTURE_INDEX (op->src); + int t1 = TEXTURE_INDEX (op->mask); + + map = op->dst->drawable->backend->program_map; + program = &map->filters[op->type][fp_type].fp[t0][t1]; + + if (program->size < id) { + int old_size; + + program->name = realloc (program->name, + id * sizeof (glitz_gl_uint_t)); + if (program->name == NULL) { + glitz_surface_status_add (op->dst, GLITZ_STATUS_NO_MEMORY_MASK); + return 0; + } + old_size = program->size; + program->size = id; + memset (program->name + old_size, 0, + (program->size - old_size) * sizeof (glitz_gl_uint_t)); + } + + if (program->name[id - 1] == 0) { + glitz_surface_push_current (op->dst, GLITZ_CONTEXT_CURRENT); + + program->name[id - 1] = + _glitz_create_fragment_program (op, fp_type, id, + _program_expand_map[t0][t1]); + + glitz_surface_pop_current (op->dst); } - old_size = program->size; - program->size = id; - memset (program->name + old_size, 0, - (program->size - old_size) * sizeof (glitz_gl_uint_t)); - } - - if (program->name[id - 1] == 0) { - glitz_surface_push_current (op->dst, GLITZ_CONTEXT_CURRENT); - - program->name[id - 1] = - _glitz_create_fragment_program (op, fp_type, id, - _program_expand_map[t0][t1]); - - glitz_surface_pop_current (op->dst); - } - - if (program->name[id - 1] > 0) - return program->name[id - 1]; - else - return 0; + + if (program->name[id - 1] > 0) + return program->name[id - 1]; + else + return 0; } diff --git a/src/glitz_rect.c b/src/glitz_rect.c index 360c635..d9f5c04 100644 --- a/src/glitz_rect.c +++ b/src/glitz_rect.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -29,260 +29,259 @@ #include "glitzint.h" -#define STORE_16(dst, size, src) \ - dst = ((size) ? \ - ((((((1L << (size)) - 1L) * (src)) / 0xffff) * 0xffff) / \ - ((1L << (size)) - 1L)) : \ - dst) +#define STORE_16(dst, size, src) \ + dst = ((size) ? \ + ((((((1L << (size)) - 1L) * (src)) / 0xffff) * 0xffff) / \ + ((1L << (size)) - 1L)) : \ + dst) static glitz_buffer_t * _glitz_minimum_buffer (glitz_surface_t *surface, - const glitz_rectangle_t *rects, - int n_rects, - unsigned int *pixel) + const glitz_rectangle_t *rects, + int n_rects, + unsigned int *pixel) { glitz_buffer_t *buffer; int i, size = 0; unsigned int *data; - + while (n_rects--) { - i = rects->width * rects->height; - if (i > size) - size = i; - - rects++; + i = rects->width * rects->height; + if (i > size) + size = i; + + rects++; } if (size <= 1) - return glitz_buffer_create_for_data (pixel); - + return glitz_buffer_create_for_data (pixel); + buffer = glitz_pixel_buffer_create (surface->drawable, NULL, - size * sizeof (unsigned int), - GLITZ_BUFFER_HINT_STATIC_DRAW); + size * sizeof (unsigned int), + GLITZ_BUFFER_HINT_STATIC_DRAW); if (!buffer) - return NULL; - + return NULL; + data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); - + while (size--) - *data++ = *pixel; + *data++ = *pixel; glitz_buffer_unmap (buffer); - + return buffer; } void glitz_set_rectangles (glitz_surface_t *dst, - const glitz_color_t *color, - const glitz_rectangle_t *rects, - int n_rects) + const glitz_color_t *color, + const glitz_rectangle_t *rects, + int n_rects) { GLITZ_GL_SURFACE (dst); if (n_rects < 1) - return; + return; if (SURFACE_SOLID (dst)) { - glitz_color_t old = dst->solid; - glitz_box_t *clip = dst->clip; - int n_clip = dst->n_clip; - - for (; n_clip; clip++, n_clip--) - { - if (clip->x1 > 0 || - clip->y1 > 0 || - clip->x2 < 1 || - clip->y2 < 1) - continue; - - for (; n_rects; rects++, n_rects--) - { - if (rects->x > 0 || - rects->y > 0 || - (rects->x + rects->width) < 1 || - (rects->y + rects->height) < 1) - continue; - - STORE_16 (dst->solid.red, - dst->format->color.red_size, - color->red); - STORE_16 (dst->solid.green, - dst->format->color.green_size, - color->green); - STORE_16 (dst->solid.blue, - dst->format->color.blue_size, - color->blue); - STORE_16 (dst->solid.alpha, - dst->format->color.alpha_size, - color->alpha); - - if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK) - { - dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; - glitz_surface_damage (dst, &dst->box, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_DRAWABLE_MASK); - } - else - { - if (dst->solid.red != old.red || - dst->solid.green != old.green || - dst->solid.blue != old.blue || - dst->solid.alpha != old.alpha) - glitz_surface_damage (dst, &dst->box, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_DRAWABLE_MASK); - } - break; - } - break; - } + glitz_color_t old = dst->solid; + glitz_box_t *clip = dst->clip; + int n_clip = dst->n_clip; + + for (; n_clip; clip++, n_clip--) + { + if (clip->x1 > 0 || + clip->y1 > 0 || + clip->x2 < 1 || + clip->y2 < 1) + continue; + + for (; n_rects; rects++, n_rects--) + { + if (rects->x > 0 || + rects->y > 0 || + (rects->x + rects->width) < 1 || + (rects->y + rects->height) < 1) + continue; + + STORE_16 (dst->solid.red, + dst->format->color.red_size, + color->red); + STORE_16 (dst->solid.green, + dst->format->color.green_size, + color->green); + STORE_16 (dst->solid.blue, + dst->format->color.blue_size, + color->blue); + STORE_16 (dst->solid.alpha, + dst->format->color.alpha_size, + color->alpha); + + if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK) + { + dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; + glitz_surface_damage (dst, &dst->box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_DRAWABLE_MASK); + } + else + { + if (dst->solid.red != old.red || + dst->solid.green != old.green || + dst->solid.blue != old.blue || + dst->solid.alpha != old.alpha) + glitz_surface_damage (dst, &dst->box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_DRAWABLE_MASK); + } + break; + } + break; + } } else { - static glitz_pixel_format_t pf = { - { - 32, - 0xff000000, - 0x00ff0000, - 0x0000ff00, - 0x000000ff - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - }; - glitz_buffer_t *buffer = NULL; - glitz_box_t box; - glitz_bool_t drawable = 0; - - if (n_rects == 1 && rects->width <= 1 && rects->height <= 1) - { - glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); - } - else - { - drawable = glitz_surface_push_current (dst, - GLITZ_DRAWABLE_CURRENT); - } - - if (drawable) - { - glitz_box_t *clip; - int n_clip; - int target_height = SURFACE_DRAWABLE_HEIGHT (dst); - - gl->clear_color (color->red / (glitz_gl_clampf_t) 0xffff, - color->green / (glitz_gl_clampf_t) 0xffff, - color->blue / (glitz_gl_clampf_t) 0xffff, - color->alpha / (glitz_gl_clampf_t) 0xffff); - - while (n_rects--) - { - clip = dst->clip; - n_clip = dst->n_clip; - while (n_clip--) - { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - - if (dst->box.x1 > box.x1) - box.x1 = dst->box.x1; - if (dst->box.y1 > box.y1) - box.y1 = dst->box.y1; - if (dst->box.x2 < box.x2) - box.x2 = dst->box.x2; - if (dst->box.y2 < box.y2) - box.y2 = dst->box.y2; - - if (rects->x > box.x1) - box.x1 = rects->x; - if (rects->y > box.y1) - box.y1 = rects->y; - if (rects->x + rects->width < box.x2) - box.x2 = rects->x + rects->width; - if (rects->y + rects->height < box.y2) - box.y2 = rects->y + rects->height; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - gl->scissor (box.x1, - target_height - dst->y - box.y2, - box.x2 - box.x1, - box.y2 - box.y1); - - gl->clear (GLITZ_GL_COLOR_BUFFER_BIT); - - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_SOLID_MASK); - } - - clip++; - } - rects++; - } - } - else - { - unsigned int pixel = - ((((unsigned int) color->alpha * 0xff) / 0xffff) << 24) | - ((((unsigned int) color->red * 0xff) / 0xffff) << 16) | - ((((unsigned int) color->green * 0xff) / 0xffff) << 8) | - ((((unsigned int) color->blue * 0xff) / 0xffff)); - int x1, y1, x2, y2; - - buffer = _glitz_minimum_buffer (dst, rects, n_rects, &pixel); - if (!buffer) - { - glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); - return; - } - - while (n_rects--) - { - x1 = rects->x; - y1 = rects->y; - x2 = x1 + rects->width; - y2 = y1 + rects->height; - - if (x1 < 0) - x1 = 0; - if (y1 < 0) - y1 = 0; - if (x2 > dst->box.x2) - x2 = dst->box.x2; - if (y2 > dst->box.y2) - y2 = dst->box.y2; - - if (x1 < x2 && y1 < y2) - glitz_set_pixels (dst, - x1, y1, - x2 - x1, y2 - y1, - &pf, buffer); - - rects++; - } - - if (buffer) - glitz_buffer_destroy (buffer); - } - glitz_surface_pop_current (dst); + static glitz_pixel_format_t pf = { + { + 32, + 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }; + glitz_buffer_t *buffer = NULL; + glitz_box_t box; + glitz_bool_t drawable = 0; + + if (n_rects == 1 && rects->width <= 1 && rects->height <= 1) + { + glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); + } + else + { + drawable = glitz_surface_push_current (dst, + GLITZ_DRAWABLE_CURRENT); + } + + if (drawable) + { + glitz_box_t *clip; + int n_clip; + + gl->clear_color (color->red / (glitz_gl_clampf_t) 0xffff, + color->green / (glitz_gl_clampf_t) 0xffff, + color->blue / (glitz_gl_clampf_t) 0xffff, + color->alpha / (glitz_gl_clampf_t) 0xffff); + + while (n_rects--) + { + clip = dst->clip; + n_clip = dst->n_clip; + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + + if (dst->box.x1 > box.x1) + box.x1 = dst->box.x1; + if (dst->box.y1 > box.y1) + box.y1 = dst->box.y1; + if (dst->box.x2 < box.x2) + box.x2 = dst->box.x2; + if (dst->box.y2 < box.y2) + box.y2 = dst->box.y2; + + if (rects->x > box.x1) + box.x1 = rects->x; + if (rects->y > box.y1) + box.y1 = rects->y; + if (rects->x + rects->width < box.x2) + box.x2 = rects->x + rects->width; + if (rects->y + rects->height < box.y2) + box.y2 = rects->y + rects->height; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, + box.y2 - box.y1); + + gl->clear (GLITZ_GL_COLOR_BUFFER_BIT); + + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + clip++; + } + rects++; + } + } + else + { + unsigned int pixel = + ((((unsigned int) color->alpha * 0xff) / 0xffff) << 24) | + ((((unsigned int) color->red * 0xff) / 0xffff) << 16) | + ((((unsigned int) color->green * 0xff) / 0xffff) << 8) | + ((((unsigned int) color->blue * 0xff) / 0xffff)); + int x1, y1, x2, y2; + + buffer = _glitz_minimum_buffer (dst, rects, n_rects, &pixel); + if (!buffer) + { + glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); + return; + } + + while (n_rects--) + { + x1 = rects->x; + y1 = rects->y; + x2 = x1 + rects->width; + y2 = y1 + rects->height; + + if (x1 < 0) + x1 = 0; + if (y1 < 0) + y1 = 0; + if (x2 > dst->box.x2) + x2 = dst->box.x2; + if (y2 > dst->box.y2) + y2 = dst->box.y2; + + if (x1 < x2 && y1 < y2) + glitz_set_pixels (dst, + x1, y1, + x2 - x1, y2 - y1, + &pf, buffer); + + rects++; + } + + if (buffer) + glitz_buffer_destroy (buffer); + } + glitz_surface_pop_current (dst); } } slim_hidden_def(glitz_set_rectangles); void glitz_set_rectangle (glitz_surface_t *dst, - const glitz_color_t *color, - int x, - int y, - unsigned int width, - unsigned int height) + const glitz_color_t *color, + int x, + int y, + unsigned int width, + unsigned int height) { glitz_rectangle_t rect; diff --git a/src/glitz_region.c b/src/glitz_region.c index 88e7884..f853ef9 100644 --- a/src/glitz_region.c +++ b/src/glitz_region.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,41 +31,41 @@ #define REGION_ALLOC_CHUNK 16 -#define BOX_SUBSUMS_BOX(b1, b2) \ - ((b2)->x1 >= (b1)->x1 && \ - (b2)->x2 <= (b1)->x2 && \ - (b2)->y1 >= (b1)->y1 && \ - (b2)->y2 <= (b1)->y2) - -#define BOX_INTERSECTS_BOX(b1, b2) \ - ((b1)->x1 < (b2)->x2 && \ - (b1)->x2 > (b2)->x1 && \ - (b1)->y1 < (b2)->y2 && \ - (b1)->y2 > (b2)->y1) - -#define BOX_CLOSE_TO_BOX(b1, b2) \ - ((b1)->x1 < ((b2)->x2 + 1) && \ - (b1)->x2 > ((b2)->x1 - 1) && \ - (b1)->y1 < ((b2)->y2 + 1) && \ - (b1)->y2 > ((b2)->y1 - 1)) - -#define BOX_NEXT_TO_BOX(b1, b2) \ - ((((b1)->x1 == (b2)->x2 || \ - (b1)->x2 == (b2)->x1) && \ - (b1)->y1 == (b2)->y1 && \ - (b1)->y2 == (b2)->y2) || \ - (((b1)->y1 == (b2)->y2 || \ - (b1)->y2 == (b2)->y1) && \ - (b1)->x1 == (b2)->x1 && \ - (b1)->x2 == (b2)->x2)) - -#define MERGE_BOXES(d, b1, b2) \ - { \ - (d)->x1 = MIN ((b1)->x1, (b2)->x1); \ - (d)->y1 = MIN ((b1)->y1, (b2)->y1); \ - (d)->x2 = MAX ((b1)->x2, (b2)->x2); \ - (d)->y2 = MAX ((b1)->y2, (b2)->y2); \ - } +#define BOX_SUBSUMS_BOX(b1, b2) \ + ((b2)->x1 >= (b1)->x1 && \ + (b2)->x2 <= (b1)->x2 && \ + (b2)->y1 >= (b1)->y1 && \ + (b2)->y2 <= (b1)->y2) + +#define BOX_INTERSECTS_BOX(b1, b2) \ + ((b1)->x1 < (b2)->x2 && \ + (b1)->x2 > (b2)->x1 && \ + (b1)->y1 < (b2)->y2 && \ + (b1)->y2 > (b2)->y1) + +#define BOX_CLOSE_TO_BOX(b1, b2) \ + ((b1)->x1 < ((b2)->x2 + 1) && \ + (b1)->x2 > ((b2)->x1 - 1) && \ + (b1)->y1 < ((b2)->y2 + 1) && \ + (b1)->y2 > ((b2)->y1 - 1)) + +#define BOX_NEXT_TO_BOX(b1, b2) \ + ((((b1)->x1 == (b2)->x2 || \ + (b1)->x2 == (b2)->x1) && \ + (b1)->y1 == (b2)->y1 && \ + (b1)->y2 == (b2)->y2) || \ + (((b1)->y1 == (b2)->y2 || \ + (b1)->y2 == (b2)->y1) && \ + (b1)->x1 == (b2)->x1 && \ + (b1)->x2 == (b2)->x2)) + +#define MERGE_BOXES(d, b1, b2) \ + { \ + (d)->x1 = MIN ((b1)->x1, (b2)->x1); \ + (d)->y1 = MIN ((b1)->y1, (b2)->y1); \ + (d)->x2 = MAX ((b1)->x2, (b2)->x2); \ + (d)->y2 = MAX ((b1)->y2, (b2)->y2); \ + } /* * No real union, boxes that intersect are just joined into bigger boxes. @@ -74,93 +74,94 @@ */ glitz_status_t glitz_region_union (glitz_region_t *region, - glitz_box_t *ubox) -{ - if (region->n_box == 0) { - region->extents = *ubox; - region->box = ®ion->extents; - region->n_box = 1; + glitz_box_t *ubox) +{ + if (region->n_box == 0) { + region->extents = *ubox; + region->box = ®ion->extents; + region->n_box = 1; + + return GLITZ_STATUS_SUCCESS; + } - return GLITZ_STATUS_SUCCESS; - } + if (BOX_CLOSE_TO_BOX (ubox, ®ion->extents)) { + glitz_box_t *box, *new_box, *dst_box; + int n_box; + + box = region->box; + n_box = region->n_box; + + while (n_box--) { + if (BOX_SUBSUMS_BOX (box, ubox)) + return GLITZ_STATUS_SUCCESS; + + box++; + } + + box = region->box; + n_box = region->n_box; + + new_box = ubox; + dst_box = NULL; + while (n_box--) { + + if (BOX_INTERSECTS_BOX (box, new_box) || + BOX_NEXT_TO_BOX (box, new_box)) { + + if (dst_box) { + /* + * Remove box from region + */ + region->n_box--; + if (region->n_box == 1) { + MERGE_BOXES (®ion->extents, box, new_box); + region->box = ®ion->extents; + + return GLITZ_STATUS_SUCCESS; + } else { + MERGE_BOXES (dst_box, box, new_box); + if (n_box) + memmove (box, box + 1, + n_box * sizeof (glitz_box_t)); + } + continue; + } else { + dst_box = box; + MERGE_BOXES (dst_box, box, new_box); + new_box = dst_box; + } + } + box++; + } + + if (dst_box) { + if (region->n_box > 1) + MERGE_BOXES (®ion->extents, ®ion->extents, ubox); + + return GLITZ_STATUS_SUCCESS; + } + } - if (BOX_CLOSE_TO_BOX (ubox, ®ion->extents)) { - glitz_box_t *box, *new_box, *dst_box; - int n_box; + /* + * Add box to region + */ + if (region->size < (region->n_box + 1)) { + region->size += REGION_ALLOC_CHUNK; + region->data = (void *) realloc (region->data, + sizeof (glitz_box_t) * region->size); + if (!region->data) + return GLITZ_STATUS_NO_MEMORY; + } - box = region->box; - n_box = region->n_box; + region->box = (glitz_box_t *) region->data; - while (n_box--) { - if (BOX_SUBSUMS_BOX (box, ubox)) - return GLITZ_STATUS_SUCCESS; - - box++; - } - - box = region->box; - n_box = region->n_box; - - new_box = ubox; - dst_box = NULL; - while (n_box--) { - - if (BOX_INTERSECTS_BOX (box, new_box) || - BOX_NEXT_TO_BOX (box, new_box)) { - - if (dst_box) { - /* - * Remove box from region - */ - region->n_box--; - if (region->n_box == 1) { - MERGE_BOXES (®ion->extents, box, new_box); - region->box = ®ion->extents; - - return GLITZ_STATUS_SUCCESS; - } else { - MERGE_BOXES (dst_box, box, new_box); - if (n_box) - memmove (box, box + 1, n_box * sizeof (glitz_box_t)); - } - continue; - } else { - dst_box = box; - MERGE_BOXES (dst_box, box, new_box); - new_box = dst_box; - } - } - box++; - } - - if (dst_box) { - if (region->n_box > 1) - MERGE_BOXES (®ion->extents, ®ion->extents, ubox); - - return GLITZ_STATUS_SUCCESS; - } - } - - /* - * Add box to region - */ - if (region->size < (region->n_box + 1)) { - region->size += REGION_ALLOC_CHUNK; - region->data = (void *) realloc (region->data, - sizeof (glitz_box_t) * region->size); - if (!region->data) - return GLITZ_STATUS_NO_MEMORY; - } - - region->box = (glitz_box_t *) region->data; - - region->box[region->n_box] = *ubox; - if (region->n_box == 1) - region->box[0] = region->extents; - - region->n_box++; - - MERGE_BOXES (®ion->extents, ®ion->extents, ubox); - - return GLITZ_STATUS_SUCCESS; + region->box[region->n_box] = *ubox; + if (region->n_box == 1) + region->box[0] = region->extents; + + region->n_box++; + + MERGE_BOXES (®ion->extents, ®ion->extents, ubox); + + return GLITZ_STATUS_SUCCESS; } diff --git a/src/glitz_status.c b/src/glitz_status.c index 2edcb08..8aa06cc 100644 --- a/src/glitz_status.c +++ b/src/glitz_status.c @@ -34,57 +34,57 @@ unsigned long glitz_status_to_status_mask (glitz_status_t status) { - switch (status) { - case GLITZ_STATUS_NO_MEMORY: - return GLITZ_STATUS_NO_MEMORY_MASK; - case GLITZ_STATUS_BAD_COORDINATE: - return GLITZ_STATUS_BAD_COORDINATE_MASK; - case GLITZ_STATUS_NOT_SUPPORTED: - return GLITZ_STATUS_NOT_SUPPORTED_MASK; - case GLITZ_STATUS_CONTENT_DESTROYED: - return GLITZ_STATUS_CONTENT_DESTROYED_MASK; - case GLITZ_STATUS_SUCCESS: - break; - } - - return 0; + switch (status) { + case GLITZ_STATUS_NO_MEMORY: + return GLITZ_STATUS_NO_MEMORY_MASK; + case GLITZ_STATUS_BAD_COORDINATE: + return GLITZ_STATUS_BAD_COORDINATE_MASK; + case GLITZ_STATUS_NOT_SUPPORTED: + return GLITZ_STATUS_NOT_SUPPORTED_MASK; + case GLITZ_STATUS_CONTENT_DESTROYED: + return GLITZ_STATUS_CONTENT_DESTROYED_MASK; + case GLITZ_STATUS_SUCCESS: + break; + } + + return 0; } glitz_status_t glitz_status_pop_from_mask (unsigned long *mask) { - if (*mask & GLITZ_STATUS_NO_MEMORY_MASK) { - *mask &= ~GLITZ_STATUS_NO_MEMORY_MASK; - return GLITZ_STATUS_NO_MEMORY; - } else if (*mask & GLITZ_STATUS_BAD_COORDINATE_MASK) { - *mask &= ~GLITZ_STATUS_BAD_COORDINATE_MASK; - return GLITZ_STATUS_BAD_COORDINATE; - } else if (*mask & GLITZ_STATUS_NOT_SUPPORTED_MASK) { - *mask &= ~GLITZ_STATUS_NOT_SUPPORTED_MASK; - return GLITZ_STATUS_NOT_SUPPORTED; - } else if (*mask & GLITZ_STATUS_CONTENT_DESTROYED_MASK) { - *mask &= ~GLITZ_STATUS_CONTENT_DESTROYED_MASK; - return GLITZ_STATUS_CONTENT_DESTROYED; - } - - return GLITZ_STATUS_SUCCESS; + if (*mask & GLITZ_STATUS_NO_MEMORY_MASK) { + *mask &= ~GLITZ_STATUS_NO_MEMORY_MASK; + return GLITZ_STATUS_NO_MEMORY; + } else if (*mask & GLITZ_STATUS_BAD_COORDINATE_MASK) { + *mask &= ~GLITZ_STATUS_BAD_COORDINATE_MASK; + return GLITZ_STATUS_BAD_COORDINATE; + } else if (*mask & GLITZ_STATUS_NOT_SUPPORTED_MASK) { + *mask &= ~GLITZ_STATUS_NOT_SUPPORTED_MASK; + return GLITZ_STATUS_NOT_SUPPORTED; + } else if (*mask & GLITZ_STATUS_CONTENT_DESTROYED_MASK) { + *mask &= ~GLITZ_STATUS_CONTENT_DESTROYED_MASK; + return GLITZ_STATUS_CONTENT_DESTROYED; + } + + return GLITZ_STATUS_SUCCESS; } const char * glitz_status_string (glitz_status_t status) { - switch (status) { - case GLITZ_STATUS_SUCCESS: - return "success"; - case GLITZ_STATUS_NO_MEMORY: - return "out of memory"; - case GLITZ_STATUS_BAD_COORDINATE: - return "bad coordinate"; - case GLITZ_STATUS_NOT_SUPPORTED: - return "not supported"; - case GLITZ_STATUS_CONTENT_DESTROYED: - return "content destroyed"; - } + switch (status) { + case GLITZ_STATUS_SUCCESS: + return "success"; + case GLITZ_STATUS_NO_MEMORY: + return "out of memory"; + case GLITZ_STATUS_BAD_COORDINATE: + return "bad coordinate"; + case GLITZ_STATUS_NOT_SUPPORTED: + return "not supported"; + case GLITZ_STATUS_CONTENT_DESTROYED: + return "content destroyed"; + } - return "<unknown error status>"; + return "<unknown error status>"; } diff --git a/src/glitz_surface.c b/src/glitz_surface.c index eff07ba..23d30bb 100644 --- a/src/glitz_surface.c +++ b/src/glitz_surface.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -34,39 +34,39 @@ glitz_surface_t * glitz_surface_create (glitz_drawable_t *drawable, - glitz_format_t *format, - unsigned int width, - unsigned int height, - unsigned long mask, - glitz_surface_attributes_t *attributes) + glitz_format_t *format, + unsigned int width, + unsigned int height, + unsigned long mask, + glitz_surface_attributes_t *attributes) { glitz_surface_t *surface; glitz_bool_t unnormalized = 0; unsigned long feature_mask = drawable->backend->feature_mask; if (!width || !height) - return NULL; + return NULL; if (mask & GLITZ_SURFACE_UNNORMALIZED_MASK) { - if (attributes->unnormalized) - { - if (!(feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK)) - return NULL; + if (attributes->unnormalized) + { + if (!(feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK)) + return NULL; - unnormalized = 1; - } + unnormalized = 1; + } } surface = (glitz_surface_t *) calloc (1, sizeof (glitz_surface_t)); if (surface == NULL) - return NULL; + return NULL; surface->drawable = drawable; glitz_drawable_reference (drawable); - + surface->ref_count = 1; - surface->filter = GLITZ_FILTER_NEAREST; + surface->filter = GLITZ_FILTER_NEAREST; surface->format = format; surface->box.x2 = (short) width; surface->box.y2 = (short) height; @@ -76,250 +76,256 @@ glitz_surface_create (glitz_drawable_t *drawable, if (width == 1 && height == 1) { - surface->flags |= GLITZ_SURFACE_FLAG_SOLID_MASK; - surface->solid.alpha = 0xffff; - - REGION_INIT (&surface->texture_damage, &surface->box); - REGION_INIT (&surface->drawable_damage, &surface->box); + surface->flags |= GLITZ_SURFACE_FLAG_SOLID_MASK; + surface->solid.alpha = 0xffff; + + REGION_INIT (&surface->texture_damage, &surface->box); + REGION_INIT (&surface->drawable_damage, &surface->box); } else { - REGION_INIT (&surface->texture_damage, NULL_BOX); - REGION_INIT (&surface->drawable_damage, NULL_BOX); + REGION_INIT (&surface->texture_damage, NULL_BOX); + REGION_INIT (&surface->drawable_damage, NULL_BOX); } - + glitz_texture_init (&surface->texture, width, height, - drawable->backend->texture_formats[format->id], - feature_mask, unnormalized); + drawable->backend->texture_formats[format->id], + feature_mask, unnormalized); - glitz_framebuffer_init (&surface->framebuffer); - if (width > 64 || height > 64) { - glitz_surface_push_current (surface, GLITZ_CONTEXT_CURRENT); - glitz_texture_size_check (&drawable->backend->gl, &surface->texture, - drawable->backend->max_texture_2d_size, - drawable->backend->max_texture_rect_size); - glitz_surface_pop_current (surface); - - if (TEXTURE_INVALID_SIZE (&surface->texture)) - { - glitz_surface_destroy (surface); - return NULL; - } + glitz_surface_push_current (surface, GLITZ_CONTEXT_CURRENT); + glitz_texture_size_check (drawable->backend->gl, &surface->texture, + drawable->backend->max_texture_2d_size, + drawable->backend->max_texture_rect_size); + glitz_surface_pop_current (surface); + + if (TEXTURE_INVALID_SIZE (&surface->texture)) + { + glitz_surface_destroy (surface); + return NULL; + } } - + return surface; } void glitz_surface_destroy (glitz_surface_t *surface) { - if (!surface) - return; - - surface->ref_count--; - if (surface->ref_count) - return; - - if (surface->texture.name) { - glitz_surface_push_current (surface, GLITZ_ANY_CONTEXT_CURRENT); - - glitz_framebuffer_fini (&surface->drawable->backend->gl, - &surface->framebuffer); - glitz_texture_fini (&surface->drawable->backend->gl, &surface->texture); - - glitz_surface_pop_current (surface); - } - - REGION_UNINIT (&surface->texture_damage); - REGION_UNINIT (&surface->drawable_damage); - - if (surface->geometry.buffer) - glitz_buffer_destroy (surface->geometry.buffer); - - if (surface->geometry.array) - glitz_multi_array_destroy (surface->geometry.array); - - if (surface->transform) - free (surface->transform); - - if (surface->filter_params) - free (surface->filter_params); - - if (surface->attached) - glitz_drawable_destroy (surface->attached); - - glitz_drawable_destroy (surface->drawable); + if (!surface) + return; + + surface->ref_count--; + if (surface->ref_count) + return; + + if (surface->attached) + { + surface->attached->backend->detach_notify (surface->attached, surface); + if (surface->attached->front == surface) + surface->attached->front = NULL; + else if (surface->attached->back == surface) + surface->attached->back = NULL; + + glitz_drawable_destroy (surface->attached); + surface->attached = NULL; + } + + if (surface->texture.name) { + glitz_surface_push_current (surface, GLITZ_ANY_CONTEXT_CURRENT); + glitz_texture_fini (surface->drawable->backend->gl, &surface->texture); + glitz_surface_pop_current (surface); + } - free (surface); + REGION_UNINIT (&surface->texture_damage); + REGION_UNINIT (&surface->drawable_damage); + + if (surface->geometry.buffer) + glitz_buffer_destroy (surface->geometry.buffer); + + if (surface->geometry.array) + glitz_multi_array_destroy (surface->geometry.array); + + if (surface->transform) + free (surface->transform); + + if (surface->filter_params) + free (surface->filter_params); + + glitz_drawable_destroy (surface->drawable); + + free (surface); } void glitz_surface_reference (glitz_surface_t *surface) { - if (surface == NULL) - return; + if (surface == NULL) + return; - surface->ref_count++; + surface->ref_count++; } -static void +void _glitz_surface_sync_texture (glitz_surface_t *surface) { if (REGION_NOTEMPTY (&surface->texture_damage)) { - glitz_box_t *box; - int n_box; - - GLITZ_GL_SURFACE (surface); - - if (!(TEXTURE_ALLOCATED (&surface->texture))) - glitz_texture_allocate (gl, &surface->texture); - - if (SURFACE_SOLID (surface) && (!SURFACE_SOLID_DAMAGE (surface))) - { - glitz_gl_float_t color[4]; - - if (TEXTURE_ALLOCATED (&surface->texture)) - { - color[0] = surface->solid.red / 65535.0f; - color[1] = surface->solid.green / 65535.0f; - color[2] = surface->solid.blue / 65535.0f; - color[3] = surface->solid.alpha / 65535.0f; - - glitz_texture_bind (gl, &surface->texture); - gl->tex_sub_image_2d (surface->texture.target, 0, - surface->texture.box.x1, - surface->texture.box.y1, - 1, 1, GLITZ_GL_RGBA, - GLITZ_GL_FLOAT, color); - glitz_texture_unbind (gl, &surface->texture); - } - REGION_EMPTY (&surface->texture_damage); - return; - } - - glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); - - gl->read_buffer (surface->buffer); - - gl->disable (GLITZ_GL_SCISSOR_TEST); - - glitz_texture_bind (gl, &surface->texture); - - box = REGION_RECTS (&surface->texture_damage); - n_box = REGION_NUM_RECTS (&surface->texture_damage); - - while (n_box--) - { - glitz_texture_copy_drawable (gl, - &surface->texture, - surface->attached, - box->x1 + surface->x, - box->y1 + surface->y, - box->x2 - box->x1, - box->y2 - box->y1, - box->x1, - box->y1); - - box++; - } - - REGION_EMPTY (&surface->texture_damage); - - glitz_texture_unbind (gl, &surface->texture); - - gl->enable (GLITZ_GL_SCISSOR_TEST); - - glitz_surface_pop_current (surface); + glitz_box_t *box; + int n_box; + + GLITZ_GL_SURFACE (surface); + + if (!(TEXTURE_ALLOCATED (&surface->texture))) + glitz_texture_allocate (gl, &surface->texture); + + if (SURFACE_SOLID (surface) && (!SURFACE_SOLID_DAMAGE (surface))) + { + glitz_gl_float_t color[4]; + + if (TEXTURE_ALLOCATED (&surface->texture)) + { + color[0] = surface->solid.red / 65535.0f; + color[1] = surface->solid.green / 65535.0f; + color[2] = surface->solid.blue / 65535.0f; + color[3] = surface->solid.alpha / 65535.0f; + + glitz_texture_bind (gl, &surface->texture); + gl->tex_sub_image_2d (surface->texture.target, 0, + surface->texture.box.x1, + surface->texture.box.y1, + 1, 1, GLITZ_GL_RGBA, + GLITZ_GL_FLOAT, color); + glitz_texture_unbind (gl, &surface->texture); + } + REGION_EMPTY (&surface->texture_damage); + return; + } + + glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); + + gl->read_buffer (surface->buffer); + + gl->disable (GLITZ_GL_SCISSOR_TEST); + + glitz_texture_bind (gl, &surface->texture); + + box = REGION_RECTS (&surface->texture_damage); + n_box = REGION_NUM_RECTS (&surface->texture_damage); + + while (n_box--) + { + glitz_texture_copy_drawable (gl, + &surface->texture, + surface->attached, + box->x1 + surface->x, + box->y1 + surface->y, + box->x2 - box->x1, + box->y2 - box->y1, + box->x1, + box->y1); + + box++; + } + + REGION_EMPTY (&surface->texture_damage); + + glitz_texture_unbind (gl, &surface->texture); + + gl->enable (GLITZ_GL_SCISSOR_TEST); + + glitz_surface_pop_current (surface); } } void glitz_surface_sync_drawable (glitz_surface_t *surface) -{ +{ if (REGION_NOTEMPTY (&surface->drawable_damage)) { - glitz_texture_t *texture; - glitz_box_t *box, *ext; - int n_box; - - GLITZ_GL_SURFACE (surface); - - texture = glitz_surface_get_texture (surface, 0); - if (!texture) - return; - - box = REGION_RECTS (&surface->drawable_damage); - ext = REGION_EXTENTS (&surface->drawable_damage); - n_box = REGION_NUM_RECTS (&surface->drawable_damage); - - glitz_texture_bind (gl, texture); - - glitz_texture_set_tex_gen (gl, texture, NULL, - 0, 0, - GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK, - NULL); - - gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); - gl->color_4us (0x0, 0x0, 0x0, 0xffff); - - glitz_texture_ensure_wrap (gl, texture, GLITZ_GL_CLAMP_TO_EDGE); - glitz_texture_ensure_filter (gl, texture, GLITZ_GL_NEAREST); - - glitz_set_operator (gl, GLITZ_OPERATOR_SRC); - - gl->scissor (surface->x + ext->x1, - surface->attached->height - surface->y - ext->y2, - ext->x2 - ext->x1, - ext->y2 - ext->y1); - - if (n_box > 1) - { - glitz_float_t *data; - void *ptr; - int vertices; - - ptr = malloc (n_box * 8 * sizeof (glitz_float_t)); - if (!ptr) { - glitz_surface_status_add (surface, - GLITZ_STATUS_NO_MEMORY_MASK); - return; - } - - data = (glitz_float_t *) ptr; - vertices = n_box << 2; - - while (n_box--) - { - *data++ = (glitz_float_t) box->x1; - *data++ = (glitz_float_t) box->y1; - *data++ = (glitz_float_t) box->x2; - *data++ = (glitz_float_t) box->y1; - *data++ = (glitz_float_t) box->x2; - *data++ = (glitz_float_t) box->y2; - *data++ = (glitz_float_t) box->x1; - *data++ = (glitz_float_t) box->y2; - - box++; - } - - gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr); - gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices); - - free (ptr); - } - else - { - glitz_geometry_enable_none (gl, surface, ext); - gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); - } - - glitz_texture_unbind (gl, texture); - - REGION_EMPTY (&surface->drawable_damage); + glitz_texture_t *texture; + glitz_texture_parameters_t param; + glitz_box_t *box, *ext; + int n_box; + + GLITZ_GL_SURFACE (surface); + + texture = glitz_surface_get_texture (surface, 0); + if (!texture) + return; + + box = REGION_RECTS (&surface->drawable_damage); + ext = REGION_EXTENTS (&surface->drawable_damage); + n_box = REGION_NUM_RECTS (&surface->drawable_damage); + + glitz_texture_bind (gl, texture); + + glitz_texture_set_tex_gen (gl, texture, NULL, + 0, 0, + GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK, + NULL); + + gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_REPLACE); + gl->color_4us (0x0, 0x0, 0x0, 0xffff); + + param.filter[0] = param.filter[1] = GLITZ_GL_CLAMP_TO_EDGE; + param.wrap[0] = param.wrap[1] = GLITZ_GL_NEAREST; + + glitz_texture_ensure_parameters (gl, texture, ¶m); + + glitz_set_operator (gl, GLITZ_OPERATOR_SRC); + + gl->scissor (surface->x + ext->x1, + surface->attached->height - surface->y - ext->y2, + ext->x2 - ext->x1, + ext->y2 - ext->y1); + + if (n_box > 1) + { + glitz_float_t *data; + void *ptr; + int vertices; + + ptr = malloc (n_box * 8 * sizeof (glitz_float_t)); + if (!ptr) { + glitz_surface_status_add (surface, + GLITZ_STATUS_NO_MEMORY_MASK); + return; + } + + data = (glitz_float_t *) ptr; + vertices = n_box << 2; + + while (n_box--) + { + *data++ = (glitz_float_t) box->x1; + *data++ = (glitz_float_t) box->y1; + *data++ = (glitz_float_t) box->x2; + *data++ = (glitz_float_t) box->y1; + *data++ = (glitz_float_t) box->x2; + *data++ = (glitz_float_t) box->y2; + *data++ = (glitz_float_t) box->x1; + *data++ = (glitz_float_t) box->y2; + + box++; + } + + gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr); + gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices); + + free (ptr); + } + else + { + glitz_geometry_enable_none (gl, surface, ext); + gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); + } + + glitz_texture_unbind (gl, texture); + + REGION_EMPTY (&surface->drawable_damage); } } @@ -328,93 +334,96 @@ glitz_surface_sync_solid (glitz_surface_t *surface) { if (SURFACE_SOLID_DAMAGE (surface)) { - glitz_gl_float_t *c, color[64]; - glitz_texture_t *texture; - - GLITZ_GL_SURFACE (surface); - - texture = glitz_surface_get_texture (surface, 0); - - c = &color[(texture->box.y1 * texture->width + texture->box.x1) * 4]; - if (texture) - { - glitz_texture_bind (gl, texture); - gl->get_tex_image (texture->target, 0, - GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color); - glitz_texture_unbind (gl, texture); - } - else - { - c[0] = c[1] = c[2] = 0.0f; - c[3] = 1.0f; - } - - surface->solid.red = c[0] * 65535.0f; - surface->solid.green = c[1] * 65535.0f; - surface->solid.blue = c[2] * 65535.0f; - surface->solid.alpha = c[3] * 65535.0f; - - surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; + glitz_gl_float_t *c, color[64]; + glitz_texture_t *texture; + + GLITZ_GL_SURFACE (surface); + + texture = glitz_surface_get_texture (surface, 0); + + c = &color[(texture->box.y1 * texture->width + texture->box.x1) * 4]; + if (texture) + { + glitz_texture_bind (gl, texture); + gl->get_tex_image (texture->target, 0, + GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color); + glitz_texture_unbind (gl, texture); + } + else + { + c[0] = c[1] = c[2] = 0.0f; + c[3] = 1.0f; + } + + surface->solid.red = c[0] * 65535.0f; + surface->solid.green = c[1] * 65535.0f; + surface->solid.blue = c[2] * 65535.0f; + surface->solid.alpha = c[3] * 65535.0f; + + surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; } } glitz_texture_t * glitz_surface_get_texture (glitz_surface_t *surface, - glitz_bool_t allocate) + glitz_bool_t allocate) { GLITZ_GL_SURFACE (surface); if (REGION_NOTEMPTY (&surface->texture_damage)) { - _glitz_surface_sync_texture (surface); + _glitz_surface_sync_texture (surface); } else if (allocate) { - if (!(TEXTURE_ALLOCATED (&surface->texture))) - glitz_texture_allocate (gl, &surface->texture); + if (!(TEXTURE_ALLOCATED (&surface->texture))) + glitz_texture_allocate (gl, &surface->texture); } - + if (TEXTURE_ALLOCATED (&surface->texture)) - return &surface->texture; - + return &surface->texture; + return NULL; } void glitz_surface_damage (glitz_surface_t *surface, - glitz_box_t *box, - int what) + glitz_box_t *box, + int what) { - if (box) - { - if (what & GLITZ_DAMAGE_DRAWABLE_MASK) - REGION_UNION (&surface->drawable_damage, box); - - if (surface->attached && (what & GLITZ_DAMAGE_TEXTURE_MASK)) - REGION_UNION (&surface->texture_damage, box); - } - else + if (surface->attached && !DRAWABLE_IS_FBO (surface->attached)) { - if (what & GLITZ_DAMAGE_DRAWABLE_MASK) - { - REGION_EMPTY (&surface->drawable_damage); - REGION_INIT (&surface->drawable_damage, &surface->box); - } - - if (surface->attached && (what & GLITZ_DAMAGE_TEXTURE_MASK)) - { - REGION_EMPTY (&surface->texture_damage); - REGION_INIT (&surface->texture_damage, &surface->box); - } + if (box) + { + if (what & GLITZ_DAMAGE_DRAWABLE_MASK) + REGION_UNION (&surface->drawable_damage, box); + + if (surface->attached && (what & GLITZ_DAMAGE_TEXTURE_MASK)) + REGION_UNION (&surface->texture_damage, box); + } + else + { + if (what & GLITZ_DAMAGE_DRAWABLE_MASK) + { + REGION_EMPTY (&surface->drawable_damage); + REGION_INIT (&surface->drawable_damage, &surface->box); + } + + if (surface->attached && (what & GLITZ_DAMAGE_TEXTURE_MASK)) + { + REGION_EMPTY (&surface->texture_damage); + REGION_INIT (&surface->texture_damage, &surface->box); + } + } } - + if (what & GLITZ_DAMAGE_SOLID_MASK) - surface->flags |= GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; + surface->flags |= GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; } void glitz_surface_status_add (glitz_surface_t *surface, - int flags) + int flags) { surface->status_mask |= flags; } @@ -424,108 +433,142 @@ _glitz_surface_update_state (glitz_surface_t *surface) { glitz_drawable_t *drawable; int width, height; - + GLITZ_GL_SURFACE (surface); - if (surface->attached) - { - drawable = surface->attached; - width = drawable->width; - height = drawable->height; - } - else - { - drawable = surface->drawable; - width = surface->texture.width; - height = surface->texture.height; - } - + drawable = surface->attached; + width = drawable->width; + height = drawable->height; + if (drawable->update_all || - drawable->viewport.x != surface->x || - drawable->viewport.y != surface->y || - drawable->viewport.width != surface->box.x2 || - drawable->viewport.height != surface->box.y2) + drawable->viewport.x != surface->x || + drawable->viewport.y != surface->y || + drawable->viewport.width != surface->box.x2 || + drawable->viewport.height != surface->box.y2) { - gl->viewport (surface->x, - height - surface->y - surface->box.y2, - surface->box.x2, - surface->box.y2); - gl->matrix_mode (GLITZ_GL_PROJECTION); - gl->load_identity (); - gl->ortho (0.0, - surface->box.x2, - height - surface->box.y2, - height, - -1.0, 1.0); - gl->matrix_mode (GLITZ_GL_MODELVIEW); - gl->load_identity (); - gl->scale_f (1.0f, -1.0f, 1.0f); - gl->translate_f (0.0f, -height, 0.0f); - - drawable->viewport.x = surface->x; - drawable->viewport.y = surface->y; - drawable->viewport.width = surface->box.x2; - drawable->viewport.height = surface->box.y2; - - drawable->update_all = 0; + gl->viewport (surface->x, + height - surface->y - surface->box.y2, + surface->box.x2, + surface->box.y2); + gl->matrix_mode (GLITZ_GL_PROJECTION); + gl->load_identity (); + gl->ortho (0.0, + surface->box.x2, + height - surface->box.y2, + height, + -1.0, 1.0); + gl->matrix_mode (GLITZ_GL_MODELVIEW); + gl->load_identity (); + gl->scale_f (1.0f, -1.0f, 1.0f); + gl->translate_f (0.0f, -height, 0.0f); + + drawable->viewport.x = surface->x; + drawable->viewport.y = surface->y; + drawable->viewport.width = surface->box.x2; + drawable->viewport.height = surface->box.y2; + + drawable->update_all = 0; } - + gl->draw_buffer (surface->buffer); if (SURFACE_DITHER (surface)) - gl->enable (GLITZ_GL_DITHER); + gl->enable (GLITZ_GL_DITHER); else - gl->disable (GLITZ_GL_DITHER); + gl->disable (GLITZ_GL_DITHER); } void glitz_surface_attach (glitz_surface_t *surface, - glitz_drawable_t *drawable, - glitz_drawable_buffer_t buffer, - int x, - int y) + glitz_drawable_t *drawable, + glitz_drawable_buffer_t buffer) { - glitz_drawable_reference (drawable); + if (drawable) + { + if (buffer == GLITZ_DRAWABLE_BUFFER_FRONT_COLOR) + { + if (surface == drawable->front) + return; + + if (surface->format->type != GLITZ_FORMAT_TYPE_COLOR) + drawable = NULL; + + if (drawable) + { + glitz_drawable_reference (drawable); + if (drawable->front) + glitz_surface_detach (drawable->front); + + drawable->front = surface; + } + + surface->buffer = GLITZ_GL_FRONT; + } + else if ((buffer == GLITZ_DRAWABLE_BUFFER_BACK_COLOR) && + drawable->format->d.doublebuffer) + { + if (surface == drawable->back) + return; + + if (surface->format->type != GLITZ_FORMAT_TYPE_COLOR) + drawable = NULL; + + if (drawable) + { + glitz_drawable_reference (drawable); + if (drawable->back) + glitz_surface_detach (drawable->back); + + drawable->back = surface; + } + + surface->buffer = GLITZ_GL_BACK; + } + else + drawable = NULL; + } if (surface->attached) - glitz_drawable_destroy (surface->attached); - + glitz_surface_detach (surface); + surface->attached = drawable; - surface->x = x; - surface->y = y; - - switch (buffer) { - case GLITZ_DRAWABLE_BUFFER_FRONT_COLOR: - surface->buffer = GLITZ_GL_FRONT; - break; - case GLITZ_DRAWABLE_BUFFER_BACK_COLOR: - surface->buffer = GLITZ_GL_BACK; - break; - } + if (drawable) + { + surface->attached->backend->attach_notify (drawable, surface); + + if (TEXTURE_ALLOCATED (&surface->texture)) + glitz_surface_damage (surface, NULL, GLITZ_DAMAGE_DRAWABLE_MASK); - if ((!SURFACE_SOLID (surface)) || SURFACE_SOLID_DAMAGE (surface)) - REGION_EMPTY (&surface->texture_damage); + if ((!SURFACE_SOLID (surface)) || SURFACE_SOLID_DAMAGE (surface)) + REGION_EMPTY (&surface->texture_damage); + } } void glitz_surface_detach (glitz_surface_t *surface) { if (!surface->attached) - return; + return; if (REGION_NOTEMPTY (&surface->texture_damage)) { - glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); - _glitz_surface_sync_texture (surface); - glitz_surface_pop_current (surface); + glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); + _glitz_surface_sync_texture (surface); + glitz_surface_pop_current (surface); } - - glitz_drawable_destroy (surface->attached); + + surface->attached->backend->detach_notify (surface->attached, surface); + + if (surface == surface->attached->front) + surface->attached->front = NULL; + + if (surface == surface->attached->back) + surface->attached->back = NULL; + + glitz_drawable_destroy (surface->attached); + surface->attached = NULL; - surface->buffer = GLITZ_GL_FRONT; - surface->x = 0; - surface->y = 0; - + REGION_EMPTY (&surface->drawable_damage); REGION_INIT (&surface->drawable_damage, &surface->box); } @@ -546,382 +589,391 @@ slim_hidden_def(glitz_surface_get_attached_drawable); glitz_bool_t glitz_surface_push_current (glitz_surface_t *surface, - glitz_constraint_t constraint) + glitz_constraint_t constraint) { - if (surface->attached) - { - surface->attached->backend->push_current (surface->attached, - surface, - constraint); - if (constraint == GLITZ_DRAWABLE_CURRENT) - { - if (surface->attached->backend->feature_mask & - GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) - glitz_framebuffer_unbind (&surface->attached->backend->gl); - - _glitz_surface_update_state (surface); - glitz_surface_sync_drawable (surface); - } - } - else - { - surface->drawable->backend->push_current (surface->drawable, - surface, - constraint); - if (constraint == GLITZ_DRAWABLE_CURRENT) - { - if (surface->drawable->backend->feature_mask & - GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) - { - if (glitz_framebuffer_complete (&surface->drawable->backend->gl, - &surface->framebuffer, - &surface->texture)) - { - _glitz_surface_update_state (surface); - return 1; - } - } - - return 0; - } - } - - return 1; + glitz_drawable_t *drawable; + + if (surface->attached) + { + drawable = surface->attached; + if (drawable->backend->push_current (drawable, surface, + constraint)) + { + if (constraint == GLITZ_DRAWABLE_CURRENT) + { + if (drawable->backend->feature_mask & + GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) + { + if (!surface->fb) + { + GLITZ_GL_DRAWABLE (drawable); + + gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, 0); + + _glitz_surface_update_state (surface); + glitz_surface_sync_drawable (surface); + } + else + { + _glitz_surface_update_state (surface); + } + } + else + { + _glitz_surface_update_state (surface); + glitz_surface_sync_drawable (surface); + } + } + + return 1; + } + + return 0; + } + else + { + drawable = surface->drawable; + + if (constraint == GLITZ_DRAWABLE_CURRENT) + { + drawable->backend->push_current (drawable, surface, + GLITZ_ANY_CONTEXT_CURRENT); + } + else + { + return drawable->backend->push_current (drawable, surface, + constraint); + } + } + + return 0; } void glitz_surface_pop_current (glitz_surface_t *surface) { - glitz_surface_t *other; - - if (surface->attached) { - other = surface->attached->backend->pop_current (surface->attached); - } else { - if (surface->framebuffer.name) - glitz_framebuffer_unbind (&surface->drawable->backend->gl); - - other = surface->drawable->backend->pop_current (surface->drawable); - } - - if (other) { - if ((!other->attached) && - (other->drawable->backend->feature_mask & - GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK)) + glitz_drawable_t *drawable; + glitz_surface_t *other; + + drawable = (surface->attached) ? surface->attached : surface->drawable; + + other = drawable->backend->pop_current (drawable); + if (other) { - glitz_framebuffer_complete (&other->drawable->backend->gl, - &other->framebuffer, - &other->texture); + if (other->fb) + drawable->backend->gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, + other->fb); + + _glitz_surface_update_state (other); } - _glitz_surface_update_state (other); - } } void glitz_surface_set_transform (glitz_surface_t *surface, - glitz_transform_t *transform) + glitz_transform_t *transform) { - static glitz_transform_t identity = { - { - { FIXED1, 0x00000, 0x00000 }, - { 0x00000, FIXED1, 0x00000 }, - { 0x00000, 0x00000, FIXED1 } - } - }; - - if (transform && - memcmp (transform, &identity, sizeof (glitz_transform_t)) == 0) - transform = NULL; - - if (transform) { - glitz_gl_float_t height, *m, *t; - - if (!surface->transform) { - surface->transform = malloc (sizeof (glitz_matrix_t)); - if (surface->transform == NULL) { - glitz_surface_status_add (surface, GLITZ_STATUS_NO_MEMORY_MASK); - return; - } + static glitz_transform_t identity = { + { + { FIXED1, 0x00000, 0x00000 }, + { 0x00000, FIXED1, 0x00000 }, + { 0x00000, 0x00000, FIXED1 } + } + }; + + if (transform && + memcmp (transform, &identity, sizeof (glitz_transform_t)) == 0) + transform = NULL; + + if (transform) { + glitz_gl_float_t height, *m, *t; + + if (!surface->transform) { + surface->transform = malloc (sizeof (glitz_matrix_t)); + if (surface->transform == NULL) { + glitz_surface_status_add (surface, + GLITZ_STATUS_NO_MEMORY_MASK); + return; + } + } + + m = surface->transform->m; + t = surface->transform->t; + + m[0] = FIXED_TO_FLOAT (transform->matrix[0][0]); + m[4] = FIXED_TO_FLOAT (transform->matrix[0][1]); + m[8] = 0.0f; + m[12] = FIXED_TO_FLOAT (transform->matrix[0][2]); + + m[1] = FIXED_TO_FLOAT (transform->matrix[1][0]); + m[5] = FIXED_TO_FLOAT (transform->matrix[1][1]); + m[9] = 0.0f; + m[13] = FIXED_TO_FLOAT (transform->matrix[1][2]); + + m[2] = 0.0f; + m[6] = 0.0f; + m[10] = 1.0f; + m[14] = 0.0f; + + m[3] = FIXED_TO_FLOAT (transform->matrix[2][0]); + m[7] = FIXED_TO_FLOAT (transform->matrix[2][1]); + m[11] = 0.0f; + m[15] = FIXED_TO_FLOAT (transform->matrix[2][2]); + + /* Projective transformation matrix conversion to normalized + texture coordinates seems to be working fine. However, it would be + good if someone could verify that this is actually a correct way for + doing this. + + We need to do this: + + scale (IDENTITY, 0, -1) + translate (IDENTITY, 0, -texture_height) + multiply (TEXTURE_MATRIX, IDENTITY, MATRIX) + scale (TEXTURE_MATRIX, 0, -1) + translate (TEXTURE_MATRIX, 0, -texture_height) + + the following code does it pretty efficiently. */ + + height = surface->texture.texcoord_height_unit * + (surface->texture.box.y2 - surface->texture.box.y1); + + t[0] = m[0]; + t[4] = m[4]; + t[8] = 0.0f; + t[12] = surface->texture.texcoord_width_unit * m[12]; + + t[3] = m[3] / surface->texture.texcoord_width_unit; + t[7] = m[7] / surface->texture.texcoord_height_unit; + t[11] = 0.0f; + t[15] = m[15]; + + t[1] = height * t[3] - m[1]; + t[5] = height * t[7] - m[5]; + t[9] = 0.0f; + t[13] = height * t[15] - surface->texture.texcoord_height_unit * m[13]; + + t[2] = 0.0f; + t[6] = 0.0f; + t[10] = 1.0f; + t[14] = 0.0f; + + /* scale y = -1 */ + t[4] = -t[4]; + t[5] = -t[5]; + t[7] = -t[7]; + + /* translate y = -texture_height */ + t[12] -= t[4] * height; + t[13] -= t[5] * height; + t[15] -= t[7] * height; + + /* Translate coordinates into texture. This only makes a difference + when GL_ARB_texture_border_clamp is missing as box.x1 and box.y1 are + otherwise always zero. This breaks projective transformations so + those wont work without GL_ARB_texture_border_clamp. */ + t[12] += surface->texture.texcoord_width_unit * + surface->texture.box.x1; + t[13] += surface->texture.texcoord_height_unit * + surface->texture.box.y1; + + surface->flags |= GLITZ_SURFACE_FLAG_TRANSFORM_MASK; + if (m[3] != 0.0f || m[7] != 0.0f || (m[15] != 1.0f && m[15] != -1.0f)) + surface->flags |= GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK; + } else { + if (surface->transform) + free (surface->transform); + + surface->transform = NULL; + surface->flags &= ~GLITZ_SURFACE_FLAG_TRANSFORM_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK; } - - m = surface->transform->m; - t = surface->transform->t; - - m[0] = FIXED_TO_FLOAT (transform->matrix[0][0]); - m[4] = FIXED_TO_FLOAT (transform->matrix[0][1]); - m[8] = 0.0f; - m[12] = FIXED_TO_FLOAT (transform->matrix[0][2]); - - m[1] = FIXED_TO_FLOAT (transform->matrix[1][0]); - m[5] = FIXED_TO_FLOAT (transform->matrix[1][1]); - m[9] = 0.0f; - m[13] = FIXED_TO_FLOAT (transform->matrix[1][2]); - - m[2] = 0.0f; - m[6] = 0.0f; - m[10] = 1.0f; - m[14] = 0.0f; - - m[3] = FIXED_TO_FLOAT (transform->matrix[2][0]); - m[7] = FIXED_TO_FLOAT (transform->matrix[2][1]); - m[11] = 0.0f; - m[15] = FIXED_TO_FLOAT (transform->matrix[2][2]); - - /* Projective transformation matrix conversion to normalized - texture coordinates seems to be working fine. However, it would be - good if someone could verify that this is actually a correct way for - doing this. - - We need to do this: - - scale (IDENTITY, 0, -1) - translate (IDENTITY, 0, -texture_height) - multiply (TEXTURE_MATRIX, IDENTITY, MATRIX) - scale (TEXTURE_MATRIX, 0, -1) - translate (TEXTURE_MATRIX, 0, -texture_height) - - the following code does it pretty efficiently. */ - - height = surface->texture.texcoord_height_unit * - (surface->texture.box.y2 - surface->texture.box.y1); - - t[0] = m[0]; - t[4] = m[4]; - t[8] = 0.0f; - t[12] = surface->texture.texcoord_width_unit * m[12]; - - t[3] = m[3] / surface->texture.texcoord_width_unit; - t[7] = m[7] / surface->texture.texcoord_height_unit; - t[11] = 0.0f; - t[15] = m[15]; - - t[1] = height * t[3] - m[1]; - t[5] = height * t[7] - m[5]; - t[9] = 0.0f; - t[13] = height * t[15] - surface->texture.texcoord_height_unit * m[13]; - - t[2] = 0.0f; - t[6] = 0.0f; - t[10] = 1.0f; - t[14] = 0.0f; - - /* scale y = -1 */ - t[4] = -t[4]; - t[5] = -t[5]; - t[7] = -t[7]; - - /* translate y = -texture_height */ - t[12] -= t[4] * height; - t[13] -= t[5] * height; - t[15] -= t[7] * height; - - /* Translate coordinates into texture. This only makes a difference when - GL_ARB_texture_border_clamp is missing as box.x1 and box.y1 are - otherwise always zero. This breaks projective transformations so - those wont work without GL_ARB_texture_border_clamp. */ - t[12] += surface->texture.texcoord_width_unit * surface->texture.box.x1; - t[13] += surface->texture.texcoord_height_unit * surface->texture.box.y1; - - surface->flags |= GLITZ_SURFACE_FLAG_TRANSFORM_MASK; - if (m[3] != 0.0f || m[7] != 0.0f || (m[15] != 1.0f && m[15] != -1.0f)) - surface->flags |= GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK; - } else { - if (surface->transform) - free (surface->transform); - - surface->transform = NULL; - surface->flags &= ~GLITZ_SURFACE_FLAG_TRANSFORM_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK; - } } slim_hidden_def(glitz_surface_set_transform); void glitz_surface_set_fill (glitz_surface_t *surface, - glitz_fill_t fill) + glitz_fill_t fill) { - switch (fill) { - case GLITZ_FILL_TRANSPARENT: - surface->flags &= ~GLITZ_SURFACE_FLAG_REPEAT_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_MIRRORED_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_PAD_MASK; - break; - case GLITZ_FILL_NEAREST: - surface->flags &= ~GLITZ_SURFACE_FLAG_REPEAT_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_MIRRORED_MASK; - surface->flags |= GLITZ_SURFACE_FLAG_PAD_MASK; - break; - case GLITZ_FILL_REPEAT: - surface->flags |= GLITZ_SURFACE_FLAG_REPEAT_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_MIRRORED_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_PAD_MASK; - break; - case GLITZ_FILL_REFLECT: - surface->flags |= GLITZ_SURFACE_FLAG_REPEAT_MASK; - surface->flags |= GLITZ_SURFACE_FLAG_MIRRORED_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_PAD_MASK; - break; - } - - glitz_filter_set_type (surface, surface->filter); + switch (fill) { + case GLITZ_FILL_TRANSPARENT: + surface->flags &= ~GLITZ_SURFACE_FLAG_REPEAT_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_MIRRORED_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_PAD_MASK; + break; + case GLITZ_FILL_NEAREST: + surface->flags &= ~GLITZ_SURFACE_FLAG_REPEAT_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_MIRRORED_MASK; + surface->flags |= GLITZ_SURFACE_FLAG_PAD_MASK; + break; + case GLITZ_FILL_REPEAT: + surface->flags |= GLITZ_SURFACE_FLAG_REPEAT_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_MIRRORED_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_PAD_MASK; + break; + case GLITZ_FILL_REFLECT: + surface->flags |= GLITZ_SURFACE_FLAG_REPEAT_MASK; + surface->flags |= GLITZ_SURFACE_FLAG_MIRRORED_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_PAD_MASK; + break; + } + + glitz_filter_set_type (surface, surface->filter); } slim_hidden_def(glitz_surface_set_fill); void glitz_surface_set_component_alpha (glitz_surface_t *surface, - glitz_bool_t component_alpha) + glitz_bool_t component_alpha) { - if (component_alpha && surface->format->color.red_size) - surface->flags |= GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK; - else - surface->flags &= ~GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK; + if (component_alpha && surface->format->color.red_size) + surface->flags |= GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK; + else + surface->flags &= ~GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK; } slim_hidden_def(glitz_surface_set_component_alpha); void glitz_surface_set_filter (glitz_surface_t *surface, - glitz_filter_t filter, - glitz_fixed16_16_t *params, - int n_params) + glitz_filter_t filter, + glitz_fixed16_16_t *params, + int n_params) { - glitz_status_t status; - - status = glitz_filter_set_params (surface, filter, params, n_params); - if (status) { - glitz_surface_status_add (surface, glitz_status_to_status_mask (status)); - } else { - switch (filter) { - case GLITZ_FILTER_NEAREST: - surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK; - break; - case GLITZ_FILTER_BILINEAR: - surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK; - surface->flags |= GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK; - break; - case GLITZ_FILTER_CONVOLUTION: - case GLITZ_FILTER_GAUSSIAN: - surface->flags |= GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK; - surface->flags |= GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK; - break; - case GLITZ_FILTER_LINEAR_GRADIENT: - case GLITZ_FILTER_RADIAL_GRADIENT: - surface->flags |= GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK; - surface->flags &= ~GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK; - surface->flags |= GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK; - surface->flags |= GLITZ_SURFACE_FLAG_EYE_COORDS_MASK; - break; + glitz_status_t status; + + status = glitz_filter_set_params (surface, filter, params, n_params); + if (status) { + glitz_surface_status_add (surface, + glitz_status_to_status_mask (status)); + } else { + switch (filter) { + case GLITZ_FILTER_NEAREST: + surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK; + break; + case GLITZ_FILTER_BILINEAR: + surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK; + surface->flags |= GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK; + break; + case GLITZ_FILTER_CONVOLUTION: + case GLITZ_FILTER_GAUSSIAN: + surface->flags |= GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK; + surface->flags |= GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK; + break; + case GLITZ_FILTER_LINEAR_GRADIENT: + case GLITZ_FILTER_RADIAL_GRADIENT: + surface->flags |= GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK; + surface->flags |= GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK; + surface->flags |= GLITZ_SURFACE_FLAG_EYE_COORDS_MASK; + break; + } + surface->filter = filter; } - surface->filter = filter; - } } slim_hidden_def(glitz_surface_set_filter); void glitz_surface_set_dither (glitz_surface_t *surface, - glitz_bool_t dither) + glitz_bool_t dither) { - if (dither) - surface->flags |= GLITZ_SURFACE_FLAG_DITHER_MASK; - else - surface->flags &= ~GLITZ_SURFACE_FLAG_DITHER_MASK; + if (dither) + surface->flags |= GLITZ_SURFACE_FLAG_DITHER_MASK; + else + surface->flags &= ~GLITZ_SURFACE_FLAG_DITHER_MASK; } slim_hidden_def(glitz_surface_set_dither); void glitz_surface_flush (glitz_surface_t *surface) { - if (surface->attached && REGION_NOTEMPTY (&surface->drawable_damage)) { - glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); - glitz_surface_pop_current (surface); - } + if (!surface->attached) + return; + + if (!DRAWABLE_IS_FBO (surface->attached)) + { + if (REGION_NOTEMPTY (&surface->drawable_damage)) + { + glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); + glitz_surface_pop_current (surface); + } + } } slim_hidden_def(glitz_surface_flush); unsigned int glitz_surface_get_width (glitz_surface_t *surface) { - return (unsigned int) surface->box.x2; + return (unsigned int) surface->box.x2; } slim_hidden_def(glitz_surface_get_width); unsigned int glitz_surface_get_height (glitz_surface_t *surface) { - return (unsigned int) surface->box.y2; + return (unsigned int) surface->box.y2; } slim_hidden_def(glitz_surface_get_height); glitz_status_t glitz_surface_get_status (glitz_surface_t *surface) { - return glitz_status_pop_from_mask (&surface->status_mask); + return glitz_status_pop_from_mask (&surface->status_mask); } slim_hidden_def(glitz_surface_get_status); glitz_format_t * glitz_surface_get_format (glitz_surface_t *surface) { - return surface->format; + return surface->format; } slim_hidden_def(glitz_surface_get_format); void glitz_surface_translate_point (glitz_surface_t *surface, - glitz_point_fixed_t *src, - glitz_point_fixed_t *dst) + glitz_point_fixed_t *src, + glitz_point_fixed_t *dst) { if (surface->texture.target == GLITZ_GL_TEXTURE_2D) { - dst->x = (INT_TO_FIXED (surface->texture.box.x1) + src->x) / - surface->texture.width; - dst->y = (INT_TO_FIXED (surface->texture.box.y2) - src->y) / - surface->texture.height; + dst->x = (INT_TO_FIXED (surface->texture.box.x1) + src->x) / + surface->texture.width; + dst->y = (INT_TO_FIXED (surface->texture.box.y2) - src->y) / + surface->texture.height; } else { - dst->x = INT_TO_FIXED (surface->texture.box.x1) + src->x; - dst->y = INT_TO_FIXED (surface->texture.box.y2) - src->y; + dst->x = INT_TO_FIXED (surface->texture.box.x1) + src->x; + dst->y = INT_TO_FIXED (surface->texture.box.y2) - src->y; } } slim_hidden_def(glitz_surface_translate_point); void glitz_surface_set_clip_region (glitz_surface_t *surface, - int x_origin, - int y_origin, - glitz_box_t *box, - int n_box) + int x_origin, + int y_origin, + glitz_box_t *box, + int n_box) { if (n_box) { - surface->clip = box; - surface->n_clip = n_box; - surface->x_clip = x_origin; - surface->y_clip = y_origin; + surface->clip = box; + surface->n_clip = n_box; + surface->x_clip = x_origin; + surface->y_clip = y_origin; } else { - surface->clip = &surface->box; - surface->n_clip = 1; - surface->x_clip = surface->y_clip = 0; + surface->clip = &surface->box; + surface->n_clip = 1; + surface->x_clip = surface->y_clip = 0; } } slim_hidden_def(glitz_surface_set_clip_region); - -glitz_bool_t -glitz_surface_valid_target (glitz_surface_t *surface) -{ - glitz_bool_t valid; - - valid = glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); - glitz_surface_pop_current (surface); - - return valid; -} diff --git a/src/glitz_texture.c b/src/glitz_texture.c index 6f65588..53737e3 100644 --- a/src/glitz_texture.c +++ b/src/glitz_texture.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,317 +31,444 @@ void glitz_texture_init (glitz_texture_t *texture, - int width, - int height, - glitz_gl_int_t texture_format, - unsigned long feature_mask, - glitz_bool_t unnormalized) + int width, + int height, + glitz_gl_int_t texture_format, + unsigned long feature_mask, + glitz_bool_t unnormalized) { - texture->filter = 0; - texture->wrap = 0; + texture->param.filter[0] = texture->param.filter[1] = GLITZ_GL_NEAREST; + texture->param.wrap[0] = texture->param.wrap[1] = GLITZ_GL_CLAMP; + texture->param.border_color.red = texture->param.border_color.green = + texture->param.border_color.blue = + texture->param.border_color.alpha = 0; + texture->format = texture_format; texture->name = 0; if (feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK) { - texture->box.x1 = texture->box.y1 = 0; - texture->box.x2 = texture->width = width; - texture->box.y2 = texture->height = height; - texture->flags = GLITZ_TEXTURE_FLAG_REPEATABLE_MASK | - GLITZ_TEXTURE_FLAG_PADABLE_MASK; + texture->box.x1 = texture->box.y1 = 0; + texture->box.x2 = texture->width = width; + texture->box.y2 = texture->height = height; + texture->flags = GLITZ_TEXTURE_FLAG_REPEATABLE_MASK | + GLITZ_TEXTURE_FLAG_PADABLE_MASK; } else { - texture->box.x1 = texture->box.y1 = 1; - texture->box.x2 = width + 1; - texture->box.y2 = height + 1; - texture->width = width + 2; - texture->height = height + 2; - texture->flags = 0; + texture->box.x1 = texture->box.y1 = 1; + texture->box.x2 = width + 1; + texture->box.y2 = height + 1; + texture->width = width + 2; + texture->height = height + 2; + texture->flags = 0; } - + if (!unnormalized && - ((feature_mask & GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) || - (POWER_OF_TWO (texture->width) && POWER_OF_TWO (texture->height)))) + ((feature_mask & GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) || + (POWER_OF_TWO (texture->width) && POWER_OF_TWO (texture->height)))) { - texture->target = GLITZ_GL_TEXTURE_2D; + texture->target = GLITZ_GL_TEXTURE_2D; } else { - texture->flags &= ~GLITZ_TEXTURE_FLAG_REPEATABLE_MASK; - - if (feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) - { - texture->target = GLITZ_GL_TEXTURE_RECTANGLE; - } - else - { - texture->target = GLITZ_GL_TEXTURE_2D; - texture->flags &= ~GLITZ_TEXTURE_FLAG_PADABLE_MASK; - - if (!POWER_OF_TWO (texture->width)) - texture->width = glitz_uint_to_power_of_two (texture->width); - - if (!POWER_OF_TWO (texture->height)) - texture->height = glitz_uint_to_power_of_two (texture->height); - } + texture->flags &= ~GLITZ_TEXTURE_FLAG_REPEATABLE_MASK; + + if (feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) + { + texture->target = GLITZ_GL_TEXTURE_RECTANGLE; + } + else + { + texture->target = GLITZ_GL_TEXTURE_2D; + texture->flags &= ~GLITZ_TEXTURE_FLAG_PADABLE_MASK; + + if (!POWER_OF_TWO (texture->width)) + texture->width = glitz_uint_to_power_of_two (texture->width); + + if (!POWER_OF_TWO (texture->height)) + texture->height = glitz_uint_to_power_of_two (texture->height); + } } if (texture->target == GLITZ_GL_TEXTURE_2D) { - texture->texcoord_width_unit = 1.0f / texture->width; - texture->texcoord_height_unit = 1.0f / texture->height; + texture->texcoord_width_unit = 1.0f / texture->width; + texture->texcoord_height_unit = 1.0f / texture->height; } else { - texture->texcoord_width_unit = 1.0f; - texture->texcoord_height_unit = 1.0f; + texture->texcoord_width_unit = 1.0f; + texture->texcoord_height_unit = 1.0f; } } void glitz_texture_size_check (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_int_t max_2d, - glitz_gl_int_t max_rect) { - glitz_gl_enum_t proxy_target; - glitz_gl_int_t value, max; - - if (texture->target == GLITZ_GL_TEXTURE_2D) { - max = max_2d; - proxy_target = GLITZ_GL_PROXY_TEXTURE_2D; - } else { - max = max_rect; - proxy_target = GLITZ_GL_PROXY_TEXTURE_RECTANGLE; - } - - if (texture->width > max || texture->height > max) { - texture->flags |= GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK; - return; - } - - gl->tex_image_2d (proxy_target, 0, - texture->format, texture->width, texture->height, - 0, GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL); - gl->get_tex_level_parameter_iv (proxy_target, 0, - GLITZ_GL_TEXTURE_WIDTH, &value); - if (value != texture->width) { - texture->flags |= GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK; - return; - } - - gl->get_tex_level_parameter_iv (proxy_target, 0, - GLITZ_GL_TEXTURE_HEIGHT, &value); - if (value != texture->height) - texture->flags |= GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK; + glitz_texture_t *texture, + glitz_gl_int_t max_2d, + glitz_gl_int_t max_rect) +{ + glitz_gl_enum_t proxy_target; + glitz_gl_int_t value, max; + + if (texture->target == GLITZ_GL_TEXTURE_2D) { + max = max_2d; + proxy_target = GLITZ_GL_PROXY_TEXTURE_2D; + } else { + max = max_rect; + proxy_target = GLITZ_GL_PROXY_TEXTURE_RECTANGLE; + } + + if (texture->width > max || texture->height > max) { + texture->flags |= GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK; + return; + } + + gl->tex_image_2d (proxy_target, 0, + texture->format, texture->width, texture->height, + 0, GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL); + gl->get_tex_level_parameter_iv (proxy_target, 0, + GLITZ_GL_TEXTURE_WIDTH, &value); + if (value != texture->width) { + texture->flags |= GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK; + return; + } + + gl->get_tex_level_parameter_iv (proxy_target, 0, + GLITZ_GL_TEXTURE_HEIGHT, &value); + if (value != texture->height) + texture->flags |= GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK; } void glitz_texture_allocate (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture) + glitz_texture_t *texture) { - char *data = NULL; - - if (!texture->name) - gl->gen_textures (1, &texture->name); - - texture->flags |= GLITZ_TEXTURE_FLAG_ALLOCATED_MASK; - - glitz_texture_bind (gl, texture); - - if (texture->box.x2 != texture->width || - texture->box.y2 != texture->height) { - data = malloc (texture->width * texture->height); - if (data) - memset (data, 0, texture->width * texture->height); - - gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); - gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); - gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0); - gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0); - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1); - } - - gl->tex_image_2d (texture->target, 0, texture->format, - texture->width, texture->height, 0, - GLITZ_GL_ALPHA, GLITZ_GL_UNSIGNED_BYTE, data); - - gl->tex_parameter_i (texture->target, - GLITZ_GL_TEXTURE_MAG_FILTER, - GLITZ_GL_NEAREST); - gl->tex_parameter_i (texture->target, - GLITZ_GL_TEXTURE_MIN_FILTER, - GLITZ_GL_NEAREST); - - texture->filter = GLITZ_GL_NEAREST; - - glitz_texture_unbind (gl, texture); - - if (data) - free (data); -} + char *data = NULL; -void -glitz_texture_fini (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture) -{ - if (texture->name) - gl->delete_textures (1, &texture->name); -} + if (!texture->name) + gl->gen_textures (1, &texture->name); -void -glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_enum_t filter) -{ - if (!texture->name) - return; - - if (texture->filter != filter) { - gl->tex_parameter_i (texture->target, GLITZ_GL_TEXTURE_MAG_FILTER, filter); - gl->tex_parameter_i (texture->target, GLITZ_GL_TEXTURE_MIN_FILTER, filter); - texture->filter = filter; - } + texture->flags |= GLITZ_TEXTURE_FLAG_ALLOCATED_MASK; + + glitz_texture_bind (gl, texture); + + if (texture->box.x2 != texture->width || + texture->box.y2 != texture->height) { + data = malloc (texture->width * texture->height); + if (data) + memset (data, 0, texture->width * texture->height); + + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0); + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0); + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1); + } + + gl->tex_image_2d (texture->target, 0, texture->format, + texture->width, texture->height, 0, + GLITZ_GL_ALPHA, GLITZ_GL_UNSIGNED_BYTE, data); + + gl->tex_parameter_i (texture->target, + GLITZ_GL_TEXTURE_MAG_FILTER, + texture->param.filter[0]); + gl->tex_parameter_i (texture->target, + GLITZ_GL_TEXTURE_MIN_FILTER, + texture->param.filter[1]); + + glitz_texture_unbind (gl, texture); + + if (data) + free (data); } void -glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_enum_t wrap) +glitz_texture_fini (glitz_gl_proc_address_list_t *gl, + glitz_texture_t *texture) { - if (!texture->name) - return; - - if (texture->wrap != wrap) { - gl->tex_parameter_i (texture->target, GLITZ_GL_TEXTURE_WRAP_S, wrap); - gl->tex_parameter_i (texture->target, GLITZ_GL_TEXTURE_WRAP_T, wrap); - texture->wrap = wrap; - } + if (texture->name) + gl->delete_textures (1, &texture->name); } void glitz_texture_bind (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture) -{ - gl->disable (GLITZ_GL_TEXTURE_RECTANGLE); - gl->disable (GLITZ_GL_TEXTURE_2D); + glitz_texture_t *texture) +{ + gl->disable (GLITZ_GL_TEXTURE_RECTANGLE); + gl->disable (GLITZ_GL_TEXTURE_2D); - if (!texture->name) - return; + if (!texture->name) + return; - gl->enable (texture->target); - gl->bind_texture (texture->target, texture->name); + gl->enable (texture->target); + gl->bind_texture (texture->target, texture->name); } void glitz_texture_unbind (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture) + glitz_texture_t *texture) { - gl->bind_texture (texture->target, 0); - gl->disable (texture->target); + gl->bind_texture (texture->target, 0); + gl->disable (texture->target); } void glitz_texture_copy_drawable (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_drawable_t *drawable, - int x_drawable, - int y_drawable, - int width, - int height, - int x_texture, - int y_texture) + glitz_texture_t *texture, + glitz_drawable_t *drawable, + int x_drawable, + int y_drawable, + int width, + int height, + int x_texture, + int y_texture) { - gl->copy_tex_sub_image_2d (texture->target, 0, - texture->box.x1 + x_texture, - texture->box.y2 - y_texture - height, - x_drawable, - drawable->height - y_drawable - height, - width, height); + gl->copy_tex_sub_image_2d (texture->target, 0, + texture->box.x1 + x_texture, + texture->box.y2 - y_texture - height, + x_drawable, + drawable->height - y_drawable - height, + width, height); } void glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_geometry_t *geometry, - int x_src, - int y_src, - unsigned long flags, - glitz_int_coordinate_t *coord) + glitz_texture_t *texture, + glitz_geometry_t *geometry, + int x_src, + int y_src, + unsigned long flags, + glitz_int_coordinate_t *coord) { glitz_vec4_t plane; if (flags & GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK) { - plane.v[1] = plane.v[2] = 0.0f; - - if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) - { - plane.v[0] = 1.0f; - plane.v[3] = -x_src; - } - else - { - plane.v[0] = texture->texcoord_width_unit; - - if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK) - plane.v[3] = -(x_src) * texture->texcoord_width_unit; - else - plane.v[3] = -(x_src - texture->box.x1) * - texture->texcoord_width_unit; - } - - gl->tex_gen_i (GLITZ_GL_S, GLITZ_GL_TEXTURE_GEN_MODE, - GLITZ_GL_EYE_LINEAR); - gl->tex_gen_fv (GLITZ_GL_S, GLITZ_GL_EYE_PLANE, plane.v); - - gl->enable (GLITZ_GL_TEXTURE_GEN_S); + plane.v[1] = plane.v[2] = 0.0f; + + if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) + { + plane.v[0] = 1.0f; + plane.v[3] = -x_src; + } + else + { + plane.v[0] = texture->texcoord_width_unit; + + if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK) + plane.v[3] = -(x_src) * texture->texcoord_width_unit; + else + plane.v[3] = -(x_src - texture->box.x1) * + texture->texcoord_width_unit; + } + + gl->tex_gen_i (GLITZ_GL_S, GLITZ_GL_TEXTURE_GEN_MODE, + GLITZ_GL_EYE_LINEAR); + gl->tex_gen_fv (GLITZ_GL_S, GLITZ_GL_EYE_PLANE, plane.v); + + gl->enable (GLITZ_GL_TEXTURE_GEN_S); } else - gl->disable (GLITZ_GL_TEXTURE_GEN_S); + gl->disable (GLITZ_GL_TEXTURE_GEN_S); if (flags & GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK) { - plane.v[0] = plane.v[2] = 0.0f; - if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) - { - plane.v[1] = 1.0f; - plane.v[3] = -y_src; - } - else - { - plane.v[1] = -texture->texcoord_height_unit; - - if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK) - plane.v[3] = (y_src + texture->box.y2 - texture->box.y1) * - texture->texcoord_height_unit; - else - plane.v[3] = (y_src + texture->box.y2) * - texture->texcoord_height_unit; - } - - gl->tex_gen_i (GLITZ_GL_T, GLITZ_GL_TEXTURE_GEN_MODE, - GLITZ_GL_EYE_LINEAR); - gl->tex_gen_fv (GLITZ_GL_T, GLITZ_GL_EYE_PLANE, plane.v); - - gl->enable (GLITZ_GL_TEXTURE_GEN_T); + plane.v[0] = plane.v[2] = 0.0f; + if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) + { + plane.v[1] = 1.0f; + plane.v[3] = -y_src; + } + else + { + plane.v[1] = -texture->texcoord_height_unit; + + if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK) + plane.v[3] = (y_src + texture->box.y2 - texture->box.y1) * + texture->texcoord_height_unit; + else + plane.v[3] = (y_src + texture->box.y2) * + texture->texcoord_height_unit; + } + + gl->tex_gen_i (GLITZ_GL_T, GLITZ_GL_TEXTURE_GEN_MODE, + GLITZ_GL_EYE_LINEAR); + gl->tex_gen_fv (GLITZ_GL_T, GLITZ_GL_EYE_PLANE, plane.v); + + gl->enable (GLITZ_GL_TEXTURE_GEN_T); } else - gl->disable (GLITZ_GL_TEXTURE_GEN_T); + gl->disable (GLITZ_GL_TEXTURE_GEN_T); if (!(flags & GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK)) { - unsigned char *ptr; + unsigned char *ptr; - gl->enable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY); - - ptr = glitz_buffer_bind (geometry->buffer, GLITZ_GL_ARRAY_BUFFER); - ptr += coord->offset; + gl->enable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY); - gl->tex_coord_pointer (coord->size, - coord->type, - geometry->stride, - (void *) ptr); + ptr = glitz_buffer_bind (geometry->buffer, GLITZ_GL_ARRAY_BUFFER); + ptr += coord->offset; + + gl->tex_coord_pointer (coord->size, + coord->type, + geometry->stride, + (void *) ptr); } else - gl->disable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY); + gl->disable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY); +} + +glitz_texture_object_t * +glitz_texture_object_create (glitz_surface_t *surface) +{ + glitz_texture_object_t *texture; + + GLITZ_GL_SURFACE (surface); + + /* GL_ARB_texture_rectangle is required for sane texture coordinates. + GL_ARB_texture_border_clamp is required right now as glitz will + emulate it when missing, which means a 1 pixel translucent black + border inside textures and that cannot be exposed to clients. */ + if ((!(surface->drawable->backend->feature_mask & + GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)) || + (!(surface->drawable->backend->feature_mask & + GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK))) + return 0; + + texture = malloc (sizeof (glitz_texture_object_t)); + if (!texture) + return 0; + + texture->ref_count = 1; + + glitz_surface_reference (surface); + texture->surface = surface; + + if (!(TEXTURE_ALLOCATED (&surface->texture))) + glitz_texture_allocate (gl, &surface->texture); + + texture->param = surface->texture.param; + + return texture; +} + +void +glitz_texture_object_destroy (glitz_texture_object_t *texture) +{ + texture->ref_count--; + if (texture->ref_count) + return; + + glitz_surface_destroy (texture->surface); + free (texture); +} + +void +glitz_texture_object_reference (glitz_texture_object_t *texture) +{ + texture->ref_count++; +} + +void +glitz_texture_object_set_filter (glitz_texture_object_t *texture, + glitz_texture_filter_type_t type, + glitz_texture_filter_t filter) +{ + static glitz_gl_enum_t filters[] = { + GLITZ_GL_NEAREST, + GLITZ_GL_LINEAR + }; + + texture->param.filter[type] = filters[filter]; +} + +void +glitz_texture_object_set_wrap (glitz_texture_object_t *texture, + glitz_texture_wrap_type_t type, + glitz_texture_wrap_t wrap) +{ + static glitz_gl_enum_t wraps[] = { + GLITZ_GL_CLAMP, + GLITZ_GL_CLAMP_TO_EDGE, + GLITZ_GL_CLAMP_TO_BORDER, + GLITZ_GL_REPEAT, + GLITZ_GL_MIRRORED_REPEAT + }; + + texture->param.wrap[type] = wraps[wrap]; +} + +void +glitz_texture_object_set_border_color (glitz_texture_object_t *texture, + glitz_color_t *color) +{ + texture->param.border_color = *color; +} + +void +glitz_texture_ensure_parameters (glitz_gl_proc_address_list_t *gl, + glitz_texture_t *texture, + glitz_texture_parameters_t *param) +{ + static const glitz_gl_enum_t filters[] = { + GLITZ_GL_TEXTURE_MAG_FILTER, + GLITZ_GL_TEXTURE_MIN_FILTER + }; + static const glitz_gl_enum_t wraps[] = { + GLITZ_GL_TEXTURE_WRAP_S, + GLITZ_GL_TEXTURE_WRAP_T + }; + int i; + + if (!texture->name) + return; + + for (i = 0; i < 2; i++) + { + if (texture->param.filter[i] != param->filter[i]) + { + texture->param.filter[i] = param->filter[i]; + gl->tex_parameter_i (texture->target, filters[i], + param->filter[i]); + } + + if (texture->param.wrap[i] != param->wrap[i]) + { + texture->param.wrap[i] = param->wrap[i]; + gl->tex_parameter_i (texture->target, wraps[i], param->wrap[i]); + } + } + + if (texture->param.wrap[0] == GLITZ_GL_CLAMP_TO_BORDER || + texture->param.wrap[1] == GLITZ_GL_CLAMP_TO_BORDER || + texture->param.wrap[0] == GLITZ_GL_CLAMP || + texture->param.wrap[1] == GLITZ_GL_CLAMP) + { + if (memcmp (&texture->param.border_color, ¶m->border_color, + sizeof (glitz_color_t))) + { + glitz_vec4_t vec; + + vec.v[0] = (glitz_float_t) param->border_color.red / 0xffff; + vec.v[1] = (glitz_float_t) param->border_color.green / 0xffff; + vec.v[2] = (glitz_float_t) param->border_color.blue / 0xffff; + vec.v[3] = (glitz_float_t) param->border_color.alpha / 0xffff; + + gl->tex_parameter_fv (texture->target, + GLITZ_GL_TEXTURE_BORDER_COLOR, + vec.v); + + texture->param.border_color = param->border_color; + } + } +} + +glitz_texture_target_t +glitz_texture_object_get_target (glitz_texture_object_t *texture) +{ + if (texture->surface->texture.target == GLITZ_GL_TEXTURE_2D) + return GLITZ_TEXTURE_TARGET_2D; + + return GLITZ_TEXTURE_TARGET_RECT; } diff --git a/src/glitz_trap.c b/src/glitz_trap.c index 7cad8a5..7a1654d 100644 --- a/src/glitz_trap.c +++ b/src/glitz_trap.c @@ -1,6 +1,6 @@ /* * Copyright © 2005 Novell, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -30,9 +30,9 @@ #include "glitzint.h" /* whether 't' is a well defined not obviously empty trapezoid */ -#define TRAPEZOID_VALID(t) ((t)->left.p1.y != (t)->left.p2.y && \ - (t)->right.p1.y != (t)->right.p2.y && \ - (int) ((t)->bottom - (t)->top) > 0) +#define TRAPEZOID_VALID(t) ((t)->left.p1.y != (t)->left.p2.y && \ + (t)->right.p1.y != (t)->right.p2.y && \ + (int) ((t)->bottom - (t)->top) > 0) /* whether 't' is a well defined not obviously empty trap */ #define TRAP_VALID(t) ((int) ((t)->bottom.y - (t)->top.y) > 0) @@ -46,57 +46,57 @@ typedef struct _glitz_edge { int hyp; } glitz_edge_t; -#define EDGE_INIT(e, p1x, p1y, p2x, p2y) \ - (e)->hyp = 1; \ - (e)->dx = (p2x) - (p1x); \ - (e)->dy = (p2y) - (p1y); \ - if ((e)->dy) \ - (e)->kx = (e)->dx / (e)->dy; \ - else \ - (e)->kx = 0; \ - (e)->x0 = (p1x) - (e)->kx * (p1y); \ - if ((e)->dx) \ - (e)->ky = (e)->dy / (e)->dx; \ - else \ - (e)->ky = 0; \ +#define EDGE_INIT(e, p1x, p1y, p2x, p2y) \ + (e)->hyp = 1; \ + (e)->dx = (p2x) - (p1x); \ + (e)->dy = (p2y) - (p1y); \ + if ((e)->dy) \ + (e)->kx = (e)->dx / (e)->dy; \ + else \ + (e)->kx = 0; \ + (e)->x0 = (p1x) - (e)->kx * (p1y); \ + if ((e)->dx) \ + (e)->ky = (e)->dy / (e)->dx; \ + else \ + (e)->ky = 0; \ (e)->y0 = (p1y) - (e)->ky * (p1x) #define EDGE_X(e, _y) (((e)->kx * (_y)) + (e)->x0) #define EDGE_Y(e, _x) (((e)->ky * (_x)) + (e)->y0) -#define EDGE_INTERSECT_BOX(upper_x, lower_y, left_y, right_y, \ - box_x1, box_x2, box_y1, box_y2, \ - max_x, max_y, \ - _x1, _y1, _x2, _y2) \ - if (upper_x < (box_x1)) \ - { \ - (_x1) = 0.0f; \ - (_y1) = (left_y) - (box_y1); \ - } \ - else if ((upper_x) > (box_x2)) \ - { \ - (_x1) = (max_x); \ - (_y1) = (right_y) - (box_y1); \ - } \ - else \ - { \ - (_x1) = (upper_x) - (box_x1); \ - (_y1) = 0.0f; \ - } \ - if ((lower_x) < (box_x1)) \ - { \ - (_x2) = 0.0f; \ - (_y2) = (left_y) - (box_y1); \ - } \ - else if ((lower_x) > (box_x2)) \ - { \ - (_x2) = (max_x); \ - (_y2) = (right_y) - (box_y1); \ - } \ - else \ - { \ - (_x2) = (lower_x) - (box_x1); \ - (_y2) = (max_y); \ +#define EDGE_INTERSECT_BOX(upper_x, lower_y, left_y, right_y, \ + box_x1, box_x2, box_y1, box_y2, \ + max_x, max_y, \ + _x1, _y1, _x2, _y2) \ + if (upper_x < (box_x1)) \ + { \ + (_x1) = 0.0f; \ + (_y1) = (left_y) - (box_y1); \ + } \ + else if ((upper_x) > (box_x2)) \ + { \ + (_x1) = (max_x); \ + (_y1) = (right_y) - (box_y1); \ + } \ + else \ + { \ + (_x1) = (upper_x) - (box_x1); \ + (_y1) = 0.0f; \ + } \ + if ((lower_x) < (box_x1)) \ + { \ + (_x2) = 0.0f; \ + (_y2) = (left_y) - (box_y1); \ + } \ + else if ((lower_x) > (box_x2)) \ + { \ + (_x2) = (max_x); \ + (_y2) = (right_y) - (box_y1); \ + } \ + else \ + { \ + (_x2) = (lower_x) - (box_x1); \ + (_y2) = (max_y); \ } #define AREA_ABOVE_LEFT(x1, y1, x2, y2, bottom) \ @@ -110,11 +110,11 @@ typedef struct _glitz_edge { */ static glitz_float_t _glitz_pixel_area (glitz_float_t pixel_x, - glitz_float_t pixel_y, - glitz_float_t top, - glitz_float_t bottom, - glitz_edge_t *left, - glitz_edge_t *right) + glitz_float_t pixel_y, + glitz_float_t top, + glitz_float_t bottom, + glitz_edge_t *left, + glitz_edge_t *right) { glitz_float_t area; glitz_float_t upper_x, lower_x; @@ -124,158 +124,158 @@ _glitz_pixel_area (glitz_float_t pixel_x, glitz_float_t x1, x2, y1, y2; if (bottom >= pixel_y_1) - bottom = 1.0f; + bottom = 1.0f; else - bottom = bottom - pixel_y; + bottom = bottom - pixel_y; if (top <= pixel_y) - top = 0.0f; + top = 0.0f; else - top = top - pixel_y; - + top = top - pixel_y; + if (right->ky) { - upper_x = EDGE_X (right, pixel_y); - lower_x = EDGE_X (right, pixel_y_1); - - left_y = EDGE_Y (right, pixel_x); - right_y = EDGE_Y (right, pixel_x_1); - - EDGE_INTERSECT_BOX (upper_x, lower_y, left_y, right_y, - pixel_x, pixel_x_1, pixel_y, pixel_y_1, - 1.0f, 1.0f, x1, y1, x2, y2); - - if (bottom <= y1) - { - if (left_y > right_y) - area = bottom; - else - area = 0.0f; - } - else - { - if (bottom < y2) - { - x2 -= right->kx * (y2 - bottom); - y2 = bottom; - } - area = AREA_ABOVE_LEFT (x1, y1, x2, y2, bottom); - } - - if (top <= y1) - { - if (left_y > right_y) - area -= top; - } - else - { - if (top < y2) - { - x2 -= right->kx * (y2 - top); - y2 = top; - } - - area -= AREA_ABOVE_LEFT (x1, y1, x2, y2, top); - } + upper_x = EDGE_X (right, pixel_y); + lower_x = EDGE_X (right, pixel_y_1); + + left_y = EDGE_Y (right, pixel_x); + right_y = EDGE_Y (right, pixel_x_1); + + EDGE_INTERSECT_BOX (upper_x, lower_y, left_y, right_y, + pixel_x, pixel_x_1, pixel_y, pixel_y_1, + 1.0f, 1.0f, x1, y1, x2, y2); + + if (bottom <= y1) + { + if (left_y > right_y) + area = bottom; + else + area = 0.0f; + } + else + { + if (bottom < y2) + { + x2 -= right->kx * (y2 - bottom); + y2 = bottom; + } + area = AREA_ABOVE_LEFT (x1, y1, x2, y2, bottom); + } + + if (top <= y1) + { + if (left_y > right_y) + area -= top; + } + else + { + if (top < y2) + { + x2 -= right->kx * (y2 - top); + y2 = top; + } + + area -= AREA_ABOVE_LEFT (x1, y1, x2, y2, top); + } } else { - /* Vertical Edge */ - if (right->x0 < pixel_x_1) - area = (right->x0 - pixel_x) * (bottom - top); - else - area = bottom - top; + /* Vertical Edge */ + if (right->x0 < pixel_x_1) + area = (right->x0 - pixel_x) * (bottom - top); + else + area = bottom - top; } if (left->kx) { - upper_x = EDGE_X (left, pixel_y); - lower_x = EDGE_X (left, pixel_y_1); - - left_y = EDGE_Y (left, pixel_x); - right_y = EDGE_Y (left, pixel_x_1); - - EDGE_INTERSECT_BOX (upper_x, lower_y, left_y, right_y, - pixel_x, pixel_x_1, pixel_y, pixel_y_1, - 1.0f, 1.0f, x1, y1, x2, y2); - - if (bottom <= y1) - { - if (left_y > right_y) - area -= bottom; - } - else - { - if (bottom < y2) - { - x2 -= left->kx * (y2 - bottom); - y2 = bottom; - } - area -= AREA_ABOVE_LEFT (x1, y1, x2, y2, bottom); - } - - if (top <= y1) - { - if (left_y > right_y) - area += top; - } - else - { - if (top < y2) - { - x2 -= left->kx * (y2 - top); - y2 = top; - } - - area += AREA_ABOVE_LEFT (x1, y1, x2, y2, top); - } + upper_x = EDGE_X (left, pixel_y); + lower_x = EDGE_X (left, pixel_y_1); + + left_y = EDGE_Y (left, pixel_x); + right_y = EDGE_Y (left, pixel_x_1); + + EDGE_INTERSECT_BOX (upper_x, lower_y, left_y, right_y, + pixel_x, pixel_x_1, pixel_y, pixel_y_1, + 1.0f, 1.0f, x1, y1, x2, y2); + + if (bottom <= y1) + { + if (left_y > right_y) + area -= bottom; + } + else + { + if (bottom < y2) + { + x2 -= left->kx * (y2 - bottom); + y2 = bottom; + } + area -= AREA_ABOVE_LEFT (x1, y1, x2, y2, bottom); + } + + if (top <= y1) + { + if (left_y > right_y) + area += top; + } + else + { + if (top < y2) + { + x2 -= left->kx * (y2 - top); + y2 = top; + } + + area += AREA_ABOVE_LEFT (x1, y1, x2, y2, top); + } } else { - /* Vertical Edge */ - if (left->x0 > pixel_x) - area -= (left->x0 - pixel_x) * (bottom - top); + /* Vertical Edge */ + if (left->x0 > pixel_x) + area -= (left->x0 - pixel_x) * (bottom - top); } - + return area; } #define TRAPINIT(trap, _top, _bottom, _left, _right) \ if (!TRAPEZOID_VALID (trap)) \ - continue; \ - \ + continue; \ + \ (_top) = FIXED_TO_FLOAT ((trap)->top); \ (_bottom) = FIXED_TO_FLOAT ((trap)->bottom); \ - \ + \ (_left)->tx = FIXED_TO_FLOAT ((trap)->left.p1.x); \ (_left)->bx = FIXED_TO_FLOAT ((trap)->left.p1.y); \ - \ + \ (_right)->tx = FIXED_TO_FLOAT ((trap)->right.p1.x); \ (_right)->bx = FIXED_TO_FLOAT ((trap)->right.p1.y); \ - \ + \ EDGE_INIT (_left, \ - (_left)->tx, (_left)->bx, \ - FIXED_TO_FLOAT ((trap)->left.p2.x), \ - FIXED_TO_FLOAT ((trap)->left.p2.y)); \ - \ + (_left)->tx, (_left)->bx, \ + FIXED_TO_FLOAT ((trap)->left.p2.x), \ + FIXED_TO_FLOAT ((trap)->left.p2.y)); \ + \ EDGE_INIT (_right, \ - (_right)->tx, (_right)->bx, \ - FIXED_TO_FLOAT ((trap)->right.p2.x), \ - FIXED_TO_FLOAT ((trap)->right.p2.y)); \ - \ + (_right)->tx, (_right)->bx, \ + FIXED_TO_FLOAT ((trap)->right.p2.x), \ + FIXED_TO_FLOAT ((trap)->right.p2.y)); \ + \ if ((_left)->dx) \ { \ - (_left)->tx = EDGE_X (_left, _top); \ - (_left)->bx = EDGE_X (_left, _bottom); \ + (_left)->tx = EDGE_X (_left, _top); \ + (_left)->bx = EDGE_X (_left, _bottom); \ } else \ - (_left)->tx = (_left)->bx = (_left)->x0; \ - \ + (_left)->tx = (_left)->bx = (_left)->x0; \ + \ if ((_right)->dx) \ { \ - (_right)->tx = EDGE_X (_right, _top); \ - (_right)->bx = EDGE_X (_right, _bottom); \ + (_right)->tx = EDGE_X (_right, _top); \ + (_right)->bx = EDGE_X (_right, _bottom); \ } else \ - (_right)->tx = (_right)->bx = (_right)->x0 + (_right)->tx = (_right)->bx = (_right)->x0 #define TRAP glitz_trapezoid_t @@ -306,26 +306,26 @@ _glitz_pixel_area (glitz_float_t pixel_x, #undef TRAP #undef TRAPINIT -#define TRAPINIT(trap, _top, _bottom, _left, _right) \ - if (!TRAP_VALID (trap)) \ - continue; \ - \ - (_top) = FIXED_TO_FLOAT ((trap)->top.y); \ - (_bottom) = FIXED_TO_FLOAT ((trap)->bottom.y); \ - \ - (_left)->tx = FIXED_TO_FLOAT ((trap)->top.left); \ - (_left)->bx = FIXED_TO_FLOAT ((trap)->bottom.left); \ - \ - (_right)->tx = FIXED_TO_FLOAT ((trap)->top.right); \ - (_right)->bx = FIXED_TO_FLOAT ((trap)->bottom.right); \ - \ - EDGE_INIT (_left, \ - (_left)->tx, _top, \ - (_left)->bx, _bottom); \ - \ - EDGE_INIT (_right, \ - (_right)->tx, _top, \ - (_right)->bx, _bottom) +#define TRAPINIT(trap, _top, _bottom, _left, _right) \ + if (!TRAP_VALID (trap)) \ + continue; \ + \ + (_top) = FIXED_TO_FLOAT ((trap)->top.y); \ + (_bottom) = FIXED_TO_FLOAT ((trap)->bottom.y); \ + \ + (_left)->tx = FIXED_TO_FLOAT ((trap)->top.left); \ + (_left)->bx = FIXED_TO_FLOAT ((trap)->bottom.left); \ + \ + (_right)->tx = FIXED_TO_FLOAT ((trap)->top.right); \ + (_right)->bx = FIXED_TO_FLOAT ((trap)->bottom.right); \ + \ + EDGE_INIT (_left, \ + (_left)->tx, _top, \ + (_left)->bx, _bottom); \ + \ + EDGE_INIT (_right, \ + (_right)->tx, _top, \ + (_right)->bx, _bottom) #define TRAP glitz_trap_t @@ -358,44 +358,44 @@ _glitz_pixel_area (glitz_float_t pixel_x, int glitz_add_trapezoids (glitz_buffer_t *buffer, - int offset, - unsigned int size, - glitz_data_type_t type, - glitz_surface_t *mask, - glitz_trapezoid_t *traps, - int n_traps, - int *n_added) + int offset, + unsigned int size, + glitz_data_type_t type, + glitz_surface_t *mask, + glitz_trapezoid_t *traps, + int n_traps, + int *n_added) { int count, n = n_traps; uint8_t *ptr; - + *n_added = 0; - + ptr = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); if (!ptr) - return 0; + return 0; ptr += offset; - + switch (type) { case GLITZ_DATA_TYPE_SHORT: - count = _glitz_add_trapezoids_short (ptr, size, mask, traps, &n_traps); - break; + count = _glitz_add_trapezoids_short (ptr, size, mask, traps, &n_traps); + break; case GLITZ_DATA_TYPE_INT: - count = _glitz_add_trapezoids_int (ptr, size, mask, traps, &n_traps); - break; + count = _glitz_add_trapezoids_int (ptr, size, mask, traps, &n_traps); + break; case GLITZ_DATA_TYPE_DOUBLE: - count = _glitz_add_trapezoids_double (ptr, size, mask, - traps, &n_traps); - break; + count = _glitz_add_trapezoids_double (ptr, size, mask, + traps, &n_traps); + break; default: - count = _glitz_add_trapezoids_float (ptr, size, mask, traps, &n_traps); - break; + count = _glitz_add_trapezoids_float (ptr, size, mask, traps, &n_traps); + break; } if (glitz_buffer_unmap (buffer)) - return 0; - + return 0; + *n_added = n - n_traps; return count; @@ -403,42 +403,42 @@ glitz_add_trapezoids (glitz_buffer_t *buffer, int glitz_add_traps (glitz_buffer_t *buffer, - int offset, - unsigned int size, - glitz_data_type_t type, - glitz_surface_t *mask, - glitz_trap_t *traps, - int n_traps, - int *n_added) + int offset, + unsigned int size, + glitz_data_type_t type, + glitz_surface_t *mask, + glitz_trap_t *traps, + int n_traps, + int *n_added) { int count, n = n_traps; uint8_t *ptr; - + *n_added = 0; - + ptr = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); if (!ptr) return 0; ptr += offset; - + switch (type) { case GLITZ_DATA_TYPE_SHORT: - count = _glitz_add_traps_short (ptr, size, mask, traps, &n_traps); - break; + count = _glitz_add_traps_short (ptr, size, mask, traps, &n_traps); + break; case GLITZ_DATA_TYPE_INT: - count = _glitz_add_traps_int (ptr, size, mask, traps, &n_traps); - break; + count = _glitz_add_traps_int (ptr, size, mask, traps, &n_traps); + break; case GLITZ_DATA_TYPE_DOUBLE: - count = _glitz_add_traps_double (ptr, size, mask, traps, &n_traps); - break; + count = _glitz_add_traps_double (ptr, size, mask, traps, &n_traps); + break; default: - count = _glitz_add_traps_float (ptr, size, mask, traps, &n_traps); - break; + count = _glitz_add_traps_float (ptr, size, mask, traps, &n_traps); + break; } if (glitz_buffer_unmap (buffer)) - return 0; + return 0; *n_added = n - n_traps; diff --git a/src/glitz_trapimp.h b/src/glitz_trapimp.h index 6f25dfd..cdf46fb 100644 --- a/src/glitz_trapimp.h +++ b/src/glitz_trapimp.h @@ -1,6 +1,6 @@ /* * Copyright © 2005 Novell, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -25,7 +25,7 @@ /* Define the following before including this file: - + TRAPS name of function for adding trapezoids UNIT type of underlying vertex unit TRAP type of underlying trapezoid structure @@ -38,69 +38,69 @@ #define VSKIP (BYTES_PER_VERTEX / sizeof (UNIT)) #define TSKIP (BYTES_PER_VERTEX / sizeof (glitz_float_t)) -#define ADD_VERTEX(vptr, tptr, texcoord, _x, _y) \ - (vptr)[0] = (UNIT) (_x); \ - (vptr)[1] = (UNIT) (_y); \ - (tptr)[0] = (texcoord); \ - (vptr) += VSKIP; \ +#define ADD_VERTEX(vptr, tptr, texcoord, _x, _y) \ + (vptr)[0] = (UNIT) (_x); \ + (vptr)[1] = (UNIT) (_y); \ + (tptr)[0] = (texcoord); \ + (vptr) += VSKIP; \ (tptr) += TSKIP -#define ADD_QUAD(vptr, tptr, offset, size, \ - t00, t01, t10, t11, x1, y1, x2, y2) \ - if ((offset) == (size)) \ - return (toff); \ - (offset) += BYTES_PER_QUAD; \ - ADD_VERTEX (vptr, tptr, t00, x1, y1); \ - ADD_VERTEX (vptr, tptr, t01, x2, y1); \ - ADD_VERTEX (vptr, tptr, t10, x2, y2); \ +#define ADD_QUAD(vptr, tptr, offset, size, \ + t00, t01, t10, t11, x1, y1, x2, y2) \ + if ((offset) == (size)) \ + return (toff); \ + (offset) += BYTES_PER_QUAD; \ + ADD_VERTEX (vptr, tptr, t00, x1, y1); \ + ADD_VERTEX (vptr, tptr, t01, x2, y1); \ + ADD_VERTEX (vptr, tptr, t10, x2, y2); \ ADD_VERTEX (vptr, tptr, t11, x1, y2) #define ADD_PIXEL(vptr, tptr, offset, size, tmp0, tbase, tsize, \ - x1, y1, x2, y2, alpha) \ + x1, y1, x2, y2, alpha) \ (tmp0) = (tbase) + (alpha - 0.5f) * (tsize); \ ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp0, tmp0, tmp0, \ - x1, y1, x2, y2) + x1, y1, x2, y2) -#define CALC_SPAN(tmp0, tmp1, tbase, tsize, edge, end) \ - (tmp0) = (edge) - (end); \ - (tmp0) = (tbase) - (tmp0) * (tsize); \ +#define CALC_SPAN(tmp0, tmp1, tbase, tsize, edge, end) \ + (tmp0) = (edge) - (end); \ + (tmp0) = (tbase) - (tmp0) * (tsize); \ (tmp1) = (tbase) + (end) * (tsize) #define ADD_LEFT_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \ - x1, y1, x2, y2, end) \ + x1, y1, x2, y2, end) \ CALC_SPAN (tmp0, tmp1, tbase, tsize, (x2) - (x1), end); \ ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp1, tmp1, tmp0, \ - x1, y1, x2, y2) + x1, y1, x2, y2) #define ADD_RIGHT_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \ - x1, y1, x2, y2, end) \ + x1, y1, x2, y2, end) \ CALC_SPAN (tmp0, tmp1, tbase, tsize, (x2) - (x1), end); \ ADD_QUAD (vptr, tptr, offset, size, tmp1, tmp0, tmp0, tmp1, \ - x1, y1, x2, y2) + x1, y1, x2, y2) #define ADD_TOP_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \ - x1, y1, x2, y2, end) \ + x1, y1, x2, y2, end) \ CALC_SPAN (tmp0, tmp1, tbase, tsize, (y2) - (y1), end); \ ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp0, tmp1, tmp1, \ - x1, y1, x2, y2) + x1, y1, x2, y2) #define ADD_BOTTOM_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \ - x1, y1, x2, y2, end) \ + x1, y1, x2, y2, end) \ CALC_SPAN (tmp0, tmp1, tbase, tsize, (y2) - (y1), end); \ ADD_QUAD (vptr, tptr, offset, size, tmp1, tmp1, tmp0, tmp0, \ - x1, y1, x2, y2) - - -#define CALC_EDGE(tl, tr, bl, br, x1, x2, tsize, edge, tx, bx) \ - if ((edge)->hyp) \ - { \ - (edge)->hypx = (edge)->dy / \ - sqrtf ((edge)->dx * (edge)->dx + (edge)->dy * (edge)->dy); \ - (edge)->hyp = 0; \ - } \ - (tl) = (((tx) - (x1)) * (edge)->hypx) * tsize; \ - (tr) = (((tx) - (x2)) * (edge)->hypx) * tsize; \ - (bl) = (((bx) - (x1)) * (edge)->hypx) * tsize; \ + x1, y1, x2, y2) + + +#define CALC_EDGE(tl, tr, bl, br, x1, x2, tsize, edge, tx, bx) \ + if ((edge)->hyp) \ + { \ + (edge)->hypx = (edge)->dy / \ + sqrtf ((edge)->dx * (edge)->dx + (edge)->dy * (edge)->dy); \ + (edge)->hyp = 0; \ + } \ + (tl) = (((tx) - (x1)) * (edge)->hypx) * tsize; \ + (tr) = (((tx) - (x2)) * (edge)->hypx) * tsize; \ + (bl) = (((bx) - (x1)) * (edge)->hypx) * tsize; \ (br) = (((bx) - (x2)) * (edge)->hypx) * tsize #define CALC_LEFT_EDGE(tl, tr, bl, br, x1, x2, tbase, tsize, edge, tx, bx) \ @@ -118,20 +118,20 @@ (br) = (tbase) + (br) #define ADD_LEFT_EDGE(vptr, tptr, offset, size, \ - tmp0, tmp1, tmp2, tmp3, tbase, tsize, \ - edge, x1, y1, x2, y2, tx, bx) \ + tmp0, tmp1, tmp2, tmp3, tbase, tsize, \ + edge, x1, y1, x2, y2, tx, bx) \ CALC_LEFT_EDGE (tmp0, tmp1, tmp2, tmp3, x1, x2, \ - tbase, tsize, edge, tx, bx); \ + tbase, tsize, edge, tx, bx); \ ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp1, tmp3, tmp2, \ - x1, y1, x2, y2) + x1, y1, x2, y2) #define ADD_RIGHT_EDGE(vptr, tptr, offset, size, \ - tmp0, tmp1, tmp2, tmp3, tbase, tsize, \ - edge, x1, y1, x2, y2, tx, bx) \ + tmp0, tmp1, tmp2, tmp3, tbase, tsize, \ + edge, x1, y1, x2, y2, tx, bx) \ CALC_RIGHT_EDGE (tmp0, tmp1, tmp2, tmp3, x1, x2, \ - tbase, tsize, edge, tx, bx); \ + tbase, tsize, edge, tx, bx); \ ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp1, tmp3, tmp2, \ - x1, y1, x2, y2) + x1, y1, x2, y2) /* An implicit mask surface for a single anti-aliased edge that @@ -157,33 +157,33 @@ mask.type : FLOAT mask.size : COORDINATE_SIZE_X mask.offset : 2 * sizeof (type) - + Trapezoid: top { l, r, y } bottom { l, r, y } - + Bounds: x1 = floor (MIN (top.l, bottom.l)) x2 = ceil (MAX (top.r, bottom.r)) y1 = floor (top.y) y2 = ceil (bottom.y) - + W = x2 - x1; H = y2 - y1; TH = 1 if TOP rectangle exist, else 0 BH = 1 if BOTTOM rectangle exist, else 0 - + TOP rectangle exists if: floor (top.y) != top.y BOTTOM rectangle exists if: ceil (bottom.y) != bottom.y && bottom.y > ceil (top.y) MIDDLE rectangle exists if: (H - TH - BH) > 0 - - W + + W +----------------------------------------------------+ - | | + | | | TOP +---------------------------+ | TH - | / | | + | / | | +---------------/-----------------------------+------+ | / | | | MIDDLE / | | @@ -210,7 +210,7 @@ TRAPS (void *ptr, unsigned int toff = 0, offset = 0; UNIT *vptr = (UNIT *) ptr; glitz_float_t *tptr = (glitz_float_t *) (vptr + 2); - + glitz_edge_t left, right; glitz_float_t top, bottom; @@ -232,499 +232,499 @@ TRAPS (void *ptr, for (; *n_traps; (*n_traps)--, traps++) { - TRAPINIT (traps, top, bottom, &left, &right); - - /* - Top left X greater than top right X or bottom left X greater - than bottom right X. To me, this seems like an invalid trapezoid. - Cairo's current caps generation code, creates a lot of these. The - following adjustments makes them render almost correct. - */ - if (left.tx > right.tx) - { - if (floorf (left.tx) > floorf (right.tx)) - left.tx = right.tx = floorf (left.tx); - } - - if (left.bx > right.bx) - { - if (floorf (left.bx) > floorf (right.bx)) - left.bx = right.bx = floorf (left.bx); - } - - x1 = floorf (MIN (left.tx, left.bx)); - x2 = ceilf (MAX (right.tx, right.bx)); - - /* - TOP rectangle - W - +---------+---------+------------------+---------+--------+ - | | | | | | - | lE | +------+------------------|------+ | rE | - | |/ | | \| | 1 - | /| lEtE | tE | tErE |\ | - | +-+---------+------------------+---------+-+ | - +-----+---+---------+------------------+---------+--------+ - - The following set sub-rectangles might need to be generated - to render the top span of the trapezoid correctly. - - lE = Left Edge - tE = Top Edge - rE = Right Edge - lEtE = Left/Top Edge intersection - tErE = Top/Right Edge intersection - */ - y1 = ceilf (top); - if (y1 != top) - { - y0 = floorf (top); - lx = x1; - rx = x2; - - y1lx = EDGE_X (&left, y1); - y1rx = EDGE_X (&right, y1); - - if (bottom > y1) - { - l = MAX (left.tx, y1lx); - r = MIN (right.tx, y1rx); - } - else - { - l = MAX (left.tx, left.bx); - r = MIN (right.tx, right.bx); - } - - lspan = ceilf (l); - rspan = floorf (r); - - l = floorf (l); - if (l > rspan) - l = rspan; - - r = ceilf (r); - if (r < lspan) - r = lspan; - - /* Left Edge */ - if (l > x1) - { - lx = EDGE_X (&left, y0); - if (left.dx > 0.0f) - { - tmpx = y1lx + (left.tx - lx); - lx = left.tx; - } - else - { - if (bottom < y1) - { - lx += (left.bx - y1lx); - tmpx = left.bx; - } - else - tmpx = y1lx; - } - - ADD_LEFT_EDGE (vptr, tptr, offset, size, - tmp0, tmp1, tmp2, tmp3, - tbase, tsize, &left, - x1, y0, l, y1, - lx, tmpx); - - lx = l; - } - - /* Right Edge */ - if (r < x2) - { - rx = EDGE_X (&right, y0); - if (right.dx < 0.0f) - { - tmpx = y1rx - (rx - right.tx); - rx = right.tx; - } - else - { - if (bottom < y1) - { - rx -= (y1rx - right.bx); - tmpx = right.bx; - } - else - tmpx = y1rx; - } - - ADD_RIGHT_EDGE (vptr, tptr, offset, size, - tmp0, tmp1, tmp2, tmp3, - tbase, tsize, &right, - r, y0, x2, y1, - rx, tmpx); - rx = r; - } - - /* Left/Top Edge intersection */ - if (lx < l) - { - area = _glitz_pixel_area (l++, y0, - top, bottom, - &left, &right); - - ADD_LEFT_SPAN (vptr, tptr, offset, size, - tmp0, tmp1, - tbase, tsize, - lx, y0, l, y1, - area); - } - - /* Top Edge */ - while (l < r) - { - if (l < lspan || l >= rspan) - { - area = _glitz_pixel_area (l, y0, - top, bottom, - &left, &right); - - tmpx = l++; - - ADD_PIXEL (vptr, tptr, offset, size, - tmp0, - tbase, tsize, - tmpx, y0, l, y1, - area); - } - else - { - area = MIN (bottom, y1) - top; - ADD_TOP_SPAN (vptr, tptr, offset, size, - tmp0, tmp1, - tbase, tsize, - lspan, y0, rspan, y1, - area); - l = rspan; - } - } - - /* Top/Right Edge intersection */ - if (rx > r) - { - area = _glitz_pixel_area (r, y0, - top, bottom, - &left, &right); - - ADD_RIGHT_SPAN (vptr, tptr, offset, size, - tmp0, tmp1, - tbase, tsize, - r, y0, rx, y1, - area); - } - } - else - { - y1lx = EDGE_X (&left, y1); - y1rx = EDGE_X (&right, y1); - } - - /* - BOTTOM rectangle - W - +--+------+---------+------------------+---------+----+----+ - | \ | | | | / | - | \ | | | |/ | - | \| | | /| | 1 - | |\ lEbE | bE | bErE / | | - | lE | +------+------------------|----+ | rE | - | | | | | | - +---------+---------+------------------+---------+---------+ - - The following set sub-rectangles might need to be generated - to render the bottom span of the trapezoid correctly. - - lE = Left Edge - bE = Top Edge - rE = Right Edge - lEbE = Left/Bottom Edge intersection - bErE = Bottom/Right Edge intersection - */ - - y2 = floorf (bottom); - if (y2 != bottom && y2 >= y1) - { - y3 = ceilf (bottom); - lx = x1; - rx = x2; - - if (y2 > y1) - { - y2lx = EDGE_X (&left, y2); - y2rx = EDGE_X (&right, y2); - } - else - { - y2lx = y1lx; - y2rx = y1rx; - } - - l = MAX (left.bx, y2lx); - r = MIN (right.bx, y2rx); - - lspan = ceilf (l); - rspan = floorf (r); - - l = floorf (l); - if (l > rspan) - l = rspan; - - r = ceilf (r); - if (r < lspan) - r = lspan; - - /* Left Edge */ - if (l > x1) - { - lx = EDGE_X (&left, y3); - if (y2lx > left.bx) - { - tmpx = y2lx + (left.bx - lx); - lx = left.bx; - } else - tmpx = y2lx; - - ADD_LEFT_EDGE (vptr, tptr, offset, size, - tmp0, tmp1, tmp2, tmp3, - tbase, tsize, &left, - x1, y2, l, y3, - tmpx, lx); - lx = l; - } - - /* Right Edge */ - if (r < x2) - { - rx = EDGE_X (&right, y3); - if (y2rx < right.bx) - { - tmpx = y2rx - (rx - right.bx); - rx = right.bx; - } else - tmpx = y2rx; - - ADD_RIGHT_EDGE (vptr, tptr, offset, size, - tmp0, tmp1, tmp2, tmp3, - tbase, tsize, &right, - r, y2, x2, y3, - tmpx, rx); - rx = r; - } - - /* Left/Bottom Edge intersection */ - if (lx < l) - { - area = _glitz_pixel_area (l++, y2, - top, bottom, - &left, &right); - - ADD_LEFT_SPAN (vptr, tptr, offset, size, - tmp0, tmp1, - tbase, tsize, - lx, y2, l, y3, - area); - } - - /* Bottom Edge */ - while (l < r) - { - if (l < lspan || l >= rspan) - { - area = _glitz_pixel_area (l, y2, - top, bottom, - &left, &right); - - tmpx = l++; - - ADD_PIXEL (vptr, tptr, offset, size, - tmp0, - tbase, tsize, - tmpx, y2, l, y3, - area); - } - else - { - area = bottom - y2; - ADD_BOTTOM_SPAN (vptr, tptr, offset, size, - tmp0, tmp1, - tbase, tsize, - lspan, y2, rspan, y3, - area); - l = rspan; - } - } - - /* Bottom/Right Edge intersection */ - if (rx > r) - { - area = _glitz_pixel_area (r, y2, - top, bottom, - &left, &right); - - ADD_RIGHT_SPAN (vptr, tptr, offset, size, - tmp0, tmp1, - tbase, tsize, - r, y2, rx, y3, - area); - } - } - else - { - y2lx = EDGE_X (&left, y2); - y2rx = EDGE_X (&right, y2); - } - - /* - MIDDLE rectangle - W - +---+---------------------------------+--------+------+ - | \ | / | - | \ | / | - | \ lE | / rE | H - TH - BH - | \ | / | - | \ | / | - +---------+---------------------------+--+------------+ - - The following set sub-rectangles might need to be generated - to render the middle span of the trapezoid correctly. - - lE = Left Edge - rE = Right Edge - - If floor (MIN (rE)) < ceil (MAX (lE)) a number of left and right - edges needs to be generated as pixels intersected by both edges - needs to be calculated separately in a middle span. - */ - if (y1 < y2) - { - left.tx = y1lx; - right.tx = y1rx; - - do { - if (left.tx > y2rx) - { - rx = lx = ceilf (left.tx); - if (right.dx) - y = floorf (EDGE_Y (&right, rx)); - else - y = y2; - } - else - { - rx = lx = floorf (MIN (right.tx, y2rx)); - if (left.dx) - y = floorf (EDGE_Y (&left, rx)); - else - y = y2; - } - - if (y == y1) - y = y1 + 1.0f; - - if (y > y1 && y < y2) - { - left.bx = EDGE_X (&left, y); - right.bx = EDGE_X (&right, y); - } - else - { - y = y2; - left.bx = y2lx; - right.bx = y2rx; - } - - if (lx > right.tx) - lx = floorf (right.tx); - - if (lx > right.bx) - lx = floorf (right.bx); - - if (rx < left.tx) - rx = ceilf (left.tx); - - if (rx < left.bx) - rx = ceilf (left.bx); - - /* Left Edge */ - if (lx > x1) - { - if (left.dx) - { - ADD_LEFT_EDGE (vptr, tptr, offset, size, - tmp0, tmp1, tmp2, tmp3, - tbase, tsize, &left, - x1, y1, lx, y, - left.tx, left.bx); - } - else - { - area = lx - left.x0; - ADD_LEFT_SPAN (vptr, tptr, offset, size, - tmp0, tmp1, - tbase, tsize, - x1, y1, lx, y, - area); - } - } - - /* Middle Span */ - while (lx < rx) - { - tmpy = y1; - tmpx = lx++; - - while (tmpy < y) - { - y0 = tmpy++; - area = _glitz_pixel_area (tmpx, y0, - y0, y2, - &left, &right); - - ADD_PIXEL (vptr, tptr, offset, size, - tmp0, - tbase, tsize, - tmpx, y0, lx, tmpy, - area); - } - } - - /* Right Edge */ - if (rx < x2) - { - if (right.dx) - { - ADD_RIGHT_EDGE (vptr, tptr, offset, size, - tmp0, tmp1, tmp2, tmp3, - tbase, tsize, &right, - rx, y1, x2, y, - right.tx, right.bx); - } - else - { - area = right.x0 - rx; - ADD_RIGHT_SPAN (vptr, tptr, offset, size, - tmp0, tmp1, - tbase, tsize, - rx, y1, x2, y, - area); - } - } - - left.tx = left.bx; - right.tx = right.bx; - y1 = y; - } while (y < y2); - } - - toff = offset; + TRAPINIT (traps, top, bottom, &left, &right); + + /* + Top left X greater than top right X or bottom left X greater + than bottom right X. To me, this seems like an invalid trapezoid. + Cairo's current caps generation code, creates a lot of these. The + following adjustments makes them render almost correct. + */ + if (left.tx > right.tx) + { + if (floorf (left.tx) > floorf (right.tx)) + left.tx = right.tx = floorf (left.tx); + } + + if (left.bx > right.bx) + { + if (floorf (left.bx) > floorf (right.bx)) + left.bx = right.bx = floorf (left.bx); + } + + x1 = floorf (MIN (left.tx, left.bx)); + x2 = ceilf (MAX (right.tx, right.bx)); + + /* + TOP rectangle + W + +---------+---------+------------------+---------+--------+ + | | | | | | + | lE | +------+------------------|------+ | rE | + | |/ | | \| | 1 + | /| lEtE | tE | tErE |\ | + | +-+---------+------------------+---------+-+ | + +-----+---+---------+------------------+---------+--------+ + + The following set sub-rectangles might need to be generated + to render the top span of the trapezoid correctly. + + lE = Left Edge + tE = Top Edge + rE = Right Edge + lEtE = Left/Top Edge intersection + tErE = Top/Right Edge intersection + */ + y1 = ceilf (top); + if (y1 != top) + { + y0 = floorf (top); + lx = x1; + rx = x2; + + y1lx = EDGE_X (&left, y1); + y1rx = EDGE_X (&right, y1); + + if (bottom > y1) + { + l = MAX (left.tx, y1lx); + r = MIN (right.tx, y1rx); + } + else + { + l = MAX (left.tx, left.bx); + r = MIN (right.tx, right.bx); + } + + lspan = ceilf (l); + rspan = floorf (r); + + l = floorf (l); + if (l > rspan) + l = rspan; + + r = ceilf (r); + if (r < lspan) + r = lspan; + + /* Left Edge */ + if (l > x1) + { + lx = EDGE_X (&left, y0); + if (left.dx > 0.0f) + { + tmpx = y1lx + (left.tx - lx); + lx = left.tx; + } + else + { + if (bottom < y1) + { + lx += (left.bx - y1lx); + tmpx = left.bx; + } + else + tmpx = y1lx; + } + + ADD_LEFT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &left, + x1, y0, l, y1, + lx, tmpx); + + lx = l; + } + + /* Right Edge */ + if (r < x2) + { + rx = EDGE_X (&right, y0); + if (right.dx < 0.0f) + { + tmpx = y1rx - (rx - right.tx); + rx = right.tx; + } + else + { + if (bottom < y1) + { + rx -= (y1rx - right.bx); + tmpx = right.bx; + } + else + tmpx = y1rx; + } + + ADD_RIGHT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &right, + r, y0, x2, y1, + rx, tmpx); + rx = r; + } + + /* Left/Top Edge intersection */ + if (lx < l) + { + area = _glitz_pixel_area (l++, y0, + top, bottom, + &left, &right); + + ADD_LEFT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + lx, y0, l, y1, + area); + } + + /* Top Edge */ + while (l < r) + { + if (l < lspan || l >= rspan) + { + area = _glitz_pixel_area (l, y0, + top, bottom, + &left, &right); + + tmpx = l++; + + ADD_PIXEL (vptr, tptr, offset, size, + tmp0, + tbase, tsize, + tmpx, y0, l, y1, + area); + } + else + { + area = MIN (bottom, y1) - top; + ADD_TOP_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + lspan, y0, rspan, y1, + area); + l = rspan; + } + } + + /* Top/Right Edge intersection */ + if (rx > r) + { + area = _glitz_pixel_area (r, y0, + top, bottom, + &left, &right); + + ADD_RIGHT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + r, y0, rx, y1, + area); + } + } + else + { + y1lx = EDGE_X (&left, y1); + y1rx = EDGE_X (&right, y1); + } + + /* + BOTTOM rectangle + W + +--+------+---------+------------------+---------+----+----+ + | \ | | | | / | + | \ | | | |/ | + | \| | | /| | 1 + | |\ lEbE | bE | bErE / | | + | lE | +------+------------------|----+ | rE | + | | | | | | + +---------+---------+------------------+---------+---------+ + + The following set sub-rectangles might need to be generated + to render the bottom span of the trapezoid correctly. + + lE = Left Edge + bE = Top Edge + rE = Right Edge + lEbE = Left/Bottom Edge intersection + bErE = Bottom/Right Edge intersection + */ + + y2 = floorf (bottom); + if (y2 != bottom && y2 >= y1) + { + y3 = ceilf (bottom); + lx = x1; + rx = x2; + + if (y2 > y1) + { + y2lx = EDGE_X (&left, y2); + y2rx = EDGE_X (&right, y2); + } + else + { + y2lx = y1lx; + y2rx = y1rx; + } + + l = MAX (left.bx, y2lx); + r = MIN (right.bx, y2rx); + + lspan = ceilf (l); + rspan = floorf (r); + + l = floorf (l); + if (l > rspan) + l = rspan; + + r = ceilf (r); + if (r < lspan) + r = lspan; + + /* Left Edge */ + if (l > x1) + { + lx = EDGE_X (&left, y3); + if (y2lx > left.bx) + { + tmpx = y2lx + (left.bx - lx); + lx = left.bx; + } else + tmpx = y2lx; + + ADD_LEFT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &left, + x1, y2, l, y3, + tmpx, lx); + lx = l; + } + + /* Right Edge */ + if (r < x2) + { + rx = EDGE_X (&right, y3); + if (y2rx < right.bx) + { + tmpx = y2rx - (rx - right.bx); + rx = right.bx; + } else + tmpx = y2rx; + + ADD_RIGHT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &right, + r, y2, x2, y3, + tmpx, rx); + rx = r; + } + + /* Left/Bottom Edge intersection */ + if (lx < l) + { + area = _glitz_pixel_area (l++, y2, + top, bottom, + &left, &right); + + ADD_LEFT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + lx, y2, l, y3, + area); + } + + /* Bottom Edge */ + while (l < r) + { + if (l < lspan || l >= rspan) + { + area = _glitz_pixel_area (l, y2, + top, bottom, + &left, &right); + + tmpx = l++; + + ADD_PIXEL (vptr, tptr, offset, size, + tmp0, + tbase, tsize, + tmpx, y2, l, y3, + area); + } + else + { + area = bottom - y2; + ADD_BOTTOM_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + lspan, y2, rspan, y3, + area); + l = rspan; + } + } + + /* Bottom/Right Edge intersection */ + if (rx > r) + { + area = _glitz_pixel_area (r, y2, + top, bottom, + &left, &right); + + ADD_RIGHT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + r, y2, rx, y3, + area); + } + } + else + { + y2lx = EDGE_X (&left, y2); + y2rx = EDGE_X (&right, y2); + } + + /* + MIDDLE rectangle + W + +---+---------------------------------+--------+------+ + | \ | / | + | \ | / | + | \ lE | / rE | H - TH - BH + | \ | / | + | \ | / | + +---------+---------------------------+--+------------+ + + The following set sub-rectangles might need to be generated + to render the middle span of the trapezoid correctly. + + lE = Left Edge + rE = Right Edge + + If floor (MIN (rE)) < ceil (MAX (lE)) a number of left and right + edges needs to be generated as pixels intersected by both edges + needs to be calculated separately in a middle span. + */ + if (y1 < y2) + { + left.tx = y1lx; + right.tx = y1rx; + + do { + if (left.tx > y2rx) + { + rx = lx = ceilf (left.tx); + if (right.dx) + y = floorf (EDGE_Y (&right, rx)); + else + y = y2; + } + else + { + rx = lx = floorf (MIN (right.tx, y2rx)); + if (left.dx) + y = floorf (EDGE_Y (&left, rx)); + else + y = y2; + } + + if (y == y1) + y = y1 + 1.0f; + + if (y > y1 && y < y2) + { + left.bx = EDGE_X (&left, y); + right.bx = EDGE_X (&right, y); + } + else + { + y = y2; + left.bx = y2lx; + right.bx = y2rx; + } + + if (lx > right.tx) + lx = floorf (right.tx); + + if (lx > right.bx) + lx = floorf (right.bx); + + if (rx < left.tx) + rx = ceilf (left.tx); + + if (rx < left.bx) + rx = ceilf (left.bx); + + /* Left Edge */ + if (lx > x1) + { + if (left.dx) + { + ADD_LEFT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &left, + x1, y1, lx, y, + left.tx, left.bx); + } + else + { + area = lx - left.x0; + ADD_LEFT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + x1, y1, lx, y, + area); + } + } + + /* Middle Span */ + while (lx < rx) + { + tmpy = y1; + tmpx = lx++; + + while (tmpy < y) + { + y0 = tmpy++; + area = _glitz_pixel_area (tmpx, y0, + y0, y2, + &left, &right); + + ADD_PIXEL (vptr, tptr, offset, size, + tmp0, + tbase, tsize, + tmpx, y0, lx, tmpy, + area); + } + } + + /* Right Edge */ + if (rx < x2) + { + if (right.dx) + { + ADD_RIGHT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &right, + rx, y1, x2, y, + right.tx, right.bx); + } + else + { + area = right.x0 - rx; + ADD_RIGHT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + rx, y1, x2, y, + area); + } + } + + left.tx = left.bx; + right.tx = right.bx; + y1 = y; + } while (y < y2); + } + + toff = offset; } return toff; diff --git a/src/glitz_util.c b/src/glitz_util.c index 369dbe9..3a2bb6a 100644 --- a/src/glitz_util.c +++ b/src/glitz_util.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -33,335 +33,369 @@ #include <string.h> static glitz_extension_map gl_extensions[] = { - { 0.0, "GL_ARB_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_EXT_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_NV_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_ARB_texture_non_power_of_two", - GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK }, - { 0.0, "GL_ARB_texture_mirrored_repeat", - GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK }, - { 0.0, "GL_ARB_texture_border_clamp", - GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK }, - { 0.0, "GL_ARB_texture_env_combine", - GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK }, - { 0.0, "GL_EXT_texture_env_combine", - GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK }, - { 0.0, "GL_ARB_texture_env_dot3", GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK }, - { 0.0, "GL_ARB_multisample", GLITZ_FEATURE_MULTISAMPLE_MASK }, - { 0.0, "GL_NV_multisample_filter_hint", - GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK }, - { 0.0, "GL_ARB_multitexture", GLITZ_FEATURE_MULTITEXTURE_MASK }, - { 0.0, "GL_EXT_multi_draw_arrays", GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK }, - { 0.0, "GL_ARB_fragment_program", GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK }, - { 0.0, "GL_ARB_vertex_buffer_object", - GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK }, - { 0.0, "GL_ARB_pixel_buffer_object", - GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK }, - { 0.0, "GL_EXT_pixel_buffer_object", - GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK }, - { 0.0, "GL_EXT_blend_color", GLITZ_FEATURE_BLEND_COLOR_MASK }, - { 0.0, "GL_ARB_imaging", GLITZ_FEATURE_BLEND_COLOR_MASK }, - { 0.0, "GL_APPLE_packed_pixels", GLITZ_FEATURE_PACKED_PIXELS_MASK }, - { 0.0, "GL_EXT_framebuffer_object", GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK }, - { 0.0, NULL, 0 } + { 0.0, "GL_ARB_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_EXT_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_NV_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_ARB_texture_non_power_of_two", + GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK }, + { 0.0, "GL_ARB_texture_mirrored_repeat", + GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK }, + { 0.0, "GL_ARB_texture_border_clamp", + GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK }, + { 0.0, "GL_ARB_texture_env_combine", + GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK }, + { 0.0, "GL_EXT_texture_env_combine", + GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK }, + { 0.0, "GL_ARB_texture_env_dot3", GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK }, + { 0.0, "GL_ARB_multisample", GLITZ_FEATURE_MULTISAMPLE_MASK }, + { 0.0, "GL_NV_multisample_filter_hint", + GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK }, + { 0.0, "GL_ARB_multitexture", GLITZ_FEATURE_MULTITEXTURE_MASK }, + { 0.0, "GL_EXT_multi_draw_arrays", GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK }, + { 0.0, "GL_ARB_fragment_program", GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK }, + { 0.0, "GL_ARB_vertex_buffer_object", + GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK }, + { 0.0, "GL_ARB_pixel_buffer_object", + GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK }, + { 0.0, "GL_EXT_pixel_buffer_object", + GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK }, + { 0.0, "GL_EXT_blend_color", GLITZ_FEATURE_BLEND_COLOR_MASK }, + { 0.0, "GL_ARB_imaging", GLITZ_FEATURE_BLEND_COLOR_MASK }, + { 0.0, "GL_APPLE_packed_pixels", GLITZ_FEATURE_PACKED_PIXELS_MASK }, + { 0.0, "GL_EXT_framebuffer_object", + GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK }, + { 0.0, NULL, 0 } }; static glitz_bool_t _glitz_extension_check (const char *extensions, - const char *ext_name) + const char *ext_name) { - char *end; - char *p = (char *) extensions; - int ext_name_len = strlen (ext_name); + char *end; + char *p = (char *) extensions; + int ext_name_len = strlen (ext_name); - if (! p) - return 0; + if (! p) + return 0; - end = p + strlen (p); + end = p + strlen (p); - while (p < end) { - int n = strcspn (p, " "); + while (p < end) { + int n = strcspn (p, " "); - if ((ext_name_len == n) && (strncmp (ext_name, p, n) == 0)) { - return 1; + if ((ext_name_len == n) && (strncmp (ext_name, p, n) == 0)) { + return 1; + } + p += (n + 1); } - p += (n + 1); - } - return 0; + return 0; } unsigned long glitz_extensions_query (glitz_gl_float_t version, - const char *extensions_string, - glitz_extension_map *extensions_map) + const char *extensions_string, + glitz_extension_map *extensions_map) { - unsigned long mask = 0; - int i; + unsigned long mask = 0; + int i; - for (i = 0; extensions_map[i].name; i++) - if (((extensions_map[i].version > 1.0) && - (version >= extensions_map[i].version)) || - _glitz_extension_check (extensions_string, extensions_map[i].name)) - mask |= extensions_map[i].mask; + for (i = 0; extensions_map[i].name; i++) + if (((extensions_map[i].version > 1.0) && + (version >= extensions_map[i].version)) || + _glitz_extension_check (extensions_string, extensions_map[i].name)) + mask |= extensions_map[i].mask; - return mask; + return mask; } static glitz_status_t _glitz_query_gl_extensions (glitz_gl_proc_address_list_t *gl, - glitz_gl_float_t *gl_version, - unsigned long *feature_mask) + glitz_gl_float_t *gl_version, + unsigned long *feature_mask) { - const char *gl_extensions_string; - - *gl_version = atof ((const char *) gl->get_string (GLITZ_GL_VERSION)); - if (*gl_version < 1.2f) - return GLITZ_STATUS_NOT_SUPPORTED; - - gl_extensions_string = (const char *) gl->get_string (GLITZ_GL_EXTENSIONS); - - *feature_mask = glitz_extensions_query (*gl_version, - gl_extensions_string, - gl_extensions); - - if ((*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) && - (*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK)) { - glitz_gl_int_t max_texture_units; - - gl->get_integer_v (GLITZ_GL_MAX_TEXTURE_UNITS, &max_texture_units); - if (max_texture_units >= 3) - *feature_mask |= GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; - } - - return GLITZ_STATUS_SUCCESS; + const char *gl_extensions_string; + + *gl_version = atof ((const char *) gl->get_string (GLITZ_GL_VERSION)); + if (*gl_version < 1.2f) + return GLITZ_STATUS_NOT_SUPPORTED; + + gl_extensions_string = (const char *) gl->get_string (GLITZ_GL_EXTENSIONS); + + *feature_mask = glitz_extensions_query (*gl_version, + gl_extensions_string, + gl_extensions); + + if ((*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) && + (*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK)) { + glitz_gl_int_t max_texture_units; + + gl->get_integer_v (GLITZ_GL_MAX_TEXTURE_UNITS, &max_texture_units); + if (max_texture_units >= 3) + *feature_mask |= GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; + } + + return GLITZ_STATUS_SUCCESS; } static void _glitz_gl_proc_address_lookup (glitz_backend_t *backend, - glitz_get_proc_address_proc_t get_proc_address, - void *closure) + glitz_get_proc_address_proc_t get_proc_address, + void *closure) { - if (backend->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) { - if (backend->gl_version >= 1.4f) { - backend->gl.blend_color = (glitz_gl_blend_color_t) - get_proc_address ("glBlendColor", closure); - } else { - backend->gl.blend_color = (glitz_gl_blend_color_t) - get_proc_address ("glBlendColorEXT", closure); + if (backend->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) { + if (backend->gl_version >= 1.4f) { + backend->gl->blend_color = (glitz_gl_blend_color_t) + get_proc_address ("glBlendColor", closure); + } else { + backend->gl->blend_color = (glitz_gl_blend_color_t) + get_proc_address ("glBlendColorEXT", closure); + } + + if (!backend->gl->blend_color) + backend->feature_mask &= ~GLITZ_FEATURE_BLEND_COLOR_MASK; + } + + if (backend->feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK) { + if (backend->gl_version >= 1.3f) { + backend->gl->active_texture = (glitz_gl_active_texture_t) + get_proc_address ("glActiveTexture", closure); + backend->gl->client_active_texture = + (glitz_gl_client_active_texture_t) + get_proc_address ("glClientActiveTexture", closure); + } else { + backend->gl->active_texture = (glitz_gl_active_texture_t) + get_proc_address ("glActiveTextureARB", closure); + backend->gl->client_active_texture = + (glitz_gl_client_active_texture_t) + get_proc_address ("glClientActiveTextureARB", closure); + } + + if ((!backend->gl->active_texture) || + (!backend->gl->client_active_texture)) { + backend->feature_mask &= ~GLITZ_FEATURE_MULTITEXTURE_MASK; + backend->feature_mask &= + ~GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; + } } - if (!backend->gl.blend_color) - backend->feature_mask &= ~GLITZ_FEATURE_BLEND_COLOR_MASK; - } - - if (backend->feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK) { - if (backend->gl_version >= 1.3f) { - backend->gl.active_texture = (glitz_gl_active_texture_t) - get_proc_address ("glActiveTexture", closure); - backend->gl.client_active_texture = (glitz_gl_client_active_texture_t) - get_proc_address ("glClientActiveTexture", closure); - } else { - backend->gl.active_texture = (glitz_gl_active_texture_t) - get_proc_address ("glActiveTextureARB", closure); - backend->gl.client_active_texture = (glitz_gl_client_active_texture_t) - get_proc_address ("glClientActiveTextureARB", closure); + if (backend->feature_mask & GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK) { + backend->gl->multi_draw_arrays = (glitz_gl_multi_draw_arrays_t) + get_proc_address ("glMultiDrawArraysEXT", closure); + + if (!backend->gl->multi_draw_arrays) + backend->feature_mask &= ~GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK; } - if ((!backend->gl.active_texture) || - (!backend->gl.client_active_texture)) { - backend->feature_mask &= ~GLITZ_FEATURE_MULTITEXTURE_MASK; - backend->feature_mask &= ~GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; + if (backend->feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) { + backend->gl->gen_programs = (glitz_gl_gen_programs_t) + get_proc_address ("glGenProgramsARB", closure); + backend->gl->delete_programs = (glitz_gl_delete_programs_t) + get_proc_address ("glDeleteProgramsARB", closure); + backend->gl->program_string = (glitz_gl_program_string_t) + get_proc_address ("glProgramStringARB", closure); + backend->gl->bind_program = (glitz_gl_bind_program_t) + get_proc_address ("glBindProgramARB", closure); + backend->gl->program_local_param_4fv = + (glitz_gl_program_local_param_4fv_t) + get_proc_address ("glProgramLocalParameter4fvARB", closure); + backend->gl->get_program_iv = (glitz_gl_get_program_iv_t) + get_proc_address ("glGetProgramivARB", closure); + + if ((!backend->gl->gen_programs) || + (!backend->gl->delete_programs) || + (!backend->gl->program_string) || + (!backend->gl->bind_program) || + (!backend->gl->program_local_param_4fv)) + backend->feature_mask &= ~GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK; } - } - - if (backend->feature_mask & GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK) { - backend->gl.multi_draw_arrays = (glitz_gl_multi_draw_arrays_t) - get_proc_address ("glMultiDrawArraysEXT", closure); - - if (!backend->gl.multi_draw_arrays) - backend->feature_mask &= ~GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK; - } - - if (backend->feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) { - backend->gl.gen_programs = (glitz_gl_gen_programs_t) - get_proc_address ("glGenProgramsARB", closure); - backend->gl.delete_programs = (glitz_gl_delete_programs_t) - get_proc_address ("glDeleteProgramsARB", closure); - backend->gl.program_string = (glitz_gl_program_string_t) - get_proc_address ("glProgramStringARB", closure); - backend->gl.bind_program = (glitz_gl_bind_program_t) - get_proc_address ("glBindProgramARB", closure); - backend->gl.program_local_param_4fv = (glitz_gl_program_local_param_4fv_t) - get_proc_address ("glProgramLocalParameter4fvARB", closure); - backend->gl.get_program_iv = (glitz_gl_get_program_iv_t) - get_proc_address ("glGetProgramivARB", closure); - - if ((!backend->gl.gen_programs) || - (!backend->gl.delete_programs) || - (!backend->gl.program_string) || - (!backend->gl.bind_program) || - (!backend->gl.program_local_param_4fv)) - backend->feature_mask &= ~GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK; - } - - if ((backend->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) || - (backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)) { - if (backend->gl_version >= 1.5f) { - backend->gl.gen_buffers = (glitz_gl_gen_buffers_t) - get_proc_address ("glGenBuffers", closure); - backend->gl.delete_buffers = (glitz_gl_delete_buffers_t) - get_proc_address ("glDeleteBuffers", closure); - backend->gl.bind_buffer = (glitz_gl_bind_buffer_t) - get_proc_address ("glBindBuffer", closure); - backend->gl.buffer_data = (glitz_gl_buffer_data_t) - get_proc_address ("glBufferData", closure); - backend->gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t) - get_proc_address ("glBufferSubData", closure); - backend->gl.get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t) - get_proc_address ("glGetBufferSubData", closure); - backend->gl.map_buffer = (glitz_gl_map_buffer_t) - get_proc_address ("glMapBuffer", closure); - backend->gl.unmap_buffer = (glitz_gl_unmap_buffer_t) - get_proc_address ("glUnmapBuffer", closure); - } else { - backend->gl.gen_buffers = (glitz_gl_gen_buffers_t) - get_proc_address ("glGenBuffersARB", closure); - backend->gl.delete_buffers = (glitz_gl_delete_buffers_t) - get_proc_address ("glDeleteBuffersARB", closure); - backend->gl.bind_buffer = (glitz_gl_bind_buffer_t) - get_proc_address ("glBindBufferARB", closure); - backend->gl.buffer_data = (glitz_gl_buffer_data_t) - get_proc_address ("glBufferDataARB", closure); - backend->gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t) - get_proc_address ("glBufferSubDataARB", closure); - backend->gl.get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t) - get_proc_address ("glGetBufferSubDataARB", closure); - backend->gl.map_buffer = (glitz_gl_map_buffer_t) - get_proc_address ("glMapBufferARB", closure); - backend->gl.unmap_buffer = (glitz_gl_unmap_buffer_t) - get_proc_address ("glUnmapBufferARB", closure); + + if ((backend->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) || + (backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)) { + if (backend->gl_version >= 1.5f) { + backend->gl->gen_buffers = (glitz_gl_gen_buffers_t) + get_proc_address ("glGenBuffers", closure); + backend->gl->delete_buffers = (glitz_gl_delete_buffers_t) + get_proc_address ("glDeleteBuffers", closure); + backend->gl->bind_buffer = (glitz_gl_bind_buffer_t) + get_proc_address ("glBindBuffer", closure); + backend->gl->buffer_data = (glitz_gl_buffer_data_t) + get_proc_address ("glBufferData", closure); + backend->gl->buffer_sub_data = (glitz_gl_buffer_sub_data_t) + get_proc_address ("glBufferSubData", closure); + backend->gl->get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t) + get_proc_address ("glGetBufferSubData", closure); + backend->gl->map_buffer = (glitz_gl_map_buffer_t) + get_proc_address ("glMapBuffer", closure); + backend->gl->unmap_buffer = (glitz_gl_unmap_buffer_t) + get_proc_address ("glUnmapBuffer", closure); + } else { + backend->gl->gen_buffers = (glitz_gl_gen_buffers_t) + get_proc_address ("glGenBuffersARB", closure); + backend->gl->delete_buffers = (glitz_gl_delete_buffers_t) + get_proc_address ("glDeleteBuffersARB", closure); + backend->gl->bind_buffer = (glitz_gl_bind_buffer_t) + get_proc_address ("glBindBufferARB", closure); + backend->gl->buffer_data = (glitz_gl_buffer_data_t) + get_proc_address ("glBufferDataARB", closure); + backend->gl->buffer_sub_data = (glitz_gl_buffer_sub_data_t) + get_proc_address ("glBufferSubDataARB", closure); + backend->gl->get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t) + get_proc_address ("glGetBufferSubDataARB", closure); + backend->gl->map_buffer = (glitz_gl_map_buffer_t) + get_proc_address ("glMapBufferARB", closure); + backend->gl->unmap_buffer = (glitz_gl_unmap_buffer_t) + get_proc_address ("glUnmapBufferARB", closure); + } + + if ((!backend->gl->gen_buffers) || + (!backend->gl->delete_buffers) || + (!backend->gl->bind_buffer) || + (!backend->gl->buffer_data) || + (!backend->gl->buffer_sub_data) || + (!backend->gl->get_buffer_sub_data) || + (!backend->gl->map_buffer) || + (!backend->gl->unmap_buffer)) { + backend->feature_mask &= ~GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK; + backend->feature_mask &= ~GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK; + } } - if ((!backend->gl.gen_buffers) || - (!backend->gl.delete_buffers) || - (!backend->gl.bind_buffer) || - (!backend->gl.buffer_data) || - (!backend->gl.buffer_sub_data) || - (!backend->gl.get_buffer_sub_data) || - (!backend->gl.map_buffer) || - (!backend->gl.unmap_buffer)) { - backend->feature_mask &= ~GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK; - backend->feature_mask &= ~GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK; + if (backend->feature_mask & GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) { + backend->gl->gen_framebuffers = (glitz_gl_gen_framebuffers_t) + get_proc_address ("glGenFramebuffersEXT", closure); + backend->gl->delete_framebuffers = (glitz_gl_delete_framebuffers_t) + get_proc_address ("glDeleteFramebuffersEXT", closure); + backend->gl->bind_framebuffer = (glitz_gl_bind_framebuffer_t) + get_proc_address ("glBindFramebufferEXT", closure); + backend->gl->framebuffer_renderbuffer = + (glitz_gl_framebuffer_renderbuffer_t) + get_proc_address ("glFramebufferRenderbufferEXT", closure); + backend->gl->framebuffer_texture_2d = + (glitz_gl_framebuffer_texture_2d_t) + get_proc_address ("glFramebufferTexture2DEXT", closure); + backend->gl->check_framebuffer_status = + (glitz_gl_check_framebuffer_status_t) + get_proc_address ("glCheckFramebufferStatusEXT", closure); + backend->gl->gen_renderbuffers = (glitz_gl_gen_renderbuffers_t) + get_proc_address ("glGenRenderbuffersEXT", closure); + backend->gl->delete_renderbuffers = (glitz_gl_delete_renderbuffers_t) + get_proc_address ("glDeleteRenderbuffersEXT", closure); + backend->gl->bind_renderbuffer = (glitz_gl_bind_renderbuffer_t) + get_proc_address ("glBindRenderbufferEXT", closure); + backend->gl->renderbuffer_storage = (glitz_gl_renderbuffer_storage_t) + get_proc_address ("glRenderbufferStorageEXT", closure); + backend->gl->get_renderbuffer_parameter_iv = + (glitz_gl_get_renderbuffer_parameter_iv_t) + get_proc_address ("glGetRenderbufferParameterivEXT", closure); + + if ((!backend->gl->gen_framebuffers) || + (!backend->gl->delete_framebuffers) || + (!backend->gl->bind_framebuffer) || + (!backend->gl->framebuffer_renderbuffer) || + (!backend->gl->framebuffer_texture_2d) || + (!backend->gl->check_framebuffer_status) || + (!backend->gl->gen_renderbuffers) || + (!backend->gl->delete_renderbuffers) || + (!backend->gl->bind_renderbuffer) || + (!backend->gl->renderbuffer_storage) || + (!backend->gl->get_renderbuffer_parameter_iv)) + backend->feature_mask &= ~GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK; } - } - - if (backend->feature_mask & GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) { - backend->gl.gen_framebuffers = (glitz_gl_gen_framebuffers_t) - get_proc_address ("glGenFramebuffersEXT", closure); - backend->gl.delete_framebuffers = (glitz_gl_delete_framebuffers_t) - get_proc_address ("glDeleteFramebuffersEXT", closure); - backend->gl.bind_framebuffer = (glitz_gl_bind_framebuffer_t) - get_proc_address ("glBindFramebufferEXT", closure); - backend->gl.check_framebuffer_status = - (glitz_gl_check_framebuffer_status_t) - get_proc_address ("glCheckFramebufferStatusEXT", closure); - backend->gl.framebuffer_texture_2d = (glitz_gl_framebuffer_texture_2d_t) - get_proc_address ("glFramebufferTexture2DEXT", closure); - - if ((!backend->gl.gen_framebuffers) || - (!backend->gl.delete_framebuffers) || - (!backend->gl.bind_framebuffer) || - (!backend->gl.check_framebuffer_status) || - (!backend->gl.framebuffer_texture_2d)) - backend->feature_mask &= ~GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK; - } } void glitz_backend_init (glitz_backend_t *backend, - glitz_get_proc_address_proc_t get_proc_address, - void *closure) + glitz_get_proc_address_proc_t get_proc_address, + void *closure) { - if (!_glitz_query_gl_extensions (&backend->gl, - &backend->gl_version, - &backend->feature_mask)) { - _glitz_gl_proc_address_lookup (backend, get_proc_address, closure); - glitz_create_surface_formats (&backend->gl, - &backend->formats, - &backend->texture_formats, - &backend->n_formats); - } - - backend->gl.get_integer_v (GLITZ_GL_MAX_TEXTURE_SIZE, - &backend->max_texture_2d_size); - - if (backend->feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) - backend->gl.get_integer_v (GLITZ_GL_MAX_RECTANGLE_TEXTURE_SIZE, - &backend->max_texture_rect_size); - else - backend->max_texture_rect_size = 0; + if (!_glitz_query_gl_extensions (backend->gl, + &backend->gl_version, + &backend->feature_mask)) { + _glitz_gl_proc_address_lookup (backend, get_proc_address, closure); + glitz_create_surface_formats (backend->gl, + &backend->formats, + &backend->texture_formats, + &backend->n_formats); + _glitz_add_drawable_formats (backend->gl, + backend->feature_mask, + &backend->drawable_formats, + &backend->n_drawable_formats); + } + + backend->gl->get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS, + backend->max_viewport_dims); + + backend->gl->get_integer_v (GLITZ_GL_MAX_TEXTURE_SIZE, + &backend->max_texture_2d_size); + + if (backend->feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) + backend->gl->get_integer_v (GLITZ_GL_MAX_RECTANGLE_TEXTURE_SIZE, + &backend->max_texture_rect_size); + else + backend->max_texture_rect_size = 0; } unsigned int glitz_uint_to_power_of_two (unsigned int x) { - x |= (x >> 1); - x |= (x >> 2); - x |= (x >> 4); - x |= (x >> 8); - x |= (x >> 16); - - return (x + 1); + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + + return (x + 1); } void glitz_set_raster_pos (glitz_gl_proc_address_list_t *gl, - glitz_float_t x, - glitz_float_t y) + glitz_float_t x, + glitz_float_t y) { - gl->push_attrib (GLITZ_GL_TRANSFORM_BIT | GLITZ_GL_VIEWPORT_BIT); - gl->matrix_mode (GLITZ_GL_PROJECTION); - gl->push_matrix (); - gl->load_identity (); - gl->matrix_mode (GLITZ_GL_MODELVIEW); - gl->push_matrix (); - gl->load_identity (); - gl->depth_range (0, 1); - gl->viewport (-1, -1, 2, 2); - - gl->raster_pos_2f (0, 0); - gl->bitmap (0, 0, 1, 1, x, y, NULL); - - gl->pop_matrix (); - gl->matrix_mode (GLITZ_GL_PROJECTION); - gl->pop_matrix (); - gl->pop_attrib (); + gl->push_attrib (GLITZ_GL_TRANSFORM_BIT | GLITZ_GL_VIEWPORT_BIT); + gl->matrix_mode (GLITZ_GL_PROJECTION); + gl->push_matrix (); + gl->load_identity (); + gl->matrix_mode (GLITZ_GL_MODELVIEW); + gl->push_matrix (); + gl->load_identity (); + gl->depth_range (0, 1); + gl->viewport (-1, -1, 2, 2); + + gl->raster_pos_2f (0, 0); + gl->bitmap (0, 0, 1, 1, x, y, NULL); + + gl->pop_matrix (); + gl->matrix_mode (GLITZ_GL_PROJECTION); + gl->pop_matrix (); + gl->pop_attrib (); } void glitz_clamp_value (glitz_float_t *value, - glitz_float_t min, glitz_float_t max) + glitz_float_t min, glitz_float_t max) { - if (*value < min) - *value = min; - else if (*value > max) - *value = max; + if (*value < min) + *value = min; + else if (*value > max) + *value = max; } void glitz_initiate_state (glitz_gl_proc_address_list_t *gl) { - gl->hint (GLITZ_GL_PERSPECTIVE_CORRECTION_HINT, GLITZ_GL_FASTEST); - gl->disable (GLITZ_GL_CULL_FACE); - gl->depth_mask (GLITZ_GL_FALSE); - gl->polygon_mode (GLITZ_GL_FRONT_AND_BACK, GLITZ_GL_FILL); - gl->disable (GLITZ_GL_POLYGON_SMOOTH); - gl->disable (GLITZ_GL_LINE_SMOOTH); - gl->disable (GLITZ_GL_POINT_SMOOTH); - gl->shade_model (GLITZ_GL_FLAT); - gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE); - gl->enable (GLITZ_GL_SCISSOR_TEST); - gl->disable (GLITZ_GL_STENCIL_TEST); - gl->enable_client_state (GLITZ_GL_VERTEX_ARRAY); - gl->disable (GLITZ_GL_DEPTH_TEST); + gl->hint (GLITZ_GL_PERSPECTIVE_CORRECTION_HINT, GLITZ_GL_FASTEST); + gl->disable (GLITZ_GL_CULL_FACE); + gl->depth_mask (GLITZ_GL_FALSE); + gl->polygon_mode (GLITZ_GL_FRONT_AND_BACK, GLITZ_GL_FILL); + gl->disable (GLITZ_GL_POLYGON_SMOOTH); + gl->disable (GLITZ_GL_LINE_SMOOTH); + gl->disable (GLITZ_GL_POINT_SMOOTH); + gl->shade_model (GLITZ_GL_FLAT); + gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_TRUE, + GLITZ_GL_TRUE, GLITZ_GL_TRUE); + gl->enable (GLITZ_GL_SCISSOR_TEST); + gl->disable (GLITZ_GL_STENCIL_TEST); + gl->enable_client_state (GLITZ_GL_VERTEX_ARRAY); + gl->disable (GLITZ_GL_DEPTH_TEST); } diff --git a/src/glitzint.h b/src/glitzint.h index 54fa891..7a619de 100644 --- a/src/glitzint.h +++ b/src/glitzint.h @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -88,7 +88,7 @@ #define GLITZ_CONTEXT_STACK_SIZE 16 typedef struct _glitz_gl_proc_address_list_t { - + /* core */ glitz_gl_enable_t enable; glitz_gl_disable_t disable; @@ -145,6 +145,7 @@ typedef struct _glitz_gl_proc_address_list_t { glitz_gl_bind_texture_t bind_texture; glitz_gl_tex_image_2d_t tex_image_2d; glitz_gl_tex_parameter_i_t tex_parameter_i; + glitz_gl_tex_parameter_fv_t tex_parameter_fv; glitz_gl_get_tex_level_parameter_iv_t get_tex_level_parameter_iv; glitz_gl_copy_tex_sub_image_2d_t copy_tex_sub_image_2d; glitz_gl_get_integer_v_t get_integer_v; @@ -171,8 +172,14 @@ typedef struct _glitz_gl_proc_address_list_t { glitz_gl_gen_framebuffers_t gen_framebuffers; glitz_gl_delete_framebuffers_t delete_framebuffers; glitz_gl_bind_framebuffer_t bind_framebuffer; - glitz_gl_check_framebuffer_status_t check_framebuffer_status; + glitz_gl_framebuffer_renderbuffer_t framebuffer_renderbuffer; glitz_gl_framebuffer_texture_2d_t framebuffer_texture_2d; + glitz_gl_check_framebuffer_status_t check_framebuffer_status; + glitz_gl_gen_renderbuffers_t gen_renderbuffers; + glitz_gl_delete_renderbuffers_t delete_renderbuffers; + glitz_gl_bind_renderbuffer_t bind_renderbuffer; + glitz_gl_renderbuffer_storage_t renderbuffer_storage; + glitz_gl_get_renderbuffer_parameter_iv_t get_renderbuffer_parameter_iv; } glitz_gl_proc_address_list_t; typedef int glitz_surface_type_t; @@ -307,52 +314,81 @@ typedef struct _glitz_region_t { extern glitz_status_t __internal_linkage glitz_region_union (glitz_region_t *region, - glitz_box_t *box); + glitz_box_t *box); + +#define GLITZ_DRAWABLE_TYPE_WINDOW_MASK (1L << 0) +#define GLITZ_DRAWABLE_TYPE_PBUFFER_MASK (1L << 1) +#define GLITZ_DRAWABLE_TYPE_FBO_MASK (1L << 2) + +#define GLITZ_INT_FORMAT_WINDOW_MASK (1L << 17) +#define GLITZ_INT_FORMAT_PBUFFER_MASK (1L << 18) +#define GLITZ_INT_FORMAT_FBO_MASK (1L << 19) + +typedef struct _glitz_int_drawable_format_t { + glitz_drawable_format_t d; + unsigned int types; + int caveat; + union { + void *ptr; + long val; + unsigned long uval; + void *(*fptr) (void); + } u; +} glitz_int_drawable_format_t; typedef struct glitz_backend { glitz_drawable_t * (*create_pbuffer) (void *drawable, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height); - + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); + void (*destroy) (void *drawable); - void + glitz_bool_t (*push_current) (void *drawable, - glitz_surface_t *surface, - glitz_constraint_t constraint); + glitz_surface_t *surface, + glitz_constraint_t constraint); glitz_surface_t * (*pop_current) (void *drawable); void + (*attach_notify) (void *drawable, + glitz_surface_t *surface); + + void + (*detach_notify) (void *drawable, + glitz_surface_t *surface); + + glitz_bool_t (*swap_buffers) (void *drawable); + glitz_context_t * (*create_context) (void *drawable, - glitz_drawable_format_t *format); + glitz_drawable_format_t *format); void (*destroy_context) (void *context); void (*copy_context) (void *src, - void *dst, - unsigned long mask); + void *dst, + unsigned long mask); void - (*make_current) (void *context, - void *drawable); + (*make_current) (void *drawable, + void *context); glitz_function_pointer_t (*get_proc_address) (void *context, - const char *name); + const char *name); + + glitz_gl_proc_address_list_t *gl; - glitz_gl_proc_address_list_t gl; - - glitz_drawable_format_t *drawable_formats; + glitz_int_drawable_format_t *drawable_formats; int n_drawable_formats; glitz_gl_int_t *texture_formats; @@ -360,25 +396,30 @@ typedef struct glitz_backend { int n_formats; glitz_gl_float_t gl_version; + glitz_gl_int_t max_viewport_dims[2]; glitz_gl_int_t max_texture_2d_size; glitz_gl_int_t max_texture_rect_size; unsigned long feature_mask; - + glitz_program_map_t *program_map; } glitz_backend_t; struct _glitz_drawable { - glitz_backend_t *backend; - - int ref_count; - glitz_drawable_format_t *format; - int width, height; - glitz_rectangle_t viewport; - glitz_bool_t update_all; + glitz_backend_t *backend; + int ref_count; + glitz_int_drawable_format_t *format; + int width, height; + glitz_rectangle_t viewport; + glitz_bool_t update_all; + glitz_surface_t *front; + glitz_surface_t *back; }; #define GLITZ_GL_DRAWABLE(drawable) \ - glitz_gl_proc_address_list_t *gl = &(drawable)->backend->gl; + glitz_gl_proc_address_list_t *gl = (drawable)->backend->gl; + +#define DRAWABLE_IS_FBO(drawable) \ + ((drawable)->format->types == GLITZ_DRAWABLE_TYPE_FBO_MASK) typedef struct _glitz_vec2_t { glitz_float_t v[2]; @@ -405,30 +446,43 @@ typedef struct _glitz_vec4_t { #define TEXTURE_INVALID_SIZE(texture) \ ((texture)->flags & GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK) +typedef struct _glitz_texture_parameters { + glitz_gl_enum_t filter[2]; + glitz_gl_enum_t wrap[2]; + glitz_color_t border_color; +} glitz_texture_parameters_t; + typedef struct _glitz_texture { glitz_gl_uint_t name; glitz_gl_enum_t target; glitz_gl_int_t format; unsigned long flags; - - glitz_gl_enum_t filter; - glitz_gl_enum_t wrap; - - int width; - int height; - - glitz_box_t box; - - glitz_float_t texcoord_width_unit; - glitz_float_t texcoord_height_unit; + + glitz_texture_parameters_t param; + + int width; + int height; + + glitz_box_t box; + + glitz_float_t texcoord_width_unit; + glitz_float_t texcoord_height_unit; } glitz_texture_t; +struct _glitz_texture_object { + glitz_surface_t *surface; + int ref_count; + glitz_texture_parameters_t param; +}; + struct _glitz_buffer { glitz_gl_uint_t name; glitz_gl_enum_t target; void *data; int owns_data; int ref_count; + glitz_surface_t *front_surface; + glitz_surface_t *back_surface; glitz_drawable_t *drawable; }; @@ -538,10 +592,6 @@ typedef struct _glitz_geometry { #define SURFACE_PROJECTIVE_TRANSFORM(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK) -#define SURFACE_DRAWABLE_HEIGHT(surface) \ - (((surface)->attached) ? \ - (surface)->attached->height: surface->texture.height) - typedef struct _glitz_filter_params_t glitz_filter_params_t; typedef struct _glitz_matrix { @@ -549,10 +599,6 @@ typedef struct _glitz_matrix { glitz_float_t m[16]; } glitz_matrix_t; -typedef struct _glitz_framebuffer { - glitz_gl_uint_t name; -} glitz_framebuffer_t; - #define GLITZ_DAMAGE_TEXTURE_MASK (1 << 0) #define GLITZ_DAMAGE_DRAWABLE_MASK (1 << 1) #define GLITZ_DAMAGE_SOLID_MASK (1 << 2) @@ -587,11 +633,12 @@ struct _glitz_surface { int *primcount; glitz_region_t texture_damage; glitz_region_t drawable_damage; - glitz_framebuffer_t framebuffer; + unsigned int flip_count; + glitz_gl_int_t fb; }; #define GLITZ_GL_SURFACE(surface) \ - glitz_gl_proc_address_list_t *gl = &(surface)->drawable->backend->gl; + glitz_gl_proc_address_list_t *gl = (surface)->drawable->backend->gl; struct _glitz_context { int ref_count; @@ -634,160 +681,169 @@ typedef struct _glitz_extension_map { extern void __internal_linkage glitz_set_operator (glitz_gl_proc_address_list_t *gl, - glitz_operator_t op); + glitz_operator_t op); unsigned long glitz_extensions_query (glitz_gl_float_t version, - const char *extensions_string, - glitz_extension_map *extensions_map); + const char *extensions_string, + glitz_extension_map *extensions_map); typedef glitz_function_pointer_t (* glitz_get_proc_address_proc_t) (const char *name, void *closure); void glitz_backend_init (glitz_backend_t *backend, - glitz_get_proc_address_proc_t get_proc_address, - void *closure); + glitz_get_proc_address_proc_t get_proc_address, + void *closure); extern unsigned int __internal_linkage glitz_uint_to_power_of_two (unsigned int x); extern void __internal_linkage glitz_set_raster_pos (glitz_gl_proc_address_list_t *gl, - glitz_float_t x, - glitz_float_t y); + glitz_float_t x, + glitz_float_t y); extern void __internal_linkage glitz_clamp_value (glitz_float_t *value, - glitz_float_t min, - glitz_float_t max); + glitz_float_t min, + glitz_float_t max); void glitz_initiate_state (glitz_gl_proc_address_list_t *gl); void glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl, - glitz_format_t **formats, - glitz_gl_int_t **texture_formats, - int *n_formats); + glitz_format_t **formats, + glitz_gl_int_t **texture_formats, + int *n_formats); + +extern void __internal_linkage +_glitz_add_drawable_formats (glitz_gl_proc_address_list_t *gl, + unsigned long feature_mask, + glitz_int_drawable_format_t **formats, + int *n_formats); + +void +glitz_drawable_format_copy (const glitz_drawable_format_t *src, + glitz_drawable_format_t *dst, + unsigned long mask); glitz_drawable_format_t * -glitz_drawable_format_find (glitz_drawable_format_t *formats, - int n_formats, - unsigned long mask, - const glitz_drawable_format_t *templ, - int count); +glitz_drawable_format_find (glitz_int_drawable_format_t *formats, + int n_formats, + unsigned long mask, + const glitz_int_drawable_format_t *templ, + int count); void glitz_texture_init (glitz_texture_t *texture, - int width, - int height, - glitz_gl_int_t texture_format, - unsigned long feature_mask, - glitz_bool_t unnormalized); + int width, + int height, + glitz_gl_int_t texture_format, + unsigned long feature_mask, + glitz_bool_t unnormalized); void glitz_texture_fini (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture); + glitz_texture_t *texture); void glitz_texture_size_check (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_int_t max_2d, - glitz_gl_int_t max_rect); + glitz_texture_t *texture, + glitz_gl_int_t max_2d, + glitz_gl_int_t max_rect); void glitz_texture_allocate (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture); + glitz_texture_t *texture); extern void __internal_linkage -glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_enum_t filter); - -extern void __internal_linkage -glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_enum_t wrap); +glitz_texture_ensure_parameters (glitz_gl_proc_address_list_t *gl, + glitz_texture_t *texture, + glitz_texture_parameters_t *param); void glitz_texture_bind (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture); + glitz_texture_t *texture); void glitz_texture_unbind (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture); + glitz_texture_t *texture); void glitz_texture_copy_drawable (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_drawable_t *drawable, - int x_drawable, - int y_drawable, - int width, - int height, - int x_texture, - int y_texture); + glitz_texture_t *texture, + glitz_drawable_t *drawable, + int x_drawable, + int y_drawable, + int width, + int height, + int x_texture, + int y_texture); void glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_geometry_t *geometry, - int x_src, - int y_src, - unsigned long flags, - glitz_int_coordinate_t *coord); + glitz_texture_t *texture, + glitz_geometry_t *geometry, + int x_src, + int y_src, + unsigned long flags, + glitz_int_coordinate_t *coord); + +extern void __internal_linkage +_glitz_surface_sync_texture (glitz_surface_t *surface); extern glitz_texture_t __internal_linkage * glitz_surface_get_texture (glitz_surface_t *surface, - glitz_bool_t allocate); + glitz_bool_t allocate); extern void __internal_linkage glitz_surface_sync_solid (glitz_surface_t *surface); extern glitz_bool_t __internal_linkage glitz_surface_push_current (glitz_surface_t *surface, - glitz_constraint_t constraint); + glitz_constraint_t constraint); extern void __internal_linkage glitz_surface_pop_current (glitz_surface_t *surface); extern void __internal_linkage glitz_surface_damage (glitz_surface_t *surface, - glitz_box_t *box, - int what); + glitz_box_t *box, + int what); extern void __internal_linkage glitz_surface_sync_drawable (glitz_surface_t *surface); extern void __internal_linkage glitz_surface_status_add (glitz_surface_t *surface, - int flags); + int flags); extern unsigned long __internal_linkage glitz_status_to_status_mask (glitz_status_t status); - + extern glitz_status_t __internal_linkage glitz_status_pop_from_mask (unsigned long *mask); void glitz_program_map_init (glitz_program_map_t *map); - + void glitz_program_map_fini (glitz_gl_proc_address_list_t *gl, - glitz_program_map_t *map); + glitz_program_map_t *map); extern glitz_gl_uint_t __internal_linkage glitz_get_fragment_program (glitz_composite_op_t *op, - int fp_type, - int id); + int fp_type, + int id); extern void __internal_linkage glitz_composite_op_init (glitz_composite_op_t *op, - glitz_operator_t render_op, - glitz_surface_t *src, - glitz_surface_t *mask, - glitz_surface_t *dst); + glitz_operator_t render_op, + glitz_surface_t *src, + glitz_surface_t *mask, + glitz_surface_t *dst); extern void __internal_linkage glitz_composite_enable (glitz_composite_op_t *op); @@ -797,71 +853,69 @@ glitz_composite_disable (glitz_composite_op_t *op); extern void __internal_linkage * glitz_buffer_bind (glitz_buffer_t *buffer, - glitz_gl_enum_t target); + glitz_gl_enum_t target); extern void __internal_linkage glitz_buffer_unbind (glitz_buffer_t *buffer); extern glitz_status_t __internal_linkage glitz_filter_set_params (glitz_surface_t *surface, - glitz_filter_t filter, - glitz_fixed16_16_t *params, - int n_params); + glitz_filter_t filter, + glitz_fixed16_16_t *params, + int n_params); extern void __internal_linkage glitz_filter_set_type (glitz_surface_t *surface, - glitz_filter_t filter); + glitz_filter_t filter); extern glitz_gl_uint_t __internal_linkage glitz_filter_get_vertex_program (glitz_surface_t *surface, - glitz_composite_op_t *op); + glitz_composite_op_t *op); extern glitz_gl_uint_t __internal_linkage glitz_filter_get_fragment_program (glitz_surface_t *surface, - glitz_composite_op_t *op); + glitz_composite_op_t *op); extern void __internal_linkage glitz_filter_enable (glitz_surface_t *surface, - glitz_composite_op_t *op); + glitz_composite_op_t *op); extern void __internal_linkage glitz_geometry_enable_none (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *box); + glitz_surface_t *dst, + glitz_box_t *box); extern void __internal_linkage glitz_geometry_enable (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *box); + glitz_surface_t *dst, + glitz_box_t *box); extern void __internal_linkage glitz_geometry_disable (glitz_surface_t *dst); extern void __internal_linkage glitz_geometry_draw_arrays (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_geometry_type_t type, - glitz_box_t *bounds, - int damage); - -extern void __internal_linkage -glitz_framebuffer_init (glitz_framebuffer_t *framebuffer); - -extern void __internal_linkage -glitz_framebuffer_fini (glitz_gl_proc_address_list_t *gl, - glitz_framebuffer_t *framebuffer); + glitz_surface_t *dst, + glitz_geometry_type_t type, + glitz_box_t *bounds, + int damage); -extern void __internal_linkage -glitz_framebuffer_unbind (glitz_gl_proc_address_list_t *gl); - -extern glitz_bool_t __internal_linkage -glitz_framebuffer_complete (glitz_gl_proc_address_list_t *gl, - glitz_framebuffer_t *framebuffer, - glitz_texture_t *texture); +void +_glitz_drawable_init (glitz_drawable_t *drawable, + glitz_int_drawable_format_t *format, + glitz_backend_t *backend, + int width, + int height); + +extern glitz_drawable_t __internal_linkage * +_glitz_fbo_drawable_create (glitz_drawable_t *other, + glitz_int_drawable_format_t *format, + int width, + int height); void _glitz_context_init (glitz_context_t *context, - glitz_drawable_t *drawable); + glitz_drawable_t *drawable); void _glitz_context_fini (glitz_context_t *context); @@ -912,8 +966,8 @@ typedef uint32_t glitz_fixed_1_16; typedef int32_t glitz_fixed_16_16; /* - * An unadorned "glitz_fixed" is the same as glitz_fixed_16_16, - * (since it's quite common in the code) + * An unadorned "glitz_fixed" is the same as glitz_fixed_16_16, + * (since it's quite common in the code) */ typedef glitz_fixed_16_16 glitz_fixed; @@ -941,14 +995,15 @@ typedef glitz_fixed_16_16 glitz_fixed; #define POWER_OF_TWO(v) ((v & (v - 1)) == 0) -/* Avoid unnecessary PLT entries. */ +/* Avoid unnecessary PLT entries. */ -slim_hidden_proto(glitz_find_similar_drawable_format) +slim_hidden_proto(glitz_find_drawable_format) +slim_hidden_proto(glitz_find_pbuffer_format) +slim_hidden_proto(glitz_create_drawable) slim_hidden_proto(glitz_create_pbuffer_drawable) slim_hidden_proto(glitz_drawable_get_width) slim_hidden_proto(glitz_drawable_get_height) slim_hidden_proto(glitz_drawable_swap_buffers) -slim_hidden_proto(glitz_drawable_swap_buffers) slim_hidden_proto(glitz_drawable_flush) slim_hidden_proto(glitz_drawable_finish) slim_hidden_proto(glitz_drawable_get_features) diff --git a/src/glx/glitz-glx.h b/src/glx/glitz-glx.h index d0e3125..01f50b4 100644 --- a/src/glx/glitz-glx.h +++ b/src/glx/glitz-glx.h @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -42,17 +42,24 @@ glitz_glx_init (const char *gl_library); void glitz_glx_fini (void); - - + + /* glitz_glx_format.c */ glitz_drawable_format_t * -glitz_glx_find_drawable_format (Display *display, - int screen, - unsigned long mask, - const glitz_drawable_format_t *templ, - int count); - +glitz_glx_find_window_format (Display *display, + int screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count); + +glitz_drawable_format_t * +glitz_glx_find_pbuffer_format (Display *display, + int screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count); + glitz_drawable_format_t * glitz_glx_find_drawable_format_for_visual (Display *display, int screen, @@ -60,26 +67,26 @@ glitz_glx_find_drawable_format_for_visual (Display *display, XVisualInfo * glitz_glx_get_visual_info_from_format (Display *display, - int screen, - glitz_drawable_format_t *format); - + int screen, + glitz_drawable_format_t *format); + /* glitz_glx_drawable.c */ glitz_drawable_t * glitz_glx_create_drawable_for_window (Display *display, - int screen, - glitz_drawable_format_t *format, - Window window, - unsigned int width, - unsigned int height); + int screen, + glitz_drawable_format_t *format, + Window window, + unsigned int width, + unsigned int height); glitz_drawable_t * glitz_glx_create_pbuffer_drawable (Display *display, - int screen, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height); + int screen, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); #if defined(__cplusplus) || defined(c_plusplus) diff --git a/src/glx/glitz_glx_context.c b/src/glx/glitz_glx_context.c index 5d6caad..e0f87a9 100644 --- a/src/glx/glitz_glx_context.c +++ b/src/glx/glitz_glx_context.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -35,402 +35,448 @@ extern glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address; static void _glitz_glx_context_create (glitz_glx_screen_info_t *screen_info, - XID visualid, - GLXContext share_list, - glitz_glx_context_t *context) + XID visualid, + GLXContext share_list, + glitz_glx_context_t *context) { - int vis_info_count, i; - XVisualInfo *vis_infos; - - vis_infos = XGetVisualInfo (screen_info->display_info->display, - 0, NULL, &vis_info_count); - for (i = 0; i < vis_info_count; i++) { - if (vis_infos[i].visual->visualid == visualid) - break; - } - - context->context = glXCreateContext (screen_info->display_info->display, - &vis_infos[i], share_list, - GLITZ_GL_TRUE); - context->id = visualid; - context->fbconfig = (GLXFBConfig) 0; - - XFree (vis_infos); + int vis_info_count, i; + XVisualInfo *vis_infos; + + vis_infos = XGetVisualInfo (screen_info->display_info->display, + 0, NULL, &vis_info_count); + for (i = 0; i < vis_info_count; i++) { + if (vis_infos[i].visual->visualid == visualid) + break; + } + + context->context = glXCreateContext (screen_info->display_info->display, + &vis_infos[i], share_list, + GLITZ_GL_TRUE); + context->id = visualid; + context->fbconfig = (GLXFBConfig) 0; + + XFree (vis_infos); } static void _glitz_glx_context_create_using_fbconfig (glitz_glx_screen_info_t *screen_info, - XID fbconfigid, - GLXContext share_list, - glitz_glx_context_t *context) + XID fbconfigid, + GLXContext share_list, + glitz_glx_context_t *context) { - GLXFBConfig *fbconfigs; - int i, n_fbconfigs; - XVisualInfo *vinfo = NULL; - glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; - - fbconfigs = glx->get_fbconfigs (screen_info->display_info->display, - screen_info->screen, &n_fbconfigs); - for (i = 0; i < n_fbconfigs; i++) { - int value; - - glx->get_fbconfig_attrib (screen_info->display_info->display, fbconfigs[i], - GLX_FBCONFIG_ID, &value); - if (value == (int) fbconfigid) - break; - } - - if (i < n_fbconfigs) - vinfo = glx->get_visual_from_fbconfig (screen_info->display_info->display, - fbconfigs[i]); - - context->id = fbconfigid; - if (vinfo) { - context->context = glXCreateContext (screen_info->display_info->display, - vinfo, share_list, GLITZ_GL_TRUE); - XFree (vinfo); - } else if (glx->create_new_context) - context->context = - glx->create_new_context (screen_info->display_info->display, - fbconfigs[i], GLX_RGBA_TYPE, share_list, - GLITZ_GL_TRUE); - - if (context->context) - context->fbconfig = fbconfigs[i]; - else - context->fbconfig = (GLXFBConfig) 0; + GLXFBConfig *fbconfigs; + int i, n_fbconfigs; + XVisualInfo *vinfo = NULL; + glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; + + fbconfigs = glx->get_fbconfigs (screen_info->display_info->display, + screen_info->screen, &n_fbconfigs); + for (i = 0; i < n_fbconfigs; i++) { + int value; + + glx->get_fbconfig_attrib (screen_info->display_info->display, + fbconfigs[i], + GLX_FBCONFIG_ID, &value); + if (value == (int) fbconfigid) + break; + } - if (fbconfigs) - XFree (fbconfigs); + if (i < n_fbconfigs) + vinfo = + glx->get_visual_from_fbconfig (screen_info->display_info->display, + fbconfigs[i]); + + context->id = fbconfigid; + if (vinfo) { + context->context = + glXCreateContext (screen_info->display_info->display, + vinfo, share_list, GLITZ_GL_TRUE); + XFree (vinfo); + } else if (glx->create_new_context) + context->context = + glx->create_new_context (screen_info->display_info->display, + fbconfigs[i], GLX_RGBA_TYPE, share_list, + GLITZ_GL_TRUE); + + if (context->context) + context->fbconfig = fbconfigs[i]; + else + context->fbconfig = (GLXFBConfig) 0; + + if (fbconfigs) + XFree (fbconfigs); } static glitz_context_t * _glitz_glx_create_context (void *abstract_drawable, - glitz_drawable_format_t *format) + glitz_drawable_format_t *format) { - glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; - glitz_glx_screen_info_t *screen_info = drawable->screen_info; - int format_id = screen_info->format_ids[format->id]; - glitz_glx_context_t *context; - - context = malloc (sizeof (glitz_glx_context_t)); - if (!context) - return NULL; - - _glitz_context_init (&context->base, &drawable->base); - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) - _glitz_glx_context_create_using_fbconfig (screen_info, - format_id, - screen_info->root_context, - context); - else - _glitz_glx_context_create (screen_info, - format_id, - screen_info->root_context, - context); - - return (glitz_context_t *) context; + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) + abstract_drawable; + glitz_glx_screen_info_t *screen_info = drawable->screen_info; + unsigned long format_id = + screen_info->formats[format->id].u.uval; + glitz_glx_context_t *context; + + context = malloc (sizeof (glitz_glx_context_t)); + if (!context) + return NULL; + + _glitz_context_init (&context->base, &drawable->base); + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) + _glitz_glx_context_create_using_fbconfig (screen_info, + format_id, + screen_info->root_context, + context); + else + _glitz_glx_context_create (screen_info, + format_id, + screen_info->root_context, + context); + + return (glitz_context_t *) context; } static void _glitz_glx_context_destroy (void *abstract_context) { - glitz_glx_context_t *context = (glitz_glx_context_t *) abstract_context; - glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) - context->base.drawable; - - if (drawable->screen_info->display_info->thread_info->cctx == &context->base) - { - glXMakeCurrent (drawable->screen_info->display_info->display, - None, NULL); - - drawable->screen_info->display_info->thread_info->cctx = NULL; - } - - glXDestroyContext (drawable->screen_info->display_info->display, - context->context); - - _glitz_context_fini (&context->base); - - free (context); + glitz_glx_context_t *context = (glitz_glx_context_t *) abstract_context; + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) + context->base.drawable; + + if (drawable->screen_info->display_info->thread_info->cctx == + &context->base) + { + glXMakeCurrent (drawable->screen_info->display_info->display, + None, NULL); + + drawable->screen_info->display_info->thread_info->cctx = NULL; + } + + glXDestroyContext (drawable->screen_info->display_info->display, + context->context); + + _glitz_context_fini (&context->base); + + free (context); } static void _glitz_glx_copy_context (void *abstract_src, - void *abstract_dst, - unsigned long mask) + void *abstract_dst, + unsigned long mask) { - glitz_glx_context_t *src = (glitz_glx_context_t *) abstract_src; - glitz_glx_context_t *dst = (glitz_glx_context_t *) abstract_dst; - glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) - src->base.drawable; + glitz_glx_context_t *src = (glitz_glx_context_t *) abstract_src; + glitz_glx_context_t *dst = (glitz_glx_context_t *) abstract_dst; + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) + src->base.drawable; - glXCopyContext (drawable->screen_info->display_info->display, - src->context, dst->context, mask); + glXCopyContext (drawable->screen_info->display_info->display, + src->context, dst->context, mask); } static void -_glitz_glx_make_current (void *abstract_context, - void *abstract_drawable) +_glitz_glx_make_current (void *abstract_drawable, + void *abstract_context) { - glitz_glx_context_t *context = (glitz_glx_context_t *) abstract_context; - glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; - glitz_glx_display_info_t *display_info = drawable->screen_info->display_info; - - if ((glXGetCurrentContext () != context->context) || - (glXGetCurrentDrawable () != drawable->drawable)) - { - if (display_info->thread_info->cctx) - { - glitz_context_t *ctx = display_info->thread_info->cctx; - - if (ctx->lose_current) - ctx->lose_current (ctx->closure); - } - glXMakeCurrent (display_info->display, drawable->drawable, - context->context); - } - - display_info->thread_info->cctx = &context->base; + glitz_glx_context_t *context = (glitz_glx_context_t *) abstract_context; + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) + abstract_drawable; + glitz_glx_display_info_t *display_info = + drawable->screen_info->display_info; + + if (drawable->base.width != drawable->width || + drawable->base.height != drawable->height) + _glitz_glx_drawable_update_size (drawable, + drawable->base.width, + drawable->base.height); + + if ((glXGetCurrentContext () != context->context) || + (glXGetCurrentDrawable () != drawable->drawable)) + { + if (display_info->thread_info->cctx) + { + glitz_context_t *ctx = display_info->thread_info->cctx; + + if (ctx->lose_current) + ctx->lose_current (ctx->closure); + } + + glXMakeCurrent (display_info->display, drawable->drawable, + context->context); + } + + display_info->thread_info->cctx = &context->base; } +static void +_glitz_glx_notify_dummy (void *abstract_drawable, + glitz_surface_t *surface) {} + static glitz_function_pointer_t _glitz_glx_context_get_proc_address (void *abstract_context, - const char *name) + const char *name) { - glitz_glx_context_t *context = (glitz_glx_context_t *) abstract_context; - glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) - context->base.drawable; + glitz_glx_context_t *context = (glitz_glx_context_t *) abstract_context; + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) + context->base.drawable; - _glitz_glx_make_current (context, drawable); - - return glitz_glx_get_proc_address (name, drawable->screen_info); + /* _glitz_glx_make_current (drawable, context, NULL); */ + + return glitz_glx_get_proc_address (name, drawable->screen_info); } glitz_glx_context_t * glitz_glx_context_get (glitz_glx_screen_info_t *screen_info, - glitz_drawable_format_t *format) + glitz_drawable_format_t *format) { - glitz_glx_context_t *context; - glitz_glx_context_t **contexts = screen_info->contexts; - int index, n_contexts = screen_info->n_contexts; - XID format_id; + glitz_glx_context_t *context; + glitz_glx_context_t **contexts = screen_info->contexts; + int index, n_contexts = screen_info->n_contexts; + unsigned long format_id; + + for (; n_contexts; n_contexts--, contexts++) + if ((*contexts)->id == screen_info->formats[format->id].u.uval) + return *contexts; + + index = screen_info->n_contexts++; + + screen_info->contexts = + realloc (screen_info->contexts, + sizeof (glitz_glx_context_t *) * screen_info->n_contexts); + if (!screen_info->contexts) + return NULL; + + context = malloc (sizeof (glitz_glx_context_t)); + if (!context) + return NULL; + + screen_info->contexts[index] = context; + + format_id = screen_info->formats[format->id].u.uval; + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) + _glitz_glx_context_create_using_fbconfig (screen_info, + format_id, + screen_info->root_context, + context); + else + _glitz_glx_context_create (screen_info, + format_id, + screen_info->root_context, + context); + + if (!screen_info->root_context) + screen_info->root_context = context->context; + + context->backend.gl = &_glitz_glx_gl_proc_address; + + context->backend.create_pbuffer = glitz_glx_create_pbuffer; + context->backend.destroy = glitz_glx_destroy; + context->backend.push_current = glitz_glx_push_current; + context->backend.pop_current = glitz_glx_pop_current; + context->backend.attach_notify = _glitz_glx_notify_dummy; + context->backend.detach_notify = _glitz_glx_notify_dummy; + context->backend.swap_buffers = glitz_glx_swap_buffers; + + context->backend.create_context = _glitz_glx_create_context; + context->backend.destroy_context = _glitz_glx_context_destroy; + context->backend.copy_context = _glitz_glx_copy_context; + context->backend.make_current = _glitz_glx_make_current; + context->backend.get_proc_address = _glitz_glx_context_get_proc_address; + + context->backend.drawable_formats = NULL; + context->backend.n_drawable_formats = 0; + + if (screen_info->n_formats) + { + int size; + + size = sizeof (glitz_int_drawable_format_t) * screen_info->n_formats; + context->backend.drawable_formats = malloc (size); + if (context->backend.drawable_formats) + { + memcpy (context->backend.drawable_formats, screen_info->formats, + size); + context->backend.n_drawable_formats = screen_info->n_formats; + } + } - for (; n_contexts; n_contexts--, contexts++) - if ((*contexts)->id == screen_info->format_ids[format->id]) - return *contexts; + context->backend.texture_formats = NULL; + context->backend.formats = NULL; + context->backend.n_formats = 0; - index = screen_info->n_contexts++; + context->backend.program_map = &screen_info->program_map; + context->backend.feature_mask = 0; - screen_info->contexts = - realloc (screen_info->contexts, - sizeof (glitz_glx_context_t *) * screen_info->n_contexts); - if (!screen_info->contexts) - return NULL; + context->initialized = 0; - context = malloc (sizeof (glitz_glx_context_t)); - if (!context) - return NULL; - - screen_info->contexts[index] = context; - - format_id = screen_info->format_ids[format->id]; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) - _glitz_glx_context_create_using_fbconfig (screen_info, - format_id, - screen_info->root_context, - context); - else - _glitz_glx_context_create (screen_info, - format_id, - screen_info->root_context, - context); - - if (!screen_info->root_context) - screen_info->root_context = context->context; - - memcpy (&context->backend.gl, - &_glitz_glx_gl_proc_address, - sizeof (glitz_gl_proc_address_list_t)); - - context->backend.create_pbuffer = glitz_glx_create_pbuffer; - context->backend.destroy = glitz_glx_destroy; - context->backend.push_current = glitz_glx_push_current; - context->backend.pop_current = glitz_glx_pop_current; - context->backend.swap_buffers = glitz_glx_swap_buffers; - - context->backend.create_context = _glitz_glx_create_context; - context->backend.destroy_context = _glitz_glx_context_destroy; - context->backend.copy_context = _glitz_glx_copy_context; - context->backend.make_current = _glitz_glx_make_current; - context->backend.get_proc_address = _glitz_glx_context_get_proc_address; - - context->backend.drawable_formats = screen_info->formats; - context->backend.n_drawable_formats = screen_info->n_formats; - - context->backend.texture_formats = NULL; - context->backend.formats = NULL; - context->backend.n_formats = 0; - - context->backend.program_map = &screen_info->program_map; - context->backend.feature_mask = 0; - - context->initialized = 0; - - return context; + return context; } void glitz_glx_context_destroy (glitz_glx_screen_info_t *screen_info, - glitz_glx_context_t *context) + glitz_glx_context_t *context) { - if (context->backend.formats) - free (context->backend.formats); - - if (context->backend.texture_formats) - free (context->backend.texture_formats); - - glXDestroyContext (screen_info->display_info->display, - context->context); - free (context); + if (context->backend.drawable_formats) + free (context->backend.drawable_formats); + + if (context->backend.formats) + free (context->backend.formats); + + if (context->backend.texture_formats) + free (context->backend.texture_formats); + + glXDestroyContext (screen_info->display_info->display, + context->context); + free (context); } static void _glitz_glx_context_initialize (glitz_glx_screen_info_t *screen_info, - glitz_glx_context_t *context) + glitz_glx_context_t *context) { - const char *version; - - glitz_backend_init (&context->backend, - glitz_glx_get_proc_address, - (void *) screen_info); - - context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS, - context->max_viewport_dims); - - glitz_initiate_state (&_glitz_glx_gl_proc_address); - - version = (const char *) context->backend.gl.get_string (GLITZ_GL_VERSION); - if (version) - { - /* Having trouble with TexSubImage2D to NPOT GL_TEXTURE_2D textures when - using nvidia's binary driver. Seems like a driver issue, but I'm not - sure yet. Turning of NPOT GL_TEXTURE_2D textures until this have been - solved. */ - if (strstr (version, "NVIDIA 61.11") || - strstr (version, "NVIDIA 66.29")) + const char *version; + + glitz_backend_init (&context->backend, + glitz_glx_get_proc_address, + (void *) screen_info); + + glitz_initiate_state (&_glitz_glx_gl_proc_address); + + version = (const char *) + context->backend.gl->get_string (GLITZ_GL_VERSION); + if (version) { - context->backend.feature_mask &= - ~GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK; + /* Having trouble with TexSubImage2D to NPOT GL_TEXTURE_2D textures + when using nvidia's binary driver. Seems like a driver issue, but + I'm not sure yet. Turning of NPOT GL_TEXTURE_2D textures until this + have been solved. */ + if (strstr (version, "NVIDIA 61.11") || + strstr (version, "NVIDIA 66.29")) + { + context->backend.feature_mask &= + ~GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK; + } } - } - - context->initialized = 1; + + context->initialized = 1; } static void _glitz_glx_context_make_current (glitz_glx_drawable_t *drawable, - glitz_bool_t finish) + glitz_bool_t finish) { - glitz_glx_display_info_t *display_info = drawable->screen_info->display_info; - - if (finish) - glFinish (); - - if (display_info->thread_info->cctx) - { - glitz_context_t *ctx = display_info->thread_info->cctx; - - if (ctx->lose_current) - ctx->lose_current (ctx->closure); - - display_info->thread_info->cctx = NULL; - } - - glXMakeCurrent (display_info->display, - drawable->drawable, - drawable->context->context); - - drawable->base.update_all = 1; - - if (!drawable->context->initialized) - _glitz_glx_context_initialize (drawable->screen_info, drawable->context); + glitz_glx_display_info_t *display_info = + drawable->screen_info->display_info; + + if (finish) + glFinish (); + + if (display_info->thread_info->cctx) + { + glitz_context_t *ctx = display_info->thread_info->cctx; + + if (ctx->lose_current) + ctx->lose_current (ctx->closure); + + display_info->thread_info->cctx = NULL; + } + + glXMakeCurrent (display_info->display, + drawable->drawable, + drawable->context->context); + + drawable->base.update_all = 1; + + if (!drawable->context->initialized) + _glitz_glx_context_initialize (drawable->screen_info, + drawable->context); } static void _glitz_glx_context_update (glitz_glx_drawable_t *drawable, - glitz_constraint_t constraint) + glitz_constraint_t constraint) { glitz_glx_display_info_t *dinfo = drawable->screen_info->display_info; GLXContext context = NULL; - + switch (constraint) { case GLITZ_NONE: - break; + break; case GLITZ_ANY_CONTEXT_CURRENT: - if (!dinfo->thread_info->cctx) - context = glXGetCurrentContext (); - - if (context == (GLXContext) 0) - _glitz_glx_context_make_current (drawable, 0); - break; - case GLITZ_CONTEXT_CURRENT: - if (!dinfo->thread_info->cctx) - context = glXGetCurrentContext (); - - if (context != drawable->context->context) - _glitz_glx_context_make_current (drawable, (context)? 1: 0); - break; + if (!dinfo->thread_info->cctx) + context = glXGetCurrentContext (); + + if (context == (GLXContext) 0) + _glitz_glx_context_make_current (drawable, 0); + break; + case GLITZ_CONTEXT_CURRENT: + if (!dinfo->thread_info->cctx) + context = glXGetCurrentContext (); + + if (context != drawable->context->context) + _glitz_glx_context_make_current (drawable, (context)? 1: 0); + break; case GLITZ_DRAWABLE_CURRENT: - if (!dinfo->thread_info->cctx) - context = glXGetCurrentContext (); - - if ((context != drawable->context->context) || - (glXGetCurrentDrawable () != drawable->drawable)) - _glitz_glx_context_make_current (drawable, (context)? 1: 0); - break; + if (!dinfo->thread_info->cctx) + context = glXGetCurrentContext (); + + if (drawable->base.width != drawable->width || + drawable->base.height != drawable->height) + _glitz_glx_drawable_update_size (drawable, + drawable->base.width, + drawable->base.height); + + if ((context != drawable->context->context) || + (glXGetCurrentDrawable () != drawable->drawable)) + _glitz_glx_context_make_current (drawable, (context)? 1: 0); + break; } } -void +glitz_bool_t glitz_glx_push_current (void *abstract_drawable, - glitz_surface_t *surface, - glitz_constraint_t constraint) + glitz_surface_t *surface, + glitz_constraint_t constraint) { - glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; - glitz_glx_context_info_t *context_info; - int index; - - index = drawable->screen_info->context_stack_size++; - - context_info = &drawable->screen_info->context_stack[index]; - context_info->drawable = drawable; - context_info->surface = surface; - context_info->constraint = constraint; - - _glitz_glx_context_update (context_info->drawable, constraint); + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) + abstract_drawable; + glitz_glx_context_info_t *context_info; + int index; + + index = drawable->screen_info->context_stack_size++; + + context_info = &drawable->screen_info->context_stack[index]; + context_info->drawable = drawable; + context_info->surface = surface; + context_info->constraint = constraint; + + _glitz_glx_context_update (context_info->drawable, constraint); + + return 1; } glitz_surface_t * glitz_glx_pop_current (void *abstract_drawable) { - glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; - glitz_glx_context_info_t *context_info = NULL; - int index; - - drawable->screen_info->context_stack_size--; - index = drawable->screen_info->context_stack_size - 1; - - context_info = &drawable->screen_info->context_stack[index]; - - if (context_info->drawable) - _glitz_glx_context_update (context_info->drawable, - context_info->constraint); - - if (context_info->constraint == GLITZ_DRAWABLE_CURRENT) - return context_info->surface; - - return NULL; + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) + abstract_drawable; + glitz_glx_context_info_t *context_info = NULL; + int index; + + drawable->screen_info->context_stack_size--; + index = drawable->screen_info->context_stack_size - 1; + + context_info = &drawable->screen_info->context_stack[index]; + + if (context_info->drawable) + _glitz_glx_context_update (context_info->drawable, + context_info->constraint); + + if (context_info->constraint == GLITZ_DRAWABLE_CURRENT) + return context_info->surface; + + return NULL; } diff --git a/src/glx/glitz_glx_drawable.c b/src/glx/glitz_glx_drawable.c index f770476..7c80925 100644 --- a/src/glx/glitz_glx_drawable.c +++ b/src/glx/glitz_glx_drawable.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,172 +31,212 @@ static glitz_glx_drawable_t * _glitz_glx_create_drawable (glitz_glx_screen_info_t *screen_info, - glitz_glx_context_t *context, - glitz_drawable_format_t *format, - GLXDrawable glx_drawable, - GLXPbuffer glx_pbuffer, - int width, - int height) + glitz_glx_context_t *context, + glitz_drawable_format_t *format, + GLXDrawable glx_drawable, + GLXPbuffer glx_pbuffer, + int width, + int height) { - glitz_glx_drawable_t *drawable; - - if (width <= 0 || height <= 0) - return NULL; - - drawable = (glitz_glx_drawable_t *) malloc (sizeof (glitz_glx_drawable_t)); - if (drawable == NULL) - return NULL; - - drawable->base.ref_count = 1; - drawable->screen_info = screen_info; - drawable->context = context; - drawable->drawable = glx_drawable; - drawable->pbuffer = glx_pbuffer; - drawable->base.format = format; - drawable->base.backend = &context->backend; - - glitz_drawable_update_size (&drawable->base, width, height); - - if (!context->initialized) { - glitz_glx_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT); - glitz_glx_pop_current (drawable); - } - - if (width > context->max_viewport_dims[0] || - height > context->max_viewport_dims[1]) { - free (drawable); - return NULL; - } - - screen_info->drawables++; - - return drawable; + glitz_glx_drawable_t *drawable; + + drawable = (glitz_glx_drawable_t *) malloc (sizeof (glitz_glx_drawable_t)); + if (drawable == NULL) + return NULL; + + drawable->screen_info = screen_info; + drawable->context = context; + drawable->drawable = glx_drawable; + drawable->pbuffer = glx_pbuffer; + drawable->width = width; + drawable->height = height; + + _glitz_drawable_init (&drawable->base, + &screen_info->formats[format->id], + &context->backend, + width, height); + + if (!context->initialized) { + glitz_glx_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT); + glitz_glx_pop_current (drawable); + } + + if (width > context->backend.max_viewport_dims[0] || + height > context->backend.max_viewport_dims[1]) { + free (drawable); + return NULL; + } + + screen_info->drawables++; + + return drawable; +} + +glitz_bool_t +_glitz_glx_drawable_update_size (glitz_glx_drawable_t *drawable, + int width, + int height) +{ + if (drawable->pbuffer) + { + glitz_glx_pbuffer_destroy (drawable->screen_info, drawable->pbuffer); + drawable->drawable = drawable->pbuffer = + glitz_glx_pbuffer_create (drawable->screen_info, + drawable->context->fbconfig, + (int) width, (int) height); + if (!drawable->pbuffer) + return 0; + } + + drawable->width = width; + drawable->height = height; + + return 1; } static glitz_drawable_t * _glitz_glx_create_pbuffer_drawable (glitz_glx_screen_info_t *screen_info, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { - glitz_glx_drawable_t *drawable; - glitz_glx_context_t *context; - GLXPbuffer pbuffer; - - if (!format->types.pbuffer) - return NULL; - - context = glitz_glx_context_get (screen_info, format); - if (!context) - return NULL; - - pbuffer = glitz_glx_pbuffer_create (screen_info, context->fbconfig, - (int) width, (int) height); - if (!pbuffer) - return NULL; - - drawable = _glitz_glx_create_drawable (screen_info, context, format, - pbuffer, pbuffer, - width, height); - if (!drawable) { - glitz_glx_pbuffer_destroy (screen_info, pbuffer); - return NULL; - } - - return &drawable->base; + glitz_glx_drawable_t *drawable; + glitz_glx_context_t *context; + GLXPbuffer pbuffer; + + context = glitz_glx_context_get (screen_info, format); + if (!context) + return NULL; + + pbuffer = glitz_glx_pbuffer_create (screen_info, context->fbconfig, + (int) width, (int) height); + if (!pbuffer) + return NULL; + + drawable = _glitz_glx_create_drawable (screen_info, context, format, + pbuffer, pbuffer, + width, height); + if (!drawable) { + glitz_glx_pbuffer_destroy (screen_info, pbuffer); + return NULL; + } + + return &drawable->base; } glitz_drawable_t * glitz_glx_create_pbuffer (void *abstract_templ, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { - glitz_glx_drawable_t *templ = (glitz_glx_drawable_t *) abstract_templ; + glitz_glx_drawable_t *templ = (glitz_glx_drawable_t *) abstract_templ; - return _glitz_glx_create_pbuffer_drawable (templ->screen_info, format, - width, height); + return _glitz_glx_create_pbuffer_drawable (templ->screen_info, format, + width, height); } glitz_drawable_t * glitz_glx_create_drawable_for_window (Display *display, - int screen, - glitz_drawable_format_t *format, - Window window, - unsigned int width, - unsigned int height) + int screen, + glitz_drawable_format_t *format, + Window window, + unsigned int width, + unsigned int height) { - glitz_glx_drawable_t *drawable; - glitz_glx_screen_info_t *screen_info; - glitz_glx_context_t *context; - - screen_info = glitz_glx_screen_info_get (display, screen); - if (!screen_info) - return NULL; - - context = glitz_glx_context_get (screen_info, format); - if (!context) - return NULL; - - drawable = _glitz_glx_create_drawable (screen_info, context, format, - window, (GLXPbuffer) 0, - width, height); - if (!drawable) - return NULL; - - return &drawable->base; + glitz_glx_drawable_t *drawable; + glitz_glx_screen_info_t *screen_info; + glitz_glx_context_t *context; + glitz_int_drawable_format_t *iformat; + + screen_info = glitz_glx_screen_info_get (display, screen); + if (!screen_info) + return NULL; + + if (format->id >= screen_info->n_formats) + return NULL; + + iformat = &screen_info->formats[format->id]; + if (!(iformat->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK)) + return NULL; + + context = glitz_glx_context_get (screen_info, format); + if (!context) + return NULL; + + drawable = _glitz_glx_create_drawable (screen_info, context, format, + window, (GLXPbuffer) 0, + width, height); + if (!drawable) + return NULL; + + return &drawable->base; } slim_hidden_def(glitz_glx_create_drawable_for_window); glitz_drawable_t * glitz_glx_create_pbuffer_drawable (Display *display, - int screen, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height) + int screen, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { - glitz_glx_screen_info_t *screen_info; + glitz_glx_screen_info_t *screen_info; + glitz_int_drawable_format_t *iformat; + + screen_info = glitz_glx_screen_info_get (display, screen); + if (!screen_info) + return NULL; + + if (format->id >= screen_info->n_formats) + return NULL; - screen_info = glitz_glx_screen_info_get (display, screen); - if (!screen_info) - return NULL; + iformat = &screen_info->formats[format->id]; + if (!(iformat->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK)) + return NULL; - return _glitz_glx_create_pbuffer_drawable (screen_info, format, - width, height); + return _glitz_glx_create_pbuffer_drawable (screen_info, format, + width, height); } slim_hidden_def(glitz_glx_create_pbuffer_drawable); void glitz_glx_destroy (void *abstract_drawable) { - glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; - - drawable->screen_info->drawables--; - if (drawable->screen_info->drawables == 0) { - /* - * Last drawable? We have to destroy all fragment programs as this may - * be our last chance to have a context current. - */ - glitz_glx_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT); - glitz_program_map_fini (&drawable->base.backend->gl, - &drawable->screen_info->program_map); - glitz_glx_pop_current (abstract_drawable); - } - - if (glXGetCurrentDrawable () == drawable->drawable) - glXMakeCurrent (drawable->screen_info->display_info->display, None, NULL); - - if (drawable->pbuffer) - glitz_glx_pbuffer_destroy (drawable->screen_info, drawable->pbuffer); - - free (drawable); + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) + abstract_drawable; + + drawable->screen_info->drawables--; + if (drawable->screen_info->drawables == 0) { + /* + * Last drawable? We have to destroy all fragment programs as this may + * be our last chance to have a context current. + */ + glitz_glx_push_current (abstract_drawable, NULL, + GLITZ_CONTEXT_CURRENT); + glitz_program_map_fini (drawable->base.backend->gl, + &drawable->screen_info->program_map); + glitz_glx_pop_current (abstract_drawable); + } + + if (glXGetCurrentDrawable () == drawable->drawable) + glXMakeCurrent (drawable->screen_info->display_info->display, + None, NULL); + + if (drawable->pbuffer) + glitz_glx_pbuffer_destroy (drawable->screen_info, drawable->pbuffer); + + free (drawable); } -void +glitz_bool_t glitz_glx_swap_buffers (void *abstract_drawable) { - glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) + abstract_drawable; + + glXSwapBuffers (drawable->screen_info->display_info->display, + drawable->drawable); - glXSwapBuffers (drawable->screen_info->display_info->display, - drawable->drawable); + return 1; } diff --git a/src/glx/glitz_glx_extension.c b/src/glx/glitz_glx_extension.c index 42d6748..3953b34 100644 --- a/src/glx/glitz_glx_extension.c +++ b/src/glx/glitz_glx_extension.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -30,41 +30,42 @@ #include "glitz_glxint.h" static glitz_extension_map glx_extensions[] = { - { 0.0, "GLX_SGIX_fbconfig", GLITZ_GLX_FEATURE_FBCONFIG_MASK }, - { 0.0, "GLX_SGIX_pbuffer", GLITZ_GLX_FEATURE_PBUFFER_MASK }, - { 0.0, "GLX_SGI_make_current_read", - GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK }, - { 0.0, "GLX_ARB_multisample", GLITZ_GLX_FEATURE_MULTISAMPLE_MASK }, - { 0.0, NULL, 0 } + { 0.0, "GLX_EXT_visual_rating", GLITZ_GLX_FEATURE_VISUAL_RATING_MASK }, + { 0.0, "GLX_SGIX_fbconfig", GLITZ_GLX_FEATURE_FBCONFIG_MASK }, + { 0.0, "GLX_SGIX_pbuffer", GLITZ_GLX_FEATURE_PBUFFER_MASK }, + { 0.0, "GLX_SGI_make_current_read", + GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK }, + { 0.0, "GLX_ARB_multisample", GLITZ_GLX_FEATURE_MULTISAMPLE_MASK }, + { 0.0, NULL, 0 } }; void glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info, - glitz_gl_float_t glx_version) + glitz_gl_float_t glx_version) { - const char *glx_extensions_string; + const char *glx_extensions_string; + + glx_extensions_string = + glXQueryExtensionsString (screen_info->display_info->display, + screen_info->screen); + + screen_info->glx_feature_mask = + glitz_extensions_query (glx_version, + glx_extensions_string, + glx_extensions); + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) { + const char *vendor; + + vendor = glXGetClientString (screen_info->display_info->display, + GLX_VENDOR); - glx_extensions_string = - glXQueryExtensionsString (screen_info->display_info->display, - screen_info->screen); - - screen_info->glx_feature_mask = - glitz_extensions_query (glx_version, - glx_extensions_string, - glx_extensions); - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) { - const char *vendor; + if (vendor) { - vendor = glXGetClientString (screen_info->display_info->display, - GLX_VENDOR); - - if (vendor) { - - /* NVIDIA's driver seem to support multisample with pbuffers */ - if (!strncmp ("NVIDIA", vendor, 6)) - screen_info->glx_feature_mask |= - GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK; + /* NVIDIA's driver seem to support multisample with pbuffers */ + if (!strncmp ("NVIDIA", vendor, 6)) + screen_info->glx_feature_mask |= + GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK; + } } - } } diff --git a/src/glx/glitz_glx_format.c b/src/glx/glitz_glx_format.c index 51670fc..0e18e79 100644 --- a/src/glx/glitz_glx_format.c +++ b/src/glx/glitz_glx_format.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -34,390 +34,459 @@ static int _glitz_glx_format_compare (const void *elem1, - const void *elem2) + const void *elem2) { - int i, score[2]; - glitz_drawable_format_t *format[2]; - - format[0] = (glitz_drawable_format_t *) elem1; - format[1] = (glitz_drawable_format_t *) elem2; - i = score[0] = score[1] = 0; - - for (; i < 2; i++) { - if (format[i]->color.red_size) { - if (format[i]->color.red_size == 8) - score[i] += 5; - score[i] += 10; - } + glitz_int_drawable_format_t *format[2]; + int i, score[2]; - if (format[i]->color.green_size) { - if (format[i]->color.green_size == 8) - score[i] += 5; - score[i] += 10; - } - - if (format[i]->color.alpha_size) { - if (format[i]->color.alpha_size == 8) - score[i] += 5; - score[i] += 10; + format[0] = (glitz_int_drawable_format_t *) elem1; + format[1] = (glitz_int_drawable_format_t *) elem2; + i = score[0] = score[1] = 0; + + for (; i < 2; i++) + { + if (format[i]->d.color.red_size) + { + if (format[i]->d.color.red_size >= 8) + score[i] += 5; + + score[i] += 10; + } + + if (format[i]->d.color.alpha_size) + { + if (format[i]->d.color.alpha_size >= 8) + score[i] += 5; + + score[i] += 10; + } + + if (format[i]->d.stencil_size) + score[i] += 5; + + if (format[i]->d.depth_size) + score[i] += 5; + + if (format[i]->d.doublebuffer) + score[i] += 10; + + if (format[i]->d.samples > 1) + score[i] -= (20 - format[i]->d.samples); + + if (format[i]->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK) + score[i] += 10; + + if (format[i]->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK) + score[i] += 10; + + if (format[i]->caveat) + score[i] -= 1000; } - if (format[i]->stencil_size) - score[i] += 5; - - if (format[i]->depth_size) - score[i] += 5; - - if (format[i]->doublebuffer) - score[i] += 10; - - if (format[i]->types.window) - score[i] += 10; - - if (format[i]->types.pbuffer) - score[i] += 10; - - if (format[i]->samples > 1) - score[i] -= (20 - format[i]->samples); - } - - return score[1] - score[0]; + return score[1] - score[0]; } static void -_glitz_add_format (glitz_glx_screen_info_t *screen_info, - glitz_drawable_format_t *format, - XID id) +_glitz_add_format (glitz_glx_screen_info_t *screen_info, + glitz_int_drawable_format_t *format) { int n = screen_info->n_formats; - + screen_info->formats = - realloc (screen_info->formats, - sizeof (glitz_drawable_format_t) * (n + 1)); - screen_info->format_ids = - realloc (screen_info->format_ids, sizeof (XID) * (n + 1)); - - if (screen_info->formats && screen_info->format_ids) { - screen_info->formats[n] = *format; - screen_info->formats[n].id = n; - screen_info->format_ids[n] = id; - screen_info->n_formats++; + realloc (screen_info->formats, + sizeof (glitz_int_drawable_format_t) * (n + 1)); + if (screen_info->formats) + { + screen_info->formats[n] = *format; + screen_info->formats[n].d.id = n; + screen_info->n_formats++; } } static void _glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info) { - Display *display; - glitz_drawable_format_t format; - XVisualInfo visual_templ; - XVisualInfo *visuals; - int i, num_visuals; - - display = screen_info->display_info->display; - - visual_templ.screen = screen_info->screen; - visuals = XGetVisualInfo (display, VisualScreenMask, - &visual_templ, &num_visuals); - - /* No pbuffers without fbconfigs */ - format.types.window = 1; - format.types.pbuffer = 0; - format.id = 0; - - for (i = 0; i < num_visuals; i++) { - int value; - - if ((glXGetConfig (display, &visuals[i], GLX_USE_GL, &value) != 0) || - (value == 0)) - continue; - - glXGetConfig (display, &visuals[i], GLX_RGBA, &value); - if (value == 0) - continue; - - /* Stereo is not supported yet */ - glXGetConfig (display, &visuals[i], GLX_STEREO, &value); - if (value != 0) - continue; - - glXGetConfig (display, &visuals[i], GLX_RED_SIZE, &value); - format.color.red_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_GREEN_SIZE, &value); - format.color.green_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_BLUE_SIZE, &value); - format.color.blue_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_ALPHA_SIZE, &value); - format.color.alpha_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_DEPTH_SIZE, &value); - format.depth_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_STENCIL_SIZE, &value); - format.stencil_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_DOUBLEBUFFER, &value); - format.doublebuffer = (value) ? 1: 0; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) { - glXGetConfig (display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &value); - if (value) { - glXGetConfig (display, &visuals[i], GLX_SAMPLES_ARB, &value); - format.samples = (unsigned short) (value > 1)? value: 1; - } else - format.samples = 1; - } else - format.samples = 1; - - _glitz_add_format (screen_info, &format, visuals[i].visualid); - } - - if (visuals) - XFree (visuals); + Display *display; + glitz_int_drawable_format_t format; + XVisualInfo visual_templ; + XVisualInfo *visuals; + int i, num_visuals; + + display = screen_info->display_info->display; + + visual_templ.screen = screen_info->screen; + visuals = XGetVisualInfo (display, VisualScreenMask, + &visual_templ, &num_visuals); + + /* No pbuffers without fbconfigs */ + format.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK; + format.d.id = 0; + + for (i = 0; i < num_visuals; i++) + { + int value; + + if ((glXGetConfig (display, &visuals[i], GLX_USE_GL, &value) != 0) || + (value == 0)) + continue; + + glXGetConfig (display, &visuals[i], GLX_RGBA, &value); + if (value == 0) + continue; + + /* Stereo is not supported yet */ + glXGetConfig (display, &visuals[i], GLX_STEREO, &value); + if (value != 0) + continue; + + glXGetConfig (display, &visuals[i], GLX_RED_SIZE, &value); + format.d.color.red_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_GREEN_SIZE, &value); + format.d.color.green_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_BLUE_SIZE, &value); + format.d.color.blue_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_ALPHA_SIZE, &value); + format.d.color.alpha_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_DEPTH_SIZE, &value); + format.d.depth_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_STENCIL_SIZE, &value); + format.d.stencil_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_DOUBLEBUFFER, &value); + format.d.doublebuffer = (value) ? 1: 0; + + if (screen_info->glx_feature_mask & + GLITZ_GLX_FEATURE_VISUAL_RATING_MASK) + { + glXGetConfig (display, &visuals[i], GLX_VISUAL_CAVEAT_EXT, &value); + switch (value) { + case GLX_SLOW_VISUAL_EXT: + case GLX_NON_CONFORMANT_VISUAL_EXT: + format.caveat = 1; + break; + default: + format.caveat = 0; + break; + } + } + else + format.caveat = 0; + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) + { + glXGetConfig (display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, + &value); + if (value) + { + glXGetConfig (display, &visuals[i], GLX_SAMPLES_ARB, &value); + format.d.samples = (unsigned short) (value > 1)? value: 1; + } + else + format.d.samples = 1; + } + else + format.d.samples = 1; + + format.u.uval = visuals[i].visualid; + + _glitz_add_format (screen_info, &format); + } + + if (visuals) + XFree (visuals); } static glitz_status_t _glitz_glx_query_formats_using_fbconfigs (glitz_glx_screen_info_t *screen_info) { - glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; - Display *display; - glitz_drawable_format_t format; - GLXFBConfig *fbconfigs; - int i, num_configs; - XID id; - - display = screen_info->display_info->display; - - fbconfigs = glx->get_fbconfigs (display, screen_info->screen, &num_configs); - if (!fbconfigs) { - /* fbconfigs are not supported, falling back to visuals */ - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_FBCONFIG_MASK; - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; - - return GLITZ_STATUS_NOT_SUPPORTED; - } - - for (i = 0; i < num_configs; i++) { - int value; - - if ((glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_RENDER_TYPE, &value) != 0) || - (!(value & GLX_RGBA_BIT))) - continue; - - /* Stereo is not supported yet */ - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STEREO, &value); - if (value != 0) - continue; - - glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_DRAWABLE_TYPE, &value); - if (!((value & GLX_WINDOW_BIT) || (value & GLX_PBUFFER_BIT))) - continue; - - format.types.window = (value & GLX_WINDOW_BIT)? 1: 0; - format.types.pbuffer = (value & GLX_PBUFFER_BIT)? 1: 0; - format.id = 0; - - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_FBCONFIG_ID, &value); - id = (XID) value; - - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_RED_SIZE, &value); - format.color.red_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_GREEN_SIZE, &value); - format.color.green_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_BLUE_SIZE, &value); - format.color.blue_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_ALPHA_SIZE, &value); - format.color.alpha_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DEPTH_SIZE, &value); - format.depth_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STENCIL_SIZE, &value); - format.stencil_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DOUBLEBUFFER, &value); - format.doublebuffer = (value)? 1: 0; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) { - glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_SAMPLE_BUFFERS_ARB, &value); - if (value) { - glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_SAMPLES_ARB, &value); - format.samples = (unsigned short) (value > 1)? value: 1; - if (format.samples > 1) { - if (!(screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK)) - format.types.pbuffer = 0; - } - } else - format.samples = 1; - } else - format.samples = 1; - - _glitz_add_format (screen_info, &format, id); - } - - if (fbconfigs) - XFree (fbconfigs); - - return GLITZ_STATUS_SUCCESS; + glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; + Display *display; + glitz_int_drawable_format_t format; + GLXFBConfig *fbconfigs; + int i, num_configs; + + display = screen_info->display_info->display; + + fbconfigs = glx->get_fbconfigs (display, screen_info->screen, + &num_configs); + if (!fbconfigs) + { + /* fbconfigs are not supported, falling back to visuals */ + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_FBCONFIG_MASK; + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; + + return GLITZ_STATUS_NOT_SUPPORTED; + } + + for (i = 0; i < num_configs; i++) + { + int value; + + if ((glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_RENDER_TYPE, &value) != 0) || + (!(value & GLX_RGBA_BIT))) + continue; + + /* Stereo is not supported yet */ + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STEREO, &value); + if (value != 0) + continue; + + glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_DRAWABLE_TYPE, &value); + if (!((value & GLX_WINDOW_BIT) || (value & GLX_PBUFFER_BIT))) + continue; + + format.types = 0; + if (value & GLX_WINDOW_BIT) + format.types |= GLITZ_DRAWABLE_TYPE_WINDOW_MASK; + + if (value & GLX_PBUFFER_BIT) + format.types |= GLITZ_DRAWABLE_TYPE_PBUFFER_MASK; + + format.d.id = 0; + + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_FBCONFIG_ID, + &value); + format.u.uval = value; + + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_RED_SIZE, &value); + format.d.color.red_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_GREEN_SIZE, + &value); + format.d.color.green_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_BLUE_SIZE, + &value); + format.d.color.blue_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_ALPHA_SIZE, + &value); + format.d.color.alpha_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DEPTH_SIZE, + &value); + format.d.depth_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STENCIL_SIZE, + &value); + format.d.stencil_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DOUBLEBUFFER, + &value); + format.d.doublebuffer = (value)? 1: 0; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_CONFIG_CAVEAT, + &value); + switch (value) { + case GLX_SLOW_VISUAL_EXT: + case GLX_NON_CONFORMANT_VISUAL_EXT: + format.caveat = 1; + break; + default: + format.caveat = 0; + break; + } + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) + { + glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_SAMPLE_BUFFERS_ARB, &value); + if (value) + { + glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_SAMPLES_ARB, &value); + format.d.samples = (unsigned short) (value > 1)? value: 1; + if (format.d.samples > 1) + { + if (!(screen_info->glx_feature_mask & + GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK)) + format.types &= ~GLITZ_DRAWABLE_TYPE_PBUFFER_MASK; + } + } + else + format.d.samples = 1; + } + else + format.d.samples = 1; + + _glitz_add_format (screen_info, &format); + } + + if (fbconfigs) + XFree (fbconfigs); + + return GLITZ_STATUS_SUCCESS; } void glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info) { - glitz_status_t status = GLITZ_STATUS_NOT_SUPPORTED; - XID *new_ids; - int i; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) - status = _glitz_glx_query_formats_using_fbconfigs (screen_info); - - if (status) - _glitz_glx_query_formats (screen_info); - - if (!screen_info->n_formats) - return; - - qsort (screen_info->formats, screen_info->n_formats, - sizeof (glitz_drawable_format_t), _glitz_glx_format_compare); - - /* - * Update XID list so that it matches the sorted format list. - */ - new_ids = malloc (sizeof (XID) * screen_info->n_formats); - if (!new_ids) { - screen_info->n_formats = 0; - return; - } - - for (i = 0; i < screen_info->n_formats; i++) { - new_ids[i] = screen_info->format_ids[screen_info->formats[i].id]; - screen_info->formats[i].id = i; - } - - free (screen_info->format_ids); - screen_info->format_ids = new_ids; + glitz_status_t status = GLITZ_STATUS_NOT_SUPPORTED; + int i; + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) + status = _glitz_glx_query_formats_using_fbconfigs (screen_info); + + if (status) + _glitz_glx_query_formats (screen_info); + + if (!screen_info->n_formats) + return; + + qsort (screen_info->formats, screen_info->n_formats, + sizeof (glitz_int_drawable_format_t), _glitz_glx_format_compare); + + for (i = 0; i < screen_info->n_formats; i++) + screen_info->formats[i].d.id = i; } glitz_drawable_format_t * -glitz_glx_find_drawable_format (Display *display, - int screen, - unsigned long mask, - const glitz_drawable_format_t *templ, - int count) +glitz_glx_find_window_format (Display *display, + int screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count) { - glitz_glx_screen_info_t *screen_info = - glitz_glx_screen_info_get (display, screen); + glitz_int_drawable_format_t itempl; + glitz_glx_screen_info_t *screen_info = + glitz_glx_screen_info_get (display, screen); + + glitz_drawable_format_copy (templ, &itempl.d, mask); + + itempl.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK; + mask |= GLITZ_INT_FORMAT_WINDOW_MASK; + + return glitz_drawable_format_find (screen_info->formats, + screen_info->n_formats, + mask, &itempl, count); +} +slim_hidden_def(glitz_glx_find_window_format); + +glitz_drawable_format_t * +glitz_glx_find_pbuffer_format (Display *display, + int screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count) +{ + glitz_int_drawable_format_t itempl; + glitz_glx_screen_info_t *screen_info = + glitz_glx_screen_info_get (display, screen); + + glitz_drawable_format_copy (templ, &itempl.d, mask); + + itempl.types = GLITZ_DRAWABLE_TYPE_PBUFFER_MASK; + mask |= GLITZ_INT_FORMAT_PBUFFER_MASK; - return glitz_drawable_format_find (screen_info->formats, - screen_info->n_formats, - mask, templ, count); + return glitz_drawable_format_find (screen_info->formats, + screen_info->n_formats, + mask, &itempl, count); } -slim_hidden_def(glitz_glx_find_drawable_format); +slim_hidden_def(glitz_glx_find_pbuffer_format); glitz_drawable_format_t * glitz_glx_find_drawable_format_for_visual (Display *display, - int screen, - VisualID visual_id) + int screen, + VisualID visual_id) { glitz_drawable_format_t *format = NULL; glitz_glx_screen_info_t *screen_info; - int i; + int i; screen_info = glitz_glx_screen_info_get (display, screen); if (!screen_info) - return NULL; + return NULL; if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) { - glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; - GLXFBConfig *fbconfigs; - int fid, n_fbconfigs; - - fid = -1; - fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs); - for (i = 0; i < n_fbconfigs; i++) - { - XVisualInfo *visinfo; - - visinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]); - if (visinfo && visinfo->visualid == visual_id) - { - int value; - - glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_FBCONFIG_ID, &value); - for (fid = 0; fid < screen_info->n_formats; fid++) - { - if (screen_info->format_ids[fid] == value) - { - format = screen_info->formats + fid; - break; - } - } - - if (format) - break; - } - } - - if (fbconfigs) - XFree (fbconfigs); + glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; + GLXFBConfig *fbconfigs; + int fid, n_fbconfigs; + + fid = -1; + fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs); + for (i = 0; i < n_fbconfigs; i++) + { + XVisualInfo *visinfo; + + visinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]); + if (visinfo && visinfo->visualid == visual_id) + { + int value; + + glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_FBCONFIG_ID, &value); + for (fid = 0; fid < screen_info->n_formats; fid++) + { + if (screen_info->formats[fid].u.uval == value) + { + format = &screen_info->formats[fid].d; + break; + } + } + + if (format) + break; + } + } + + if (fbconfigs) + XFree (fbconfigs); } else { - for (i = 0; i < screen_info->n_formats; i++) - { - if (visual_id == screen_info->format_ids[i]) - { - format = screen_info->formats + i; - break; - } - } + for (i = 0; i < screen_info->n_formats; i++) + { + if (visual_id == screen_info->formats[i].u.uval) + { + format = &screen_info->formats[i].d; + break; + } + } } - + return format; } slim_hidden_def(glitz_glx_find_drawable_format_for_visual); XVisualInfo * glitz_glx_get_visual_info_from_format (Display *display, - int screen, - glitz_drawable_format_t *format) + int screen, + glitz_drawable_format_t *format) { - XVisualInfo *vinfo = NULL; - glitz_glx_screen_info_t *screen_info = - glitz_glx_screen_info_get (display, screen); - glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) { - GLXFBConfig *fbconfigs; - int i, n_fbconfigs; - int fbconfigid = screen_info->format_ids[format->id]; - - fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs); - for (i = 0; i < n_fbconfigs; i++) { - int value; - - glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_FBCONFIG_ID, &value); - if (value == fbconfigid) - break; + XVisualInfo *vinfo = NULL; + glitz_glx_screen_info_t *screen_info = + glitz_glx_screen_info_get (display, screen); + glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) + { + GLXFBConfig *fbconfigs; + int i, n_fbconfigs; + int fbconfigid = screen_info->formats[format->id].u.uval; + + fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs); + for (i = 0; i < n_fbconfigs; i++) + { + int value; + + glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_FBCONFIG_ID, &value); + if (value == fbconfigid) + break; + } + + if (i < n_fbconfigs) + vinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]); + + if (fbconfigs) + XFree (fbconfigs); + } - - if (i < n_fbconfigs) - vinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]); - - if (fbconfigs) - XFree (fbconfigs); - - } else { - XVisualInfo templ; - int n_items; - - templ.visualid = screen_info->format_ids[format->id]; - - vinfo = XGetVisualInfo (display, VisualIDMask, &templ, &n_items); - } - - return vinfo; + else + { + XVisualInfo templ; + int n_items; + + templ.visualid = screen_info->formats[format->id].u.uval; + + vinfo = XGetVisualInfo (display, VisualIDMask, &templ, &n_items); + } + + return vinfo; } slim_hidden_def(glitz_glx_get_visual_info_from_format); diff --git a/src/glx/glitz_glx_info.c b/src/glx/glitz_glx_info.c index def1de7..5f7f287 100644 --- a/src/glx/glitz_glx_info.c +++ b/src/glx/glitz_glx_info.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -34,219 +34,244 @@ glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address = { - /* core */ - (glitz_gl_enable_t) glEnable, - (glitz_gl_disable_t) glDisable, - (glitz_gl_get_error_t) glGetError, - (glitz_gl_get_string_t) glGetString, - (glitz_gl_enable_client_state_t) glEnableClientState, - (glitz_gl_disable_client_state_t) glDisableClientState, - (glitz_gl_vertex_pointer_t) glVertexPointer, - (glitz_gl_tex_coord_pointer_t) glTexCoordPointer, - (glitz_gl_draw_arrays_t) glDrawArrays, - (glitz_gl_tex_env_f_t) glTexEnvf, - (glitz_gl_tex_env_fv_t) glTexEnvfv, - (glitz_gl_tex_gen_i_t) glTexGeni, - (glitz_gl_tex_gen_fv_t) glTexGenfv, - (glitz_gl_color_4us_t) glColor4us, - (glitz_gl_color_4f_t) glColor4f, - (glitz_gl_scissor_t) glScissor, - (glitz_gl_blend_func_t) glBlendFunc, - (glitz_gl_clear_t) glClear, - (glitz_gl_clear_color_t) glClearColor, - (glitz_gl_clear_stencil_t) glClearStencil, - (glitz_gl_stencil_func_t) glStencilFunc, - (glitz_gl_stencil_op_t) glStencilOp, - (glitz_gl_push_attrib_t) glPushAttrib, - (glitz_gl_pop_attrib_t) glPopAttrib, - (glitz_gl_matrix_mode_t) glMatrixMode, - (glitz_gl_push_matrix_t) glPushMatrix, - (glitz_gl_pop_matrix_t) glPopMatrix, - (glitz_gl_load_identity_t) glLoadIdentity, - (glitz_gl_load_matrix_f_t) glLoadMatrixf, - (glitz_gl_depth_range_t) glDepthRange, - (glitz_gl_viewport_t) glViewport, - (glitz_gl_raster_pos_2f_t) glRasterPos2f, - (glitz_gl_bitmap_t) glBitmap, - (glitz_gl_read_buffer_t) glReadBuffer, - (glitz_gl_draw_buffer_t) glDrawBuffer, - (glitz_gl_copy_pixels_t) glCopyPixels, - (glitz_gl_flush_t) glFlush, - (glitz_gl_finish_t) glFinish, - (glitz_gl_pixel_store_i_t) glPixelStorei, - (glitz_gl_ortho_t) glOrtho, - (glitz_gl_scale_f_t) glScalef, - (glitz_gl_translate_f_t) glTranslatef, - (glitz_gl_hint_t) glHint, - (glitz_gl_depth_mask_t) glDepthMask, - (glitz_gl_polygon_mode_t) glPolygonMode, - (glitz_gl_shade_model_t) glShadeModel, - (glitz_gl_color_mask_t) glColorMask, - (glitz_gl_read_pixels_t) glReadPixels, - (glitz_gl_get_tex_image_t) glGetTexImage, - (glitz_gl_tex_sub_image_2d_t) glTexSubImage2D, - (glitz_gl_gen_textures_t) glGenTextures, - (glitz_gl_delete_textures_t) glDeleteTextures, - (glitz_gl_bind_texture_t) glBindTexture, - (glitz_gl_tex_image_2d_t) glTexImage2D, - (glitz_gl_tex_parameter_i_t) glTexParameteri, - (glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv, - (glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D, - (glitz_gl_get_integer_v_t) glGetIntegerv, - - /* extensions */ - (glitz_gl_blend_color_t) 0, - (glitz_gl_active_texture_t) 0, - (glitz_gl_client_active_texture_t) 0, - (glitz_gl_multi_draw_arrays_t) 0, - (glitz_gl_gen_programs_t) 0, - (glitz_gl_delete_programs_t) 0, - (glitz_gl_program_string_t) 0, - (glitz_gl_bind_program_t) 0, - (glitz_gl_program_local_param_4fv_t) 0, - (glitz_gl_get_program_iv_t) 0, - (glitz_gl_gen_buffers_t) 0, - (glitz_gl_delete_buffers_t) 0, - (glitz_gl_bind_buffer_t) 0, - (glitz_gl_buffer_data_t) 0, - (glitz_gl_buffer_sub_data_t) 0, - (glitz_gl_get_buffer_sub_data_t) 0, - (glitz_gl_map_buffer_t) 0, - (glitz_gl_unmap_buffer_t) 0 + /* core */ + (glitz_gl_enable_t) glEnable, + (glitz_gl_disable_t) glDisable, + (glitz_gl_get_error_t) glGetError, + (glitz_gl_get_string_t) glGetString, + (glitz_gl_enable_client_state_t) glEnableClientState, + (glitz_gl_disable_client_state_t) glDisableClientState, + (glitz_gl_vertex_pointer_t) glVertexPointer, + (glitz_gl_tex_coord_pointer_t) glTexCoordPointer, + (glitz_gl_draw_arrays_t) glDrawArrays, + (glitz_gl_tex_env_f_t) glTexEnvf, + (glitz_gl_tex_env_fv_t) glTexEnvfv, + (glitz_gl_tex_gen_i_t) glTexGeni, + (glitz_gl_tex_gen_fv_t) glTexGenfv, + (glitz_gl_color_4us_t) glColor4us, + (glitz_gl_color_4f_t) glColor4f, + (glitz_gl_scissor_t) glScissor, + (glitz_gl_blend_func_t) glBlendFunc, + (glitz_gl_clear_t) glClear, + (glitz_gl_clear_color_t) glClearColor, + (glitz_gl_clear_stencil_t) glClearStencil, + (glitz_gl_stencil_func_t) glStencilFunc, + (glitz_gl_stencil_op_t) glStencilOp, + (glitz_gl_push_attrib_t) glPushAttrib, + (glitz_gl_pop_attrib_t) glPopAttrib, + (glitz_gl_matrix_mode_t) glMatrixMode, + (glitz_gl_push_matrix_t) glPushMatrix, + (glitz_gl_pop_matrix_t) glPopMatrix, + (glitz_gl_load_identity_t) glLoadIdentity, + (glitz_gl_load_matrix_f_t) glLoadMatrixf, + (glitz_gl_depth_range_t) glDepthRange, + (glitz_gl_viewport_t) glViewport, + (glitz_gl_raster_pos_2f_t) glRasterPos2f, + (glitz_gl_bitmap_t) glBitmap, + (glitz_gl_read_buffer_t) glReadBuffer, + (glitz_gl_draw_buffer_t) glDrawBuffer, + (glitz_gl_copy_pixels_t) glCopyPixels, + (glitz_gl_flush_t) glFlush, + (glitz_gl_finish_t) glFinish, + (glitz_gl_pixel_store_i_t) glPixelStorei, + (glitz_gl_ortho_t) glOrtho, + (glitz_gl_scale_f_t) glScalef, + (glitz_gl_translate_f_t) glTranslatef, + (glitz_gl_hint_t) glHint, + (glitz_gl_depth_mask_t) glDepthMask, + (glitz_gl_polygon_mode_t) glPolygonMode, + (glitz_gl_shade_model_t) glShadeModel, + (glitz_gl_color_mask_t) glColorMask, + (glitz_gl_read_pixels_t) glReadPixels, + (glitz_gl_get_tex_image_t) glGetTexImage, + (glitz_gl_tex_sub_image_2d_t) glTexSubImage2D, + (glitz_gl_gen_textures_t) glGenTextures, + (glitz_gl_delete_textures_t) glDeleteTextures, + (glitz_gl_bind_texture_t) glBindTexture, + (glitz_gl_tex_image_2d_t) glTexImage2D, + (glitz_gl_tex_parameter_i_t) glTexParameteri, + (glitz_gl_tex_parameter_fv_t) glTexParameterfv, + (glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv, + (glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D, + (glitz_gl_get_integer_v_t) glGetIntegerv, + + /* extensions */ + (glitz_gl_blend_color_t) 0, + (glitz_gl_active_texture_t) 0, + (glitz_gl_client_active_texture_t) 0, + (glitz_gl_multi_draw_arrays_t) 0, + (glitz_gl_gen_programs_t) 0, + (glitz_gl_delete_programs_t) 0, + (glitz_gl_program_string_t) 0, + (glitz_gl_bind_program_t) 0, + (glitz_gl_program_local_param_4fv_t) 0, + (glitz_gl_get_program_iv_t) 0, + (glitz_gl_gen_buffers_t) 0, + (glitz_gl_delete_buffers_t) 0, + (glitz_gl_bind_buffer_t) 0, + (glitz_gl_buffer_data_t) 0, + (glitz_gl_buffer_sub_data_t) 0, + (glitz_gl_get_buffer_sub_data_t) 0, + (glitz_gl_map_buffer_t) 0, + (glitz_gl_unmap_buffer_t) 0, + (glitz_gl_gen_framebuffers_t) 0, + (glitz_gl_delete_framebuffers_t) 0, + (glitz_gl_bind_framebuffer_t) 0, + (glitz_gl_framebuffer_renderbuffer_t) 0, + (glitz_gl_framebuffer_texture_2d_t) 0, + (glitz_gl_check_framebuffer_status_t) 0, + (glitz_gl_gen_renderbuffers_t) 0, + (glitz_gl_delete_renderbuffers_t) 0, + (glitz_gl_bind_renderbuffer_t) 0, + (glitz_gl_renderbuffer_storage_t) 0, + (glitz_gl_get_renderbuffer_parameter_iv_t) 0 }; glitz_function_pointer_t glitz_glx_get_proc_address (const char *name, - void *closure) + void *closure) { - glitz_glx_screen_info_t *screen_info = (glitz_glx_screen_info_t *) closure; - glitz_glx_thread_info_t *info = screen_info->display_info->thread_info; - glitz_function_pointer_t address = NULL; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK) - address = screen_info->glx.get_proc_address ((glitz_gl_ubyte_t *) name); - - if (!address) { - if (!info->dlhand) - info->dlhand = dlopen (info->gl_library, RTLD_LAZY); - - if (info->dlhand) { - dlerror (); - address = (glitz_function_pointer_t) dlsym (info->dlhand, name); - if (dlerror () != NULL) - address = NULL; + glitz_glx_screen_info_t *screen_info = (glitz_glx_screen_info_t *) closure; + glitz_glx_thread_info_t *info = screen_info->display_info->thread_info; + glitz_function_pointer_t address = NULL; + + if (screen_info->glx_feature_mask & + GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK) + address = + screen_info->glx.get_proc_address ((glitz_gl_ubyte_t *) name); + + if (!address) { + if (!info->dlhand) + info->dlhand = dlopen (info->gl_library, RTLD_LAZY); + + if (info->dlhand) { + dlerror (); + address = (glitz_function_pointer_t) dlsym (info->dlhand, name); + if (dlerror () != NULL) + address = NULL; + } } - } - - return address; + + return address; } static void _glitz_glx_proc_address_lookup (glitz_glx_screen_info_t *screen_info) { - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) { - if (screen_info->glx_version >= 1.3f) { - screen_info->glx.get_fbconfigs = (glitz_glx_get_fbconfigs_t) - glitz_glx_get_proc_address ("glXGetFBConfigs", (void *) screen_info); - screen_info->glx.get_fbconfig_attrib = (glitz_glx_get_fbconfig_attrib_t) - glitz_glx_get_proc_address ("glXGetFBConfigAttrib", - (void *) screen_info); - screen_info->glx.get_visual_from_fbconfig = - (glitz_glx_get_visual_from_fbconfig_t) - glitz_glx_get_proc_address ("glXGetVisualFromFBConfig", - (void *) screen_info); - screen_info->glx.create_new_context = (glitz_glx_create_new_context_t) - glitz_glx_get_proc_address ("glXCreateNewContext", - (void *) screen_info); - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_PBUFFER_MASK) { - screen_info->glx.create_pbuffer = (glitz_glx_create_pbuffer_t) - glitz_glx_get_proc_address ("glXCreatePbuffer", - (void *) screen_info); - screen_info->glx.destroy_pbuffer = (glitz_glx_destroy_pbuffer_t) - glitz_glx_get_proc_address ("glXDestroyPbuffer", - (void *) screen_info); - screen_info->glx.query_drawable = (glitz_glx_query_drawable_t) - glitz_glx_get_proc_address ("glXQueryDrawable", - (void *) screen_info); - } - } else { - screen_info->glx.get_fbconfigs = (glitz_glx_get_fbconfigs_t) - glitz_glx_get_proc_address ("glXGetFBConfigsSGIX", - (void *) screen_info); - screen_info->glx.get_fbconfig_attrib = (glitz_glx_get_fbconfig_attrib_t) - glitz_glx_get_proc_address ("glXGetFBConfigAttribSGIX", - (void *) screen_info); - screen_info->glx.get_visual_from_fbconfig = - (glitz_glx_get_visual_from_fbconfig_t) - glitz_glx_get_proc_address ("glXGetVisualFromFBConfigSGIX", - (void *) screen_info); - screen_info->glx.create_new_context = (glitz_glx_create_new_context_t) - glitz_glx_get_proc_address ("glXCreateContextWithConfigSGIX", - (void *) screen_info); - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_PBUFFER_MASK) { - screen_info->glx.create_pbuffer = (glitz_glx_create_pbuffer_t) - glitz_glx_get_proc_address ("glXCreateGLXPbufferSGIX", - (void *) screen_info); - screen_info->glx.destroy_pbuffer = (glitz_glx_destroy_pbuffer_t) - glitz_glx_get_proc_address ("glXDestroyGLXPbufferSGIX", - (void *) screen_info); - screen_info->glx.query_drawable = (glitz_glx_query_drawable_t) - glitz_glx_get_proc_address ("glXQueryGLXPbufferSGIX", - (void *) screen_info); - } + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) { + if (screen_info->glx_version >= 1.3f) { + screen_info->glx.get_fbconfigs = (glitz_glx_get_fbconfigs_t) + glitz_glx_get_proc_address ("glXGetFBConfigs", + (void *) screen_info); + screen_info->glx.get_fbconfig_attrib = + (glitz_glx_get_fbconfig_attrib_t) + glitz_glx_get_proc_address ("glXGetFBConfigAttrib", + (void *) screen_info); + screen_info->glx.get_visual_from_fbconfig = + (glitz_glx_get_visual_from_fbconfig_t) + glitz_glx_get_proc_address ("glXGetVisualFromFBConfig", + (void *) screen_info); + screen_info->glx.create_new_context = + (glitz_glx_create_new_context_t) + glitz_glx_get_proc_address ("glXCreateNewContext", + (void *) screen_info); + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_PBUFFER_MASK) + { + screen_info->glx.create_pbuffer = (glitz_glx_create_pbuffer_t) + glitz_glx_get_proc_address ("glXCreatePbuffer", + (void *) screen_info); + screen_info->glx.destroy_pbuffer = + (glitz_glx_destroy_pbuffer_t) + glitz_glx_get_proc_address ("glXDestroyPbuffer", + (void *) screen_info); + screen_info->glx.query_drawable = + (glitz_glx_query_drawable_t) + glitz_glx_get_proc_address ("glXQueryDrawable", + (void *) screen_info); + } + } else { + screen_info->glx.get_fbconfigs = (glitz_glx_get_fbconfigs_t) + glitz_glx_get_proc_address ("glXGetFBConfigsSGIX", + (void *) screen_info); + screen_info->glx.get_fbconfig_attrib = + (glitz_glx_get_fbconfig_attrib_t) + glitz_glx_get_proc_address ("glXGetFBConfigAttribSGIX", + (void *) screen_info); + screen_info->glx.get_visual_from_fbconfig = + (glitz_glx_get_visual_from_fbconfig_t) + glitz_glx_get_proc_address ("glXGetVisualFromFBConfigSGIX", + (void *) screen_info); + screen_info->glx.create_new_context = + (glitz_glx_create_new_context_t) + glitz_glx_get_proc_address ("glXCreateContextWithConfigSGIX", + (void *) screen_info); + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_PBUFFER_MASK) + { + screen_info->glx.create_pbuffer = (glitz_glx_create_pbuffer_t) + glitz_glx_get_proc_address ("glXCreateGLXPbufferSGIX", + (void *) screen_info); + screen_info->glx.destroy_pbuffer = + (glitz_glx_destroy_pbuffer_t) + glitz_glx_get_proc_address ("glXDestroyGLXPbufferSGIX", + (void *) screen_info); + screen_info->glx.query_drawable = (glitz_glx_query_drawable_t) + glitz_glx_get_proc_address ("glXQueryGLXPbufferSGIX", + (void *) screen_info); + } + } + + if ((!screen_info->glx.create_pbuffer) || + (!screen_info->glx.destroy_pbuffer) || + (!screen_info->glx.query_drawable)) + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; + + if ((!screen_info->glx.get_fbconfigs) || + (!screen_info->glx.get_fbconfig_attrib) || + (!screen_info->glx.get_visual_from_fbconfig) || + (!screen_info->glx.create_new_context)) { + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_FBCONFIG_MASK; + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; + } + } else + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; + + if (screen_info->glx_feature_mask & + GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK) { + if (screen_info->glx_version >= 1.3f) { + screen_info->glx.make_context_current = + (glitz_glx_make_context_current_t) + glitz_glx_get_proc_address ("glXMakeContextCurrent", + (void *) screen_info); + } else { + screen_info->glx.make_context_current = + (glitz_glx_make_context_current_t) + glitz_glx_get_proc_address ("glXMakeCurrentReadSGI", + (void *) screen_info); + } + + if (!screen_info->glx.make_context_current) + screen_info->glx_feature_mask &= + ~GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK; } - if ((!screen_info->glx.create_pbuffer) || - (!screen_info->glx.destroy_pbuffer) || - (!screen_info->glx.query_drawable)) - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; - - if ((!screen_info->glx.get_fbconfigs) || - (!screen_info->glx.get_fbconfig_attrib) || - (!screen_info->glx.get_visual_from_fbconfig) || - (!screen_info->glx.create_new_context)) { - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_FBCONFIG_MASK; - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; - } - } else - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK) { - if (screen_info->glx_version >= 1.3f) { - screen_info->glx.make_context_current = - (glitz_glx_make_context_current_t) - glitz_glx_get_proc_address ("glXMakeContextCurrent", - (void *) screen_info); - } else { - screen_info->glx.make_context_current = - (glitz_glx_make_context_current_t) - glitz_glx_get_proc_address ("glXMakeCurrentReadSGI", - (void *) screen_info); + if (screen_info->glx_feature_mask & + GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK) { + if (screen_info->glx_version >= 1.4f) { + screen_info->glx.get_proc_address = (glitz_glx_get_proc_address_t) + glitz_glx_get_proc_address ("glXGetProcAddress", + (void *) screen_info); + } else { + screen_info->glx.get_proc_address = (glitz_glx_get_proc_address_t) + glitz_glx_get_proc_address ("glXGetProcAddressARB", + (void *) screen_info); + } + + if (!screen_info->glx.get_proc_address) + screen_info->glx_feature_mask &= + ~GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK; } - - if (!screen_info->glx.make_context_current) - screen_info->glx_feature_mask &= - ~GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK; - } - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK) { - if (screen_info->glx_version >= 1.4f) { - screen_info->glx.get_proc_address = (glitz_glx_get_proc_address_t) - glitz_glx_get_proc_address ("glXGetProcAddress", (void *) screen_info); - } else { - screen_info->glx.get_proc_address = (glitz_glx_get_proc_address_t) - glitz_glx_get_proc_address ("glXGetProcAddressARB", - (void *) screen_info); - } - - if (!screen_info->glx.get_proc_address) - screen_info->glx_feature_mask &= - ~GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK; - } } static void @@ -258,27 +283,27 @@ _glitz_glx_screen_destroy (glitz_glx_screen_info_t *screen_info); static void _glitz_glx_thread_info_fini (glitz_glx_thread_info_t *thread_info) { - int i; - - for (i = 0; i < thread_info->n_displays; i++) - _glitz_glx_display_destroy (thread_info->displays[i]); - - free (thread_info->displays); - - thread_info->displays = NULL; - thread_info->n_displays = 0; - - if (thread_info->gl_library) { - free (thread_info->gl_library); - thread_info->gl_library = NULL; - } + int i; - if (thread_info->dlhand) { - dlclose (thread_info->dlhand); - thread_info->dlhand = NULL; - } - - thread_info->cctx = NULL; + for (i = 0; i < thread_info->n_displays; i++) + _glitz_glx_display_destroy (thread_info->displays[i]); + + free (thread_info->displays); + + thread_info->displays = NULL; + thread_info->n_displays = 0; + + if (thread_info->gl_library) { + free (thread_info->gl_library); + thread_info->gl_library = NULL; + } + + if (thread_info->dlhand) { + dlclose (thread_info->dlhand); + thread_info->dlhand = NULL; + } + + thread_info->cctx = NULL; } #ifdef XTHREADS @@ -293,108 +318,108 @@ static xthread_key_t info_tsd; static void _glitz_glx_thread_info_init (glitz_glx_thread_info_t *thread_info) { - thread_info->displays = NULL; - thread_info->n_displays = 0; - thread_info->gl_library = NULL; - thread_info->dlhand = NULL; - thread_info->cctx = NULL; + thread_info->displays = NULL; + thread_info->n_displays = 0; + thread_info->gl_library = NULL; + thread_info->dlhand = NULL; + thread_info->cctx = NULL; } static void _glitz_glx_thread_info_destroy (glitz_glx_thread_info_t *thread_info) { - xthread_set_specific (info_tsd, NULL); - - if (thread_info) { - _glitz_glx_thread_info_fini (thread_info); - free (thread_info); - } + xthread_set_specific (info_tsd, NULL); + + if (thread_info) { + _glitz_glx_thread_info_fini (thread_info); + free (thread_info); + } } static void _tsd_destroy (void *p) { - if (p) { - _glitz_glx_thread_info_fini ((glitz_glx_thread_info_t *) p); - free (p); - } + if (p) { + _glitz_glx_thread_info_fini ((glitz_glx_thread_info_t *) p); + free (p); + } } static glitz_glx_thread_info_t * _glitz_glx_thread_info_get (const char *gl_library) { - glitz_glx_thread_info_t *thread_info; - void *p; - - if (!tsd_initialized) { - xthread_key_create (&info_tsd, _tsd_destroy); - tsd_initialized = 1; - } - - xthread_get_specific (info_tsd, &p); - - if (p == NULL) { - thread_info = malloc (sizeof (glitz_glx_thread_info_t)); - _glitz_glx_thread_info_init (thread_info); - - xthread_set_specific (info_tsd, thread_info); - } else - thread_info = (glitz_glx_thread_info_t *) p; - - if (gl_library) { - int len = strlen (gl_library); + glitz_glx_thread_info_t *thread_info; + void *p; - if (thread_info->gl_library) { - free (thread_info->gl_library); - thread_info->gl_library = NULL; + if (!tsd_initialized) { + xthread_key_create (&info_tsd, _tsd_destroy); + tsd_initialized = 1; } - - thread_info->gl_library = malloc (len + 1); - if (thread_info->gl_library) { - memcpy (thread_info->gl_library, gl_library, len); - thread_info->gl_library[len] = '\0'; + + xthread_get_specific (info_tsd, &p); + + if (p == NULL) { + thread_info = malloc (sizeof (glitz_glx_thread_info_t)); + _glitz_glx_thread_info_init (thread_info); + + xthread_set_specific (info_tsd, thread_info); + } else + thread_info = (glitz_glx_thread_info_t *) p; + + if (gl_library) { + int len = strlen (gl_library); + + if (thread_info->gl_library) { + free (thread_info->gl_library); + thread_info->gl_library = NULL; + } + + thread_info->gl_library = malloc (len + 1); + if (thread_info->gl_library) { + memcpy (thread_info->gl_library, gl_library, len); + thread_info->gl_library[len] = '\0'; + } } - } - return thread_info; + return thread_info; } #else /* not thread safe */ static glitz_glx_thread_info_t thread_info = { - NULL, - 0, - NULL, - NULL + NULL, + 0, + NULL, + NULL }; static void _glitz_glx_thread_info_destroy (glitz_glx_thread_info_t *thread_info) { - if (thread_info) - _glitz_glx_thread_info_fini (thread_info); + if (thread_info) + _glitz_glx_thread_info_fini (thread_info); } static glitz_glx_thread_info_t * _glitz_glx_thread_info_get (const char *gl_library) { - if (gl_library) { - int len = strlen (gl_library); - - if (thread_info.gl_library) { - free (thread_info.gl_library); - thread_info.gl_library = NULL; - } - - thread_info.gl_library = malloc (len + 1); - if (thread_info.gl_library) { - memcpy (thread_info.gl_library, gl_library, len); - thread_info.gl_library[len] = '\0'; + if (gl_library) { + int len = strlen (gl_library); + + if (thread_info.gl_library) { + free (thread_info.gl_library); + thread_info.gl_library = NULL; + } + + thread_info.gl_library = malloc (len + 1); + if (thread_info.gl_library) { + memcpy (thread_info.gl_library, gl_library, len); + thread_info.gl_library[len] = '\0'; + } } - } - - return &thread_info; + + return &thread_info; } #endif @@ -402,143 +427,142 @@ _glitz_glx_thread_info_get (const char *gl_library) static glitz_glx_display_info_t * _glitz_glx_display_info_get (Display *display) { - glitz_glx_display_info_t *display_info; - glitz_glx_thread_info_t *thread_info = _glitz_glx_thread_info_get (NULL); - glitz_glx_display_info_t **displays = thread_info->displays; - int index, n_displays = thread_info->n_displays; - - for (; n_displays; n_displays--, displays++) - if ((*displays)->display == display) - return *displays; - - index = thread_info->n_displays++; - - thread_info->displays = - realloc (thread_info->displays, - sizeof (glitz_glx_display_info_t *) * thread_info->n_displays); - - display_info = malloc (sizeof (glitz_glx_display_info_t)); - thread_info->displays[index] = display_info; - - display_info->thread_info = thread_info; - display_info->display = display; - display_info->screens = NULL; - display_info->n_screens = 0; - - return display_info; + glitz_glx_display_info_t *display_info; + glitz_glx_thread_info_t *thread_info = _glitz_glx_thread_info_get (NULL); + glitz_glx_display_info_t **displays = thread_info->displays; + int index, n_displays = thread_info->n_displays; + + for (; n_displays; n_displays--, displays++) + if ((*displays)->display == display) + return *displays; + + index = thread_info->n_displays++; + + thread_info->displays = + realloc (thread_info->displays, + sizeof (glitz_glx_display_info_t *) * + thread_info->n_displays); + + display_info = malloc (sizeof (glitz_glx_display_info_t)); + thread_info->displays[index] = display_info; + + display_info->thread_info = thread_info; + display_info->display = display; + display_info->screens = NULL; + display_info->n_screens = 0; + + return display_info; } static void _glitz_glx_display_destroy (glitz_glx_display_info_t *display_info) { - int i; - - for (i = 0; i < display_info->n_screens; i++) - _glitz_glx_screen_destroy (display_info->screens[i]); - - if (display_info->screens) - free (display_info->screens); - - free (display_info); + int i; + + for (i = 0; i < display_info->n_screens; i++) + _glitz_glx_screen_destroy (display_info->screens[i]); + + if (display_info->screens) + free (display_info->screens); + + free (display_info); } glitz_glx_screen_info_t * glitz_glx_screen_info_get (Display *display, - int screen) + int screen) { - glitz_glx_screen_info_t *screen_info; - glitz_glx_display_info_t *display_info = - _glitz_glx_display_info_get (display); - glitz_glx_screen_info_t **screens = display_info->screens; - int error_base, event_base, index, n_screens = display_info->n_screens; - - for (; n_screens; n_screens--, screens++) - if ((*screens)->screen == screen) - return *screens; - - index = display_info->n_screens++; - - display_info->screens = - realloc (display_info->screens, - sizeof (glitz_glx_screen_info_t *) * display_info->n_screens); - - screen_info = malloc (sizeof (glitz_glx_screen_info_t)); - display_info->screens[index] = screen_info; - - screen_info->display_info = display_info; - screen_info->screen = screen; - screen_info->drawables = 0; - screen_info->formats = NULL; - screen_info->format_ids = NULL; - screen_info->n_formats = 0; - - screen_info->contexts = NULL; - screen_info->n_contexts = 0; - - memset (&screen_info->glx, 0, sizeof (glitz_glx_static_proc_address_list_t)); - - glitz_program_map_init (&screen_info->program_map); - - screen_info->root_context = (GLXContext) 0; - screen_info->glx_feature_mask = 0; - - if (glXQueryExtension (display, &error_base, &event_base)) { - int major, minor; - - if (glXQueryVersion (display, &major, &minor)) { - screen_info->glx_version = major + minor / 10.0f; - if (major > 1 || (major > 0 || minor >= 2)) { - glitz_glx_query_extensions (screen_info, screen_info->glx_version); - _glitz_glx_proc_address_lookup (screen_info); - glitz_glx_query_formats (screen_info); - } + glitz_glx_screen_info_t *screen_info; + glitz_glx_display_info_t *display_info = + _glitz_glx_display_info_get (display); + glitz_glx_screen_info_t **screens = display_info->screens; + int error_base, event_base, index, n_screens = display_info->n_screens; + + for (; n_screens; n_screens--, screens++) + if ((*screens)->screen == screen) + return *screens; + + index = display_info->n_screens++; + + display_info->screens = + realloc (display_info->screens, + sizeof (glitz_glx_screen_info_t *) * display_info->n_screens); + + screen_info = malloc (sizeof (glitz_glx_screen_info_t)); + display_info->screens[index] = screen_info; + + screen_info->display_info = display_info; + screen_info->screen = screen; + screen_info->drawables = 0; + screen_info->formats = NULL; + screen_info->n_formats = 0; + + screen_info->contexts = NULL; + screen_info->n_contexts = 0; + + memset (&screen_info->glx, 0, + sizeof (glitz_glx_static_proc_address_list_t)); + + glitz_program_map_init (&screen_info->program_map); + + screen_info->root_context = (GLXContext) 0; + screen_info->glx_feature_mask = 0; + + if (glXQueryExtension (display, &error_base, &event_base)) { + int major, minor; + + if (glXQueryVersion (display, &major, &minor)) { + screen_info->glx_version = major + minor / 10.0f; + if (major > 1 || (major > 0 || minor >= 2)) { + glitz_glx_query_extensions (screen_info, + screen_info->glx_version); + _glitz_glx_proc_address_lookup (screen_info); + glitz_glx_query_formats (screen_info); + } + } } - } - - screen_info->context_stack_size = 1; - screen_info->context_stack->drawable = NULL; - screen_info->context_stack->surface = NULL; - screen_info->context_stack->constraint = GLITZ_NONE; - - return screen_info; + + screen_info->context_stack_size = 1; + screen_info->context_stack->drawable = NULL; + screen_info->context_stack->surface = NULL; + screen_info->context_stack->constraint = GLITZ_NONE; + + return screen_info; } static void _glitz_glx_screen_destroy (glitz_glx_screen_info_t *screen_info) { - Display *display = screen_info->display_info->display; - int i; + Display *display = screen_info->display_info->display; + int i; + + if (screen_info->root_context) + glXMakeCurrent (display, None, NULL); - if (screen_info->root_context) - glXMakeCurrent (display, None, NULL); - - for (i = 0; i < screen_info->n_contexts; i++) - glitz_glx_context_destroy (screen_info, screen_info->contexts[i]); + for (i = 0; i < screen_info->n_contexts; i++) + glitz_glx_context_destroy (screen_info, screen_info->contexts[i]); - if (screen_info->contexts) - free (screen_info->contexts); - - if (screen_info->formats) - free (screen_info->formats); + if (screen_info->contexts) + free (screen_info->contexts); - if (screen_info->format_ids) - free (screen_info->format_ids); + if (screen_info->formats) + free (screen_info->formats); - free (screen_info); + free (screen_info); } void glitz_glx_init (const char *gl_library) { - _glitz_glx_thread_info_get (gl_library); + _glitz_glx_thread_info_get (gl_library); } slim_hidden_def(glitz_glx_init); void glitz_glx_fini (void) { - glitz_glx_thread_info_t *info = _glitz_glx_thread_info_get (NULL); + glitz_glx_thread_info_t *info = _glitz_glx_thread_info_get (NULL); - _glitz_glx_thread_info_destroy (info); + _glitz_glx_thread_info_destroy (info); } slim_hidden_def(glitz_glx_fini); diff --git a/src/glx/glitz_glx_pbuffer.c b/src/glx/glitz_glx_pbuffer.c index 3af899f..b5a9ecf 100644 --- a/src/glx/glitz_glx_pbuffer.c +++ b/src/glx/glitz_glx_pbuffer.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -31,37 +31,37 @@ GLXPbuffer glitz_glx_pbuffer_create (glitz_glx_screen_info_t *screen_info, - GLXFBConfig fbconfig, - int width, - int height) + GLXFBConfig fbconfig, + int width, + int height) { - if (fbconfig) { - int attributes[9]; + Display *dpy = screen_info->display_info->display; + + if (fbconfig) { + int attributes[9]; + + attributes[0] = GLX_PBUFFER_WIDTH; + attributes[1] = width; - attributes[0] = GLX_PBUFFER_WIDTH; - attributes[1] = width; + attributes[2] = GLX_PBUFFER_HEIGHT; + attributes[3] = height; - attributes[2] = GLX_PBUFFER_HEIGHT; - attributes[3] = height; - - attributes[4] = GLX_LARGEST_PBUFFER; - attributes[5] = 0; + attributes[4] = GLX_LARGEST_PBUFFER; + attributes[5] = 0; - attributes[6] = GLX_PRESERVED_CONTENTS; - attributes[7] = 1; - attributes[8] = 0; + attributes[6] = GLX_PRESERVED_CONTENTS; + attributes[7] = 1; + attributes[8] = 0; - return - screen_info->glx.create_pbuffer (screen_info->display_info->display, - fbconfig, attributes); - } else - return (GLXPbuffer) 0; + return screen_info->glx.create_pbuffer (dpy, fbconfig, attributes); + } else + return (GLXPbuffer) 0; } -void +void glitz_glx_pbuffer_destroy (glitz_glx_screen_info_t *screen_info, - GLXPbuffer pbuffer) + GLXPbuffer pbuffer) { - screen_info->glx.destroy_pbuffer (screen_info->display_info->display, - pbuffer); + screen_info->glx.destroy_pbuffer (screen_info->display_info->display, + pbuffer); } diff --git a/src/glx/glitz_glxext.h b/src/glx/glitz_glxext.h index fd8bde0..015e76a 100644 --- a/src/glx/glitz_glxext.h +++ b/src/glx/glitz_glxext.h @@ -95,25 +95,25 @@ typedef XID GLXPbuffer; #endif typedef glitz_function_pointer_t (* glitz_glx_get_proc_address_t) - (const glitz_gl_ubyte_t *); + (const glitz_gl_ubyte_t *); typedef GLXFBConfig *(* glitz_glx_get_fbconfigs_t) - (Display *display, int screen, int *n_elements); + (Display *display, int screen, int *n_elements); typedef int (* glitz_glx_get_fbconfig_attrib_t) - (Display *display, GLXFBConfig config, int attribute, int *value); + (Display *display, GLXFBConfig config, int attribute, int *value); typedef XVisualInfo *(* glitz_glx_get_visual_from_fbconfig_t) - (Display *display, GLXFBConfig config); + (Display *display, GLXFBConfig config); typedef GLXPbuffer (* glitz_glx_create_pbuffer_t) - (Display *display, GLXFBConfig config, const int *attrib_list); + (Display *display, GLXFBConfig config, const int *attrib_list); typedef void (* glitz_glx_destroy_pbuffer_t) - (Display *display, GLXPbuffer pbuffer); + (Display *display, GLXPbuffer pbuffer); typedef void (* glitz_glx_query_drawable_t) - (Display *display, GLXDrawable drawable, - int attribute, unsigned int *value); + (Display *display, GLXDrawable drawable, + int attribute, unsigned int *value); typedef Bool (* glitz_glx_make_context_current_t) - (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); typedef GLXContext (* glitz_glx_create_new_context_t) - (Display *display, GLXFBConfig config, int render_type, - GLXContext share_list, Bool direct); + (Display *display, GLXFBConfig config, int render_type, + GLXContext share_list, Bool direct); #ifndef GLX_ARB_multisample #define GLX_SAMPLE_BUFFERS_ARB 0x186a0 @@ -121,8 +121,8 @@ typedef GLXContext (* glitz_glx_create_new_context_t) #endif typedef Bool *(* glitz_glx_bind_tex_image_t) - (Display *display, GLXPbuffer pbuffer, int buffer); + (Display *display, GLXPbuffer pbuffer, int buffer); typedef Bool (* glitz_glx_release_tex_image_t) - (Display *display, GLXPbuffer pbuffer, int buffer); + (Display *display, GLXPbuffer pbuffer, int buffer); #endif /* GLITZ_GLXEXT_H_INCLUDED */ diff --git a/src/glx/glitz_glxint.h b/src/glx/glitz_glxint.h index 023a79b..fde6719 100644 --- a/src/glx/glitz_glxint.h +++ b/src/glx/glitz_glxint.h @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -36,139 +36,143 @@ #include "glitz_glxext.h" -#define GLITZ_GLX_FEATURE_FBCONFIG_MASK (1L << 0) -#define GLITZ_GLX_FEATURE_PBUFFER_MASK (1L << 1) -#define GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK (1L << 2) -#define GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK (1L << 3) -#define GLITZ_GLX_FEATURE_MULTISAMPLE_MASK (1L << 4) -#define GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 5) +#define GLITZ_GLX_FEATURE_VISUAL_RATING_MASK (1L << 0) +#define GLITZ_GLX_FEATURE_FBCONFIG_MASK (1L << 1) +#define GLITZ_GLX_FEATURE_PBUFFER_MASK (1L << 2) +#define GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK (1L << 3) +#define GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK (1L << 4) +#define GLITZ_GLX_FEATURE_MULTISAMPLE_MASK (1L << 5) +#define GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 6) typedef struct _glitz_glx_drawable glitz_glx_drawable_t; typedef struct _glitz_glx_screen_info_t glitz_glx_screen_info_t; typedef struct _glitz_glx_display_info_t glitz_glx_display_info_t; typedef struct _glitz_glx_static_proc_address_list_t { - glitz_glx_get_proc_address_t get_proc_address; - glitz_glx_get_fbconfigs_t get_fbconfigs; - glitz_glx_get_fbconfig_attrib_t get_fbconfig_attrib; - glitz_glx_get_visual_from_fbconfig_t get_visual_from_fbconfig; - glitz_glx_create_pbuffer_t create_pbuffer; - glitz_glx_destroy_pbuffer_t destroy_pbuffer; - glitz_glx_query_drawable_t query_drawable; - glitz_glx_make_context_current_t make_context_current; - glitz_glx_create_new_context_t create_new_context; + glitz_glx_get_proc_address_t get_proc_address; + glitz_glx_get_fbconfigs_t get_fbconfigs; + glitz_glx_get_fbconfig_attrib_t get_fbconfig_attrib; + glitz_glx_get_visual_from_fbconfig_t get_visual_from_fbconfig; + glitz_glx_create_pbuffer_t create_pbuffer; + glitz_glx_destroy_pbuffer_t destroy_pbuffer; + glitz_glx_query_drawable_t query_drawable; + glitz_glx_make_context_current_t make_context_current; + glitz_glx_create_new_context_t create_new_context; } glitz_glx_static_proc_address_list_t; typedef struct _glitz_glx_thread_info_t { - glitz_glx_display_info_t **displays; - int n_displays; - char *gl_library; - void *dlhand; - glitz_context_t *cctx; + glitz_glx_display_info_t **displays; + int n_displays; + char *gl_library; + void *dlhand; + glitz_context_t *cctx; } glitz_glx_thread_info_t; struct _glitz_glx_display_info_t { - glitz_glx_thread_info_t *thread_info; - Display *display; - glitz_glx_screen_info_t **screens; - int n_screens; + glitz_glx_thread_info_t *thread_info; + Display *display; + glitz_glx_screen_info_t **screens; + int n_screens; }; typedef struct _glitz_glx_context_info_t { - glitz_glx_drawable_t *drawable; - glitz_surface_t *surface; - glitz_constraint_t constraint; + glitz_glx_drawable_t *drawable; + glitz_surface_t *surface; + glitz_constraint_t constraint; } glitz_glx_context_info_t; typedef struct _glitz_glx_context_t { - glitz_context_t base; - GLXContext context; - glitz_format_id_t id; - GLXFBConfig fbconfig; - glitz_backend_t backend; - glitz_gl_int_t max_viewport_dims[2]; - glitz_gl_int_t max_texture_2d_size; - glitz_gl_int_t max_texture_rect_size; - glitz_bool_t initialized; + glitz_context_t base; + GLXContext context; + glitz_format_id_t id; + GLXFBConfig fbconfig; + glitz_backend_t backend; + glitz_bool_t initialized; } glitz_glx_context_t; struct _glitz_glx_screen_info_t { - glitz_glx_display_info_t *display_info; - int screen; - int drawables; - glitz_drawable_format_t *formats; - XID *format_ids; - int n_formats; - glitz_glx_context_t **contexts; - int n_contexts; - glitz_glx_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; - int context_stack_size; - GLXContext root_context; - unsigned long glx_feature_mask; - glitz_gl_float_t glx_version; - glitz_glx_static_proc_address_list_t glx; - glitz_program_map_t program_map; + glitz_glx_display_info_t *display_info; + int screen; + int drawables; + glitz_int_drawable_format_t *formats; + int n_formats; + glitz_glx_context_t **contexts; + int n_contexts; + glitz_glx_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; + int context_stack_size; + GLXContext root_context; + unsigned long glx_feature_mask; + glitz_gl_float_t glx_version; + glitz_glx_static_proc_address_list_t glx; + glitz_program_map_t program_map; }; struct _glitz_glx_drawable { - glitz_drawable_t base; - - glitz_glx_screen_info_t *screen_info; - glitz_glx_context_t *context; - GLXDrawable drawable; - GLXDrawable pbuffer; + glitz_drawable_t base; + + glitz_glx_screen_info_t *screen_info; + glitz_glx_context_t *context; + GLXDrawable drawable; + GLXDrawable pbuffer; + int width; + int height; }; extern void __internal_linkage glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info, - glitz_gl_float_t glx_version); + glitz_gl_float_t glx_version); extern glitz_glx_screen_info_t __internal_linkage * glitz_glx_screen_info_get (Display *display, - int screen); + int screen); extern glitz_function_pointer_t __internal_linkage glitz_glx_get_proc_address (const char *name, - void *closure); + void *closure); extern glitz_glx_context_t __internal_linkage * glitz_glx_context_get (glitz_glx_screen_info_t *screen_info, - glitz_drawable_format_t *format); + glitz_drawable_format_t *format); extern void __internal_linkage glitz_glx_context_destroy (glitz_glx_screen_info_t *screen_info, - glitz_glx_context_t *context); + glitz_glx_context_t *context); extern void __internal_linkage glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info); +extern glitz_bool_t __internal_linkage +_glitz_glx_drawable_update_size (glitz_glx_drawable_t *drawable, + int width, + int height); + extern GLXPbuffer __internal_linkage glitz_glx_pbuffer_create (glitz_glx_screen_info_t *screen_info, - GLXFBConfig fbconfig, - int width, - int height); + GLXFBConfig fbconfig, + int width, + int height); extern void __internal_linkage glitz_glx_pbuffer_destroy (glitz_glx_screen_info_t *screen_info, - GLXPbuffer pbuffer); + GLXPbuffer pbuffer); extern glitz_drawable_t __internal_linkage * glitz_glx_create_pbuffer (void *abstract_templ, - glitz_drawable_format_t *format, - unsigned int width, - unsigned int height); + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); -extern void __internal_linkage +extern glitz_bool_t __internal_linkage glitz_glx_push_current (void *abstract_drawable, - glitz_surface_t *surface, - glitz_constraint_t constraint); + glitz_surface_t *surface, + glitz_constraint_t constraint); extern glitz_surface_t __internal_linkage * glitz_glx_pop_current (void *abstract_drawable); void glitz_glx_make_current (void *abstract_drawable, - glitz_constraint_t constraint); + glitz_constraint_t constraint); extern glitz_status_t __internal_linkage glitz_glx_make_current_read (void *abstract_surface); @@ -176,14 +180,15 @@ glitz_glx_make_current_read (void *abstract_surface); extern void __internal_linkage glitz_glx_destroy (void *abstract_drawable); -extern void __internal_linkage +extern glitz_bool_t __internal_linkage glitz_glx_swap_buffers (void *abstract_drawable); -/* Avoid unnecessary PLT entries. */ +/* Avoid unnecessary PLT entries. */ slim_hidden_proto(glitz_glx_init) slim_hidden_proto(glitz_glx_fini) -slim_hidden_proto(glitz_glx_find_drawable_format) +slim_hidden_proto(glitz_glx_find_window_format) +slim_hidden_proto(glitz_glx_find_pbuffer_format) slim_hidden_proto(glitz_glx_find_drawable_format_for_visual) slim_hidden_proto(glitz_glx_get_visual_info_from_format) slim_hidden_proto(glitz_glx_create_drawable_for_window) |