diff options
author | David Reveman <davidr@novell.com> | 2004-04-28 08:59:38 +0000 |
---|---|---|
committer | David Reveman <davidr@novell.com> | 2004-04-28 08:59:38 +0000 |
commit | 14b8f0268696e867ef1c87d174e0ab4c233e691b (patch) | |
tree | c4a36d7caa3027d0cf7d5c6e3e1812bc54df4354 | |
parent | ffe7e1d21cef1ab1e576274f774f86a47f58317b (diff) |
Added support for direct compositing with mask surface only using multi-texturing
-rw-r--r-- | ChangeLog | 51 | ||||
-rw-r--r-- | src/glitz.c | 44 | ||||
-rw-r--r-- | src/glitz.h | 6 | ||||
-rw-r--r-- | src/glitz_agl_extension.c | 24 | ||||
-rw-r--r-- | src/glitz_agl_pbuffer.c | 2 | ||||
-rw-r--r-- | src/glitz_agl_surface.c | 22 | ||||
-rw-r--r-- | src/glitz_aglint.h | 5 | ||||
-rw-r--r-- | src/glitz_format.c | 45 | ||||
-rw-r--r-- | src/glitz_gl.h | 16 | ||||
-rw-r--r-- | src/glitz_glx_extension.c | 27 | ||||
-rw-r--r-- | src/glitz_glx_surface.c | 23 | ||||
-rw-r--r-- | src/glitz_glxint.h | 21 | ||||
-rw-r--r-- | src/glitz_program.c | 76 | ||||
-rw-r--r-- | src/glitz_surface.c | 142 | ||||
-rw-r--r-- | src/glitz_texture.c | 12 | ||||
-rw-r--r-- | src/glitz_util.c | 2 | ||||
-rw-r--r-- | src/glitzint.h | 16 |
17 files changed, 333 insertions, 201 deletions
@@ -1,3 +1,54 @@ +2004-04-28 David Reveman <c99drn@cs.umu.se> + + * src/glitzint.h: Added internal_format to glitz_texture_t. Added + SURFACE_SOLID macro. Removed glitz_format_find_sufficient_standard. + + * src/glitz_util.c (glitz_get_gl_format_from_bpp): + Use GLITZ_GL_LUMINANCE_ALPHA instead of GLITZ_GL_ALPHA for + A8 surfaces. + + * src/glitz_texture.c: Added support for direct compositing with mask + surface only using multi-texturing. + + * src/glitz_surface.c: Added _glitz_surface_try_push_current. + Added support for direct compositing with mask surface only using + multi-texturing. + (glitz_surface_gl_begin): Removed unnecessary set of surface status. + + * src/glitz_program.c: Added support for direct compositing with + mask surface only using multi-texturing. + + * src/glitz_gl.h: Added GLITZ_GL_MODULATE and GLITZ_GL_LUMINANCE_ALPHA. + + * src/glitz_format.c: Removed glitz_format_find_sufficient_standard. + + * src/glitz_glxint.h: Added GLITZ_AGL_FEATURE_ARB_MULTITEXTURE_MASK. + + * src/glitz_aglint.h: Added GLITZ_AGL_FEATURE_ARB_MULTITEXTURE_MASK. + + * src/glitz_glx_surface.c (_glitz_glx_surface_create_similar): + Always use glitz_format_find_standard for similar surface formats. + (_glitz_glx_surface_push_current): Fixed invalid set of surface status. + + * src/glitz_agl_surface.c (_glitz_agl_surface_create_similar): + Always use glitz_format_find_standard for similar surface formats. + (_glitz_agl_surface_push_current): Fixed invalid set of surface status. + + * src/glitz_agl_pbuffer.c (glitz_agl_pbuffer_create): Use internal + format for pbuffer. + + * src/glitz_glx_extension.c: Detect GL_ARB_multitexture extension. + + * src/glitz_agl_extension.c: Detect GL_ARB_multitexture extension. + + * src/glitz.h (GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK): Added + GLITZ_FEATURE_ARB_MULTITEXTURE_MASK. + + * src/glitz.c (_glitz_composite_direct): Added support for + direct compositing with mask surface only using multi-texturing. + (glitz_composite): Solid mask surfaces are now supported by all + hardware. + 2004-04-25 David Reveman <c99drn@cs.umu.se> * src/glitz_programmatic.c (glitz_programmatic_surface_bind): diff --git a/src/glitz.c b/src/glitz.c index bd47c98..4e29691 100644 --- a/src/glitz.c +++ b/src/glitz.c @@ -138,7 +138,7 @@ _glitz_composite_direct (glitz_operator_t op, gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); + GLITZ_GL_MODULATE); if (mask->transform) glitz_texture_ensure_filter (gl, mask_texture, mask->filter); @@ -404,6 +404,7 @@ glitz_composite (glitz_operator_t op, glitz_point_t tl, bl, br, tr; glitz_region_box_t clip; glitz_program_type_t type = 0; + glitz_bool_t simple_modulate = 0; gl = dst->gl; @@ -412,17 +413,26 @@ glitz_composite (glitz_operator_t op, width + abs (x_src), height + abs (y_src)); - if (mask && SURFACE_PROGRAMMATIC (mask)) - glitz_programmatic_surface_setup (mask, - width + abs (x_mask), - height + abs (y_mask)); - if (mask) { + if (SURFACE_PROGRAMMATIC (mask)) + glitz_programmatic_surface_setup (mask, + width + abs (x_mask), + height + abs (y_mask)); + + if (SURFACE_SOLID (mask) && (!SURFACE_PROGRAMMATIC (src))) { + simple_modulate = 1; + if ((dst->feature_mask & GLITZ_FEATURE_CONVOLUTION_FILTER_MASK) && + src->convolution) + simple_modulate = 0; + } + } + + if (mask && (!simple_modulate)) { glitz_region_box_t mask_bounds; static glitz_color_t clear_color = { 0x0000, 0x0000, 0x0000, 0x0000 }; glitz_bool_t intermediate_translate; - if ((dst->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) && + if ((dst->feature_mask & GLITZ_FEATURE_ARB_MULTITEXTURE_MASK) && _glitz_composite_direct (op, src, mask, dst, x_src, y_src, @@ -532,10 +542,26 @@ glitz_composite (glitz_operator_t op, } glitz_texture_bind (gl, texture); - + gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); + (simple_modulate)? GLITZ_GL_MODULATE: GLITZ_GL_REPLACE); + + if (simple_modulate) { + glitz_programmatic_surface_t *m = (glitz_programmatic_surface_t *) mask; + + gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, + GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_MODULATE); + gl->color_4us (m->u.solid.color.alpha, + m->u.solid.color.alpha, + m->u.solid.color.alpha, + m->u.solid.color.alpha); + } else { + gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, + GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_REPLACE); + } clip.x1 = x_dst; clip.y1 = y_dst; diff --git a/src/glitz.h b/src/glitz.h index cea4291..2a65487 100644 --- a/src/glitz.h +++ b/src/glitz.h @@ -1,3 +1,4 @@ + /* * Copyright © 2004 David Reveman, Peter Nilsson * @@ -142,8 +143,9 @@ typedef enum { #define GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 4) #define GLITZ_FEATURE_MULTISAMPLE_MASK (1L << 5) #define GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK (1L << 6) -#define GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 7) -#define GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 8) +#define GLITZ_FEATURE_ARB_MULTITEXTURE_MASK (1L << 7) +#define GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 8) +#define GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 9) typedef enum { GLITZ_STANDARD_ARGB32, diff --git a/src/glitz_agl_extension.c b/src/glitz_agl_extension.c index 897186c..537c061 100644 --- a/src/glitz_agl_extension.c +++ b/src/glitz_agl_extension.c @@ -41,6 +41,7 @@ static glitz_extension_map gl_extensions[] = { { "GL_ARB_multisample", GLITZ_AGL_FEATURE_MULTISAMPLE_MASK }, { "GL_NV_multisample_filter_hint", GLITZ_AGL_FEATURE_MULTISAMPLE_FILTER_MASK }, + { "GL_ARB_multitexture", GLITZ_AGL_FEATURE_ARB_MULTITEXTURE_MASK }, { "GL_ARB_vertex_program", GLITZ_AGL_FEATURE_ARB_VERTEX_PROGRAM_MASK }, { "GL_ARB_fragment_program", GLITZ_AGL_FEATURE_ARB_FRAGMENT_PROGRAM_MASK }, { NULL, 0 } @@ -95,14 +96,19 @@ glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info) thread_info->feature_mask |= GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK; if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_ARB_VERTEX_PROGRAM_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK; - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK; + GLITZ_AGL_FEATURE_ARB_MULTITEXTURE_MASK) { + thread_info->feature_mask |= GLITZ_FEATURE_ARB_MULTITEXTURE_MASK; + + if (thread_info->agl_feature_mask & + GLITZ_AGL_FEATURE_ARB_VERTEX_PROGRAM_MASK) + thread_info->feature_mask |= GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK; + + if (thread_info->agl_feature_mask & + GLITZ_AGL_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) + thread_info->feature_mask |= GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK; - if ((thread_info->feature_mask & GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK) && - (thread_info->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK)) - thread_info->feature_mask |= GLITZ_FEATURE_CONVOLUTION_FILTER_MASK; + if ((thread_info->feature_mask & GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK) && + (thread_info->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK)) + thread_info->feature_mask |= GLITZ_FEATURE_CONVOLUTION_FILTER_MASK; + } } diff --git a/src/glitz_agl_pbuffer.c b/src/glitz_agl_pbuffer.c index 22c13b6..49380a8 100644 --- a/src/glitz_agl_pbuffer.c +++ b/src/glitz_agl_pbuffer.c @@ -39,7 +39,7 @@ glitz_agl_pbuffer_create (glitz_texture_t *texture) AGLPbuffer pbuffer; aglCreatePBuffer (texture->width, texture->height, - texture->target, GL_RGBA, 0, &pbuffer); + texture->target, texture->internal_format, 0, &pbuffer); return pbuffer; } diff --git a/src/glitz_agl_surface.c b/src/glitz_agl_surface.c index a6cf27d..b961c8f 100644 --- a/src/glitz_agl_surface.c +++ b/src/glitz_agl_surface.c @@ -57,10 +57,13 @@ _glitz_agl_surface_push_current (void *abstract_surface, glitz_constraint_t constraint) { glitz_agl_surface_t *surface = (glitz_agl_surface_t *) abstract_surface; + glitz_bool_t success = 1; if (constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT && - ((!surface->pbuffer) && (!surface->drawable))) + ((!surface->pbuffer) && (!surface->drawable))) { constraint = GLITZ_CN_ANY_CONTEXT_CURRENT; + success = 0; + } surface = glitz_agl_context_push_current (surface, constraint); @@ -69,10 +72,7 @@ _glitz_agl_surface_push_current (void *abstract_surface, return 1; } - if (constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT) - return 0; - else - return 1; + return success; } static void @@ -307,14 +307,10 @@ _glitz_agl_surface_create_similar (void *abstract_templ, GLITZ_AGL_FEATURE_PBUFFER_MASK)) { glitz_format_t *format; - format = glitz_format_find_sufficient_standard - (templ->base.format, 1, GLITZ_FORMAT_OPTION_OFFSCREEN_MASK, format_name); - - if (!format) - format = glitz_format_find_standard (templ->thread_info->formats, - templ->thread_info->n_formats, - GLITZ_FORMAT_OPTION_OFFSCREEN_MASK, - format_name); + format = glitz_format_find_standard (templ->thread_info->formats, + templ->thread_info->n_formats, + GLITZ_FORMAT_OPTION_OFFSCREEN_MASK, + format_name); if (format) return _glitz_agl_surface_create (templ->thread_info, format, diff --git a/src/glitz_aglint.h b/src/glitz_aglint.h index 2754765..2c917cd 100644 --- a/src/glitz_aglint.h +++ b/src/glitz_aglint.h @@ -42,8 +42,9 @@ #define GLITZ_AGL_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 3) #define GLITZ_AGL_FEATURE_MULTISAMPLE_MASK (1L << 4) #define GLITZ_AGL_FEATURE_MULTISAMPLE_FILTER_MASK (1L << 5) -#define GLITZ_AGL_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 6) -#define GLITZ_AGL_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 7) +#define GLITZ_AGL_FEATURE_ARB_MULTITEXTURE_MASK (1L << 6) +#define GLITZ_AGL_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 7) +#define GLITZ_AGL_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 8) typedef struct _glitz_agl_surface_t glitz_agl_surface_t; diff --git a/src/glitz_format.c b/src/glitz_format.c index e3ed580..9fe1556 100644 --- a/src/glitz_format.c +++ b/src/glitz_format.c @@ -160,8 +160,9 @@ glitz_format_find_standard (glitz_format_t *formats, 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; + unsigned long mask = GLITZ_FORMAT_RED_SIZE_MASK | + GLITZ_FORMAT_GREEN_SIZE_MASK | GLITZ_FORMAT_BLUE_SIZE_MASK | + GLITZ_FORMAT_ALPHA_SIZE_MASK; switch (format_name) { case GLITZ_STANDARD_ARGB32: @@ -195,46 +196,6 @@ glitz_format_find_standard (glitz_format_t *formats, return glitz_format_find (formats, n_formats, mask, &templ, 0); } -glitz_format_t * -glitz_format_find_sufficient_standard (glitz_format_t *formats, - int n_formats, - unsigned long options, - glitz_format_name_t format_name) -{ - glitz_format_t templ; - unsigned long mask; - - switch (format_name) { - case GLITZ_STANDARD_ARGB32: - mask = GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK | - GLITZ_FORMAT_BLUE_SIZE_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK; - templ.red_size = 8; - templ.green_size = 8; - templ.blue_size = 8; - templ.alpha_size = 8; - break; - case GLITZ_STANDARD_RGB24: - mask = GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK | - GLITZ_FORMAT_BLUE_SIZE_MASK; - templ.red_size = 8; - templ.green_size = 8; - templ.blue_size = 8; - break; - case GLITZ_STANDARD_A8: - mask = GLITZ_FORMAT_ALPHA_SIZE_MASK; - templ.alpha_size = 8; - break; - case GLITZ_STANDARD_A1: - mask = GLITZ_FORMAT_ALPHA_SIZE_MASK; - templ.alpha_size = 1; - break; - } - - _glitz_format_add_options (options, &templ, &mask); - - return glitz_format_find (formats, n_formats, mask, &templ, 0); -} - void glitz_format_calculate_pixel_transfer_info (glitz_format_t *format) { diff --git a/src/glitz_gl.h b/src/glitz_gl.h index 36f279b..a5de528 100644 --- a/src/glitz_gl.h +++ b/src/glitz_gl.h @@ -72,6 +72,7 @@ typedef unsigned char glitz_gl_ubyte_t; #define GLITZ_GL_TEXTURE_WRAP_T 0x2803 #define GLITZ_GL_TEXTURE_MAG_FILTER 0x2800 #define GLITZ_GL_TEXTURE_MIN_FILTER 0x2801 +#define GLITZ_GL_MODULATE 0x2100 #define GLITZ_GL_NEAREST 0x2600 #define GLITZ_GL_LINEAR 0x2601 #define GLITZ_GL_REPEAT 0x2901 @@ -92,13 +93,14 @@ typedef unsigned char glitz_gl_ubyte_t; #define GLITZ_GL_TRANSFORM_BIT 0x00001000 #define GLITZ_GL_COLOR_BUFFER_BIT 0x00004000 -#define GLITZ_GL_ALPHA 0x1906 -#define GLITZ_GL_RGB 0x1907 -#define GLITZ_GL_COLOR 0x1800 -#define GLITZ_GL_DITHER 0x0BD0 -#define GLITZ_GL_RGBA 0x1908 -#define GLITZ_GL_BGR 0x80E0 -#define GLITZ_GL_BGRA 0x80E1 +#define GLITZ_GL_ALPHA 0x1906 +#define GLITZ_GL_RGB 0x1907 +#define GLITZ_GL_LUMINANCE_ALPHA 0x190A +#define GLITZ_GL_COLOR 0x1800 +#define GLITZ_GL_DITHER 0x0BD0 +#define GLITZ_GL_RGBA 0x1908 +#define GLITZ_GL_BGR 0x80E0 +#define GLITZ_GL_BGRA 0x80E1 #define GLITZ_GL_FRONT_AND_BACK 0x0408 #define GLITZ_GL_FLAT 0x1D00 diff --git a/src/glitz_glx_extension.c b/src/glitz_glx_extension.c index cdf15d3..83db743 100644 --- a/src/glitz_glx_extension.c +++ b/src/glitz_glx_extension.c @@ -48,6 +48,7 @@ static glitz_extension_map client_glx_extensions[] = { { "GL_ARB_multisample", GLITZ_GLX_FEATURE_MULTISAMPLE_MASK }, { "GL_NV_multisample_filter_hint", GLITZ_GLX_FEATURE_MULTISAMPLE_FILTER_MASK }, + { "GL_ARB_multitexture", GLITZ_GLX_FEATURE_ARB_MULTITEXTURE_MASK }, { "GL_ARB_vertex_program", GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK }, { "GL_ARB_fragment_program", GLITZ_GLX_FEATURE_ARB_FRAGMENT_PROGRAM_MASK }, { NULL, 0 } @@ -126,19 +127,19 @@ glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info) screen_info->glx_feature_mask |= GLITZ_GLX_FEATURE_ARB_RENDER_TEXTURE_MASK; if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK) { - screen_info->glx_feature_mask |= GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK; - screen_info->feature_mask |= GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK; - } + GLITZ_GLX_FEATURE_ARB_MULTITEXTURE_MASK) { + screen_info->feature_mask |= GLITZ_FEATURE_ARB_MULTITEXTURE_MASK; - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) { - screen_info->glx_feature_mask |= - GLITZ_GLX_FEATURE_ARB_FRAGMENT_PROGRAM_MASK; - screen_info->feature_mask |= GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK; - } + if (screen_info->glx_feature_mask & + GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK) + screen_info->feature_mask |= GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK; - if ((screen_info->feature_mask & GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK) && - (screen_info->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK)) - screen_info->feature_mask |= GLITZ_FEATURE_CONVOLUTION_FILTER_MASK; + if (screen_info->glx_feature_mask & + GLITZ_GLX_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) + screen_info->feature_mask |= GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK; + + if ((screen_info->feature_mask & GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK) && + (screen_info->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK)) + screen_info->feature_mask |= GLITZ_FEATURE_CONVOLUTION_FILTER_MASK; + } } diff --git a/src/glitz_glx_surface.c b/src/glitz_glx_surface.c index 4384084..49b46db 100644 --- a/src/glitz_glx_surface.c +++ b/src/glitz_glx_surface.c @@ -55,9 +55,13 @@ _glitz_glx_surface_push_current (void *abstract_surface, glitz_constraint_t constraint) { glitz_glx_surface_t *surface = (glitz_glx_surface_t *) abstract_surface; + glitz_bool_t success = 1; - if (constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT && (!surface->drawable)) + if (constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT && + (!surface->drawable)) { constraint = GLITZ_CN_ANY_CONTEXT_CURRENT; + success = 0; + } surface = glitz_glx_context_push_current (surface, constraint); @@ -66,10 +70,7 @@ _glitz_glx_surface_push_current (void *abstract_surface, return 1; } - if (constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT) - return 0; - else - return 1; + return success; } static void @@ -335,14 +336,10 @@ _glitz_glx_surface_create_similar (void *abstract_templ, GLITZ_FEATURE_OFFSCREEN_DRAWING_MASK)) { glitz_format_t *format; - format = glitz_format_find_sufficient_standard - (templ->base.format, 1, GLITZ_FORMAT_OPTION_OFFSCREEN_MASK, format_name); - - if (!format) - format = glitz_format_find_standard (templ->screen_info->formats, - templ->screen_info->n_formats, - GLITZ_FORMAT_OPTION_OFFSCREEN_MASK, - format_name); + format = glitz_format_find_standard (templ->screen_info->formats, + templ->screen_info->n_formats, + GLITZ_FORMAT_OPTION_OFFSCREEN_MASK, + format_name); if (format) return _glitz_glx_surface_create (templ->screen_info, format, width, height); diff --git a/src/glitz_glxint.h b/src/glitz_glxint.h index d6a2d28..ccc0118 100644 --- a/src/glitz_glxint.h +++ b/src/glitz_glxint.h @@ -37,16 +37,17 @@ #include "glitz_glxext.h" -#define GLITZ_GLX_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 0) -#define GLITZ_GLX_FEATURE_TEXTURE_NPOT_MASK (1L << 1) -#define GLITZ_GLX_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 2) -#define GLITZ_GLX_FEATURE_MULTISAMPLE_MASK (1L << 3) -#define GLITZ_GLX_FEATURE_CLIENT_MULTISAMPLE_MASK (1L << 4) -#define GLITZ_GLX_FEATURE_MULTISAMPLE_FILTER_MASK (1L << 5) -#define GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 6) -#define GLITZ_GLX_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 7) -#define GLITZ_GLX_FEATURE_GLX13_MASK (1L << 8) -#define GLITZ_GLX_FEATURE_ARB_RENDER_TEXTURE_MASK (1L << 9) +#define GLITZ_GLX_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 0) +#define GLITZ_GLX_FEATURE_TEXTURE_NPOT_MASK (1L << 1) +#define GLITZ_GLX_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 2) +#define GLITZ_GLX_FEATURE_MULTISAMPLE_MASK (1L << 3) +#define GLITZ_GLX_FEATURE_CLIENT_MULTISAMPLE_MASK (1L << 4) +#define GLITZ_GLX_FEATURE_MULTISAMPLE_FILTER_MASK (1L << 5) +#define GLITZ_GLX_FEATURE_ARB_MULTITEXTURE_MASK (1L << 6) +#define GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 7) +#define GLITZ_GLX_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 8) +#define GLITZ_GLX_FEATURE_GLX13_MASK (1L << 9) +#define GLITZ_GLX_FEATURE_ARB_RENDER_TEXTURE_MASK (1L << 10) typedef struct _glitz_glx_surface glitz_glx_surface_t; typedef struct _glitz_glx_screen_info_t glitz_glx_screen_info_t; diff --git a/src/glitz_program.c b/src/glitz_program.c index 06e07a4..c6a6d71 100644 --- a/src/glitz_program.c +++ b/src/glitz_program.c @@ -517,7 +517,13 @@ glitz_program_enable_simple (glitz_gl_proc_address_list_t *gl, glitz_texture_t *src_texture, glitz_texture_t *mask_texture) { - int offset = _glitz_program_offset (src_texture, mask_texture); + int offset; + + /* This is done without fragment program */ + if (mask_texture->internal_format == GLITZ_GL_LUMINANCE_ALPHA) + return; + + offset = _glitz_program_offset (src_texture, mask_texture); if (!programs->fragment_simple[offset]) programs->fragment_simple[offset] = @@ -642,6 +648,16 @@ glitz_program_enable_programmatic (glitz_surface_t *dst, return; } + /* no fragment proram needed for solid programmatic surface and + mask in lumniance alpha texture format */ + if (dst->feature_mask & GLITZ_FEATURE_ARB_MULTITEXTURE_MASK) { + if ((surface->type == GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE) && + (mask_texture->internal_format == GLITZ_GL_LUMINANCE_ALPHA)) { + glitz_programmatic_surface_bind (dst->gl, surface, dst->feature_mask); + return; + } + } + if (dst->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) { if (!programs->fragment_programmatic[type_offset]) programs->fragment_programmatic[type_offset] = @@ -662,12 +678,11 @@ glitz_program_type (glitz_surface_t *dst, glitz_surface_t *src, glitz_surface_t *mask) { - glitz_program_type_t type = GLITZ_PROGRAM_TYPE_NONE; + glitz_program_type_t type = GLITZ_PROGRAM_TYPE_NOT_SUPPORTED; if (dst->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) { - if (dst->feature_mask & GLITZ_FEATURE_CONVOLUTION_FILTER_MASK) - + if (dst->feature_mask & GLITZ_FEATURE_CONVOLUTION_FILTER_MASK) { if (src->convolution) { if (mask && SURFACE_PROGRAMMATIC (mask) && ((glitz_programmatic_surface_t *) mask)->type == @@ -684,20 +699,21 @@ glitz_program_type (glitz_surface_t *dst, goto OK1; } - if (mask && mask->convolution) { - if (SURFACE_PROGRAMMATIC (src) && - ((glitz_programmatic_surface_t *) src)->type == - GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE) { - if (dst->feature_mask & GLITZ_FEATURE_CONVOLUTION_FILTER_MASK) { - type = GLITZ_PROGRAM_TYPE_MASK_CONVOLUTION_AND_SOLID_SRC; - goto OK2; - } else { - type = GLITZ_PROGRAM_TYPE_SRC_PROGRAMMATIC; - goto OK1; + if (mask && mask->convolution) { + if (SURFACE_PROGRAMMATIC (src) && + ((glitz_programmatic_surface_t *) src)->type == + GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE) { + if (dst->feature_mask & GLITZ_FEATURE_CONVOLUTION_FILTER_MASK) { + type = GLITZ_PROGRAM_TYPE_MASK_CONVOLUTION_AND_SOLID_SRC; + goto OK2; + } else { + type = GLITZ_PROGRAM_TYPE_SRC_PROGRAMMATIC; + goto OK1; + } } + type = GLITZ_PROGRAM_TYPE_MASK_CONVOLUTION; + goto OK1; } - type = GLITZ_PROGRAM_TYPE_MASK_CONVOLUTION; - goto OK1; } if (SURFACE_PROGRAMMATIC (src)) { @@ -708,25 +724,28 @@ glitz_program_type (glitz_surface_t *dst, if (mask && SURFACE_PROGRAMMATIC (mask)) { type = GLITZ_PROGRAM_TYPE_MASK_PROGRAMMATIC; goto OK1; - } + } } - - if (SURFACE_PROGRAMMATIC (src) && - ((glitz_programmatic_surface_t *) src)->type == - GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE) { + + if (SURFACE_SOLID (src)) { type = GLITZ_PROGRAM_TYPE_SRC_PROGRAMMATIC; goto OK1; } - - if (mask && SURFACE_PROGRAMMATIC (mask) && - ((glitz_programmatic_surface_t *) mask)->type == - GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE) { + + if (mask && SURFACE_SOLID (mask)) { type = GLITZ_PROGRAM_TYPE_MASK_PROGRAMMATIC; goto OK1; } - if (mask && (!SURFACE_PROGRAMMATIC (mask))) - type = GLITZ_PROGRAM_TYPE_SIMPLE; + if (mask && (!SURFACE_PROGRAMMATIC (mask))) { + if (dst->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) { + type = GLITZ_PROGRAM_TYPE_SIMPLE; + } else if ((mask->texture->internal_format == GLITZ_GL_LUMINANCE_ALPHA) && + (dst->feature_mask & GLITZ_FEATURE_ARB_MULTITEXTURE_MASK)) { + type = GLITZ_PROGRAM_TYPE_SIMPLE; + } else + type = GLITZ_PROGRAM_TYPE_NOT_SUPPORTED; + } OK1: if ((SURFACE_PROGRAMMATIC (src) || src->convolution) && @@ -767,7 +786,8 @@ glitz_program_enable (glitz_program_type_t type, GLITZ_PROGRAM_MASK_OPERATION_OFFSET, 2); break; case GLITZ_PROGRAM_TYPE_SRC_PROGRAMMATIC: - glitz_program_enable_programmatic (dst, (glitz_programmatic_surface_t *) src, + glitz_program_enable_programmatic (dst, + (glitz_programmatic_surface_t *) src, src_texture, mask_texture, GLITZ_PROGRAM_SRC_OPERATION_OFFSET); break; diff --git a/src/glitz_surface.c b/src/glitz_surface.c index d9b607b..2974201 100644 --- a/src/glitz_surface.c +++ b/src/glitz_surface.c @@ -130,6 +130,16 @@ glitz_surface_push_current (glitz_surface_t *surface, return 1; } +static glitz_bool_t +_glitz_surface_try_push_current (glitz_surface_t *surface, + glitz_constraint_t constraint) +{ + if (!surface->backend->push_current (surface, constraint)) + return 0; + + return 1; +} + void glitz_surface_pop_current (glitz_surface_t *surface) { @@ -517,9 +527,8 @@ glitz_surface_read_pixels (glitz_surface_t *surface, unsigned int height, char *pixels) { - unsigned char *pixel_buf; + unsigned char *pixel_buf = NULL; int rowstride, area_rowstride, bytes_per_pixel; - unsigned int i; glitz_gl_enum_t format, type; if (SURFACE_PROGRAMMATIC (surface)) @@ -538,13 +547,16 @@ glitz_surface_read_pixels (glitz_surface_t *surface, /* We currently read the whole image to a temporary buffer and then copy the part we want, not very efficient. We only want to read the area requested. I think it can be fixed with glPixelStore parameters. */ + if (_glitz_surface_try_push_current (surface, + GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) { - if (glitz_surface_push_current (surface, - GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) { - rowstride = surface->width * bytes_per_pixel; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - pixel_buf = (unsigned char *) malloc (surface->height * rowstride); - + if (format == GLITZ_GL_LUMINANCE_ALPHA) + rowstride = surface->width * 2; + else + rowstride = surface->width * bytes_per_pixel; + + rowstride = (rowstride + 3) & -4; + pixel_buf = malloc (surface->height * rowstride); surface->gl->read_pixels (0, 0, surface->width, surface->height, format, type, pixel_buf); } else { @@ -553,9 +565,13 @@ glitz_surface_read_pixels (glitz_surface_t *surface, texture = glitz_surface_get_texture (surface); glitz_texture_bind (surface->gl, texture); - rowstride = texture->width * bytes_per_pixel; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - pixel_buf = (unsigned char *) malloc (texture->height * rowstride); + if (format == GLITZ_GL_LUMINANCE_ALPHA) { + rowstride = texture->width * 2; + } else + rowstride = texture->width * bytes_per_pixel; + + rowstride = (rowstride + 3) & -4; + pixel_buf = malloc (texture->height * rowstride); surface->gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); surface->gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0); @@ -571,16 +587,31 @@ glitz_surface_read_pixels (glitz_surface_t *surface, glitz_surface_pop_current (surface); - area_rowstride = width * bytes_per_pixel; - area_rowstride += (area_rowstride % 4)? (4 - (area_rowstride % 4)): 0; + area_rowstride = (width * bytes_per_pixel + 3) & -4; - for (i = 0; i < height; i++) { - memcpy (&pixels[(height - i - 1) * area_rowstride], - &pixel_buf[(surface->height - y - height + i) * rowstride + x], - area_rowstride); + if (format == GLITZ_GL_LUMINANCE_ALPHA) { + int i, j, k; + + /* Unpad and flip A8 image data. */ + for (i = 0; i < (int) height; i++) { + for (j = 0, k = 1; j < (int) width; j++, k += 2) { + pixels[(height - i - 1) * area_rowstride + j] = + pixel_buf[(surface->height - y - height + i) * rowstride + x + k]; + } + } + } else { + int i; + + /* Flip image data. */ + for (i = 0; i < (int) height; i++) { + memcpy (&pixels[(height - i - 1) * area_rowstride], + &pixel_buf[(surface->height - y - height + i) * rowstride + x], + area_rowstride); + } } - - free (pixel_buf); + + if (pixel_buf) + free (pixel_buf); } slim_hidden_def(glitz_surface_read_pixels); @@ -592,9 +623,10 @@ glitz_surface_draw_pixels (glitz_surface_t *surface, unsigned int height, char *pixels) { - unsigned char *pixel_buf; + unsigned char *pixel_buf = NULL; glitz_gl_enum_t format, type; int bytes_per_pixel; + glitz_bool_t drawable = 0; if (SURFACE_PROGRAMMATIC (surface)) return; @@ -609,8 +641,41 @@ glitz_surface_draw_pixels (glitz_surface_t *surface, format = glitz_get_gl_format_from_bpp (surface->format->bpp); type = glitz_get_gl_data_type_from_bpp (surface->format->bpp); - if (glitz_surface_push_current (surface, - GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) { + drawable = + _glitz_surface_try_push_current (surface, + GLITZ_CN_SURFACE_DRAWABLE_CURRENT); + + if (format == GLITZ_GL_LUMINANCE_ALPHA) { + int i, j, k, src_rowstride, dst_rowstride; + + src_rowstride = (width + 3) & -4; + dst_rowstride = (width * 2 + 3) & -4; + pixel_buf = malloc (dst_rowstride * height); + + /* Pad and flip A8 image data. */ + for (i = 0; i < (int) height; i++) { + for (j = 0, k = 0; j < (int) width; j++, k += 2) { + pixel_buf[i * dst_rowstride + k] = + pixel_buf[i * dst_rowstride + k + 1] = + pixels[(height - i - 1) * src_rowstride + j]; + } + } + pixels = pixel_buf; + } else if (!drawable) { + int i, rowstride; + + rowstride = (width * bytes_per_pixel + 3) & -4; + pixel_buf = malloc (rowstride * height); + + /* Flip image data. */ + for (i = 0; i < (int) height; i++) + memcpy (&pixel_buf[i * rowstride], + &pixels[(height - i - 1) * rowstride], rowstride); + + pixels = pixel_buf; + } + + if (drawable) { glitz_region_box_t bounds; bounds.x1 = x; @@ -621,27 +686,20 @@ glitz_surface_draw_pixels (glitz_surface_t *surface, surface->gl->disable (GLITZ_GL_SCISSOR_TEST); surface->gl->disable (GLITZ_GL_DITHER); glitz_set_operator (surface->gl, GLITZ_OPERATOR_SRC); + + if (format == GLITZ_GL_LUMINANCE_ALPHA) { + surface->gl->pixel_zoom (1.0, 1.0); + _glitz_set_raster_pos (surface->gl, x, surface->height - y - height); + } else { + surface->gl->pixel_zoom (1.0, -1.0); + _glitz_set_raster_pos (surface->gl, x, surface->height - y); + } - surface->gl->pixel_zoom (1.0, -1.0); - - _glitz_set_raster_pos (surface->gl, x, surface->height - y); surface->gl->draw_pixels (width, height, format, type, pixels); glitz_surface_dirty (surface, &bounds); } else { - int i, rowstride; glitz_texture_t *texture; - - rowstride = width * bytes_per_pixel; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - pixel_buf = (unsigned char *) malloc (rowstride * height); - - /* TODO: This is very ugly and I like to remove it as soon as possible. - Needs some changes to texture handling, as images will become upside - down without it. */ - for (i = 0; i < (int) height; i++) - memcpy (&pixel_buf[i * rowstride], - &pixels[(height - i - 1) * rowstride], rowstride); texture = glitz_surface_get_texture (surface); glitz_texture_bind (surface->gl, texture); @@ -649,7 +707,7 @@ glitz_surface_draw_pixels (glitz_surface_t *surface, surface->gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, 0); surface->gl->pixel_store_i (GLITZ_GL_PACK_SKIP_ROWS, 0); surface->gl->pixel_store_i (GLITZ_GL_PACK_SKIP_PIXELS, 0); - + surface->gl->tex_sub_image_2d (texture->target, 0, x, surface->height - y - height, width, height, @@ -658,11 +716,12 @@ glitz_surface_draw_pixels (glitz_surface_t *surface, surface->gl->flush (); glitz_texture_unbind (surface->gl, texture); - - free (pixel_buf); } glitz_surface_pop_current (surface); + + if (pixel_buf) + free (pixel_buf); } slim_hidden_def(glitz_surface_draw_pixels); @@ -708,8 +767,7 @@ slim_hidden_def(glitz_surface_get_gl_texture); void glitz_surface_gl_begin (glitz_surface_t *surface) { - if (!glitz_surface_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) - glitz_surface_status_add (surface, GLITZ_STATUS_NOT_SUPPORTED_MASK); + glitz_surface_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT); } slim_hidden_def(glitz_surface_gl_begin); diff --git a/src/glitz_texture.c b/src/glitz_texture.c index caa24ca..813a862 100644 --- a/src/glitz_texture.c +++ b/src/glitz_texture.c @@ -66,6 +66,15 @@ glitz_texture_generate (glitz_gl_proc_address_list_t *gl, texture->format = texture_format; texture->allocated = 0; + switch (texture->format) { + case GLITZ_GL_LUMINANCE_ALPHA: + texture->internal_format = GLITZ_GL_LUMINANCE_ALPHA; + break; + default: + texture->internal_format = GLITZ_GL_RGBA; + break; + } + if (!(target_mask & GLITZ_TEXTURE_TARGET_NPOT_MASK)) { _glitz_texture_find_best_target (width, height, target_mask, &texture->target); @@ -106,7 +115,8 @@ glitz_texture_allocate (glitz_gl_proc_address_list_t *gl, glitz_texture_bind (gl, texture); - gl->tex_image_2d (texture->target, 0, GLITZ_GL_RGBA, + gl->tex_image_2d (texture->target, 0, + texture->internal_format, texture->width, texture->height, 0, texture->format, GLITZ_GL_UNSIGNED_BYTE, NULL); diff --git a/src/glitz_util.c b/src/glitz_util.c index 2e661ed..73d584e 100644 --- a/src/glitz_util.c +++ b/src/glitz_util.c @@ -108,7 +108,7 @@ glitz_get_gl_format_from_bpp (unsigned short bpp) { switch (bpp) { case 8: - return GLITZ_GL_ALPHA; + return GLITZ_GL_LUMINANCE_ALPHA; break; case 24: if (big_endian ()) diff --git a/src/glitzint.h b/src/glitzint.h index 2be809c..835593f 100644 --- a/src/glitzint.h +++ b/src/glitzint.h @@ -222,8 +222,9 @@ typedef struct _glitz_matrix_t { typedef struct _glitz_texture { glitz_gl_uint_t name; - unsigned int target; - unsigned int format; + glitz_gl_enum_t target; + glitz_gl_enum_t format; + glitz_gl_enum_t internal_format; glitz_bool_t allocated; glitz_filter_t filter; @@ -274,6 +275,11 @@ typedef struct glitz_surface_backend { #define SURFACE_PROGRAMMATIC(surface) \ (surface->hint_mask & GLITZ_HINT_PROGRAMMATIC_MASK) +#define SURFACE_SOLID(surface) \ + ((surface->hint_mask & GLITZ_HINT_PROGRAMMATIC_MASK) && \ + ((glitz_programmatic_surface_t *) surface)->type == \ + GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE) + #define SURFACE_REPEAT(surface) \ (surface->hint_mask & GLITZ_INT_HINT_REPEAT_MASK) @@ -567,12 +573,6 @@ glitz_format_find_standard (glitz_format_t *formats, unsigned long options, glitz_format_name_t format_name); -glitz_format_t * -glitz_format_find_sufficient_standard (glitz_format_t *formats, - int n_formats, - unsigned long options, - glitz_format_name_t format_name); - void glitz_format_calculate_pixel_transfer_info (glitz_format_t *format); |