summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog51
-rw-r--r--src/glitz.c44
-rw-r--r--src/glitz.h6
-rw-r--r--src/glitz_agl_extension.c24
-rw-r--r--src/glitz_agl_pbuffer.c2
-rw-r--r--src/glitz_agl_surface.c22
-rw-r--r--src/glitz_aglint.h5
-rw-r--r--src/glitz_format.c45
-rw-r--r--src/glitz_gl.h16
-rw-r--r--src/glitz_glx_extension.c27
-rw-r--r--src/glitz_glx_surface.c23
-rw-r--r--src/glitz_glxint.h21
-rw-r--r--src/glitz_program.c76
-rw-r--r--src/glitz_surface.c142
-rw-r--r--src/glitz_texture.c12
-rw-r--r--src/glitz_util.c2
-rw-r--r--src/glitzint.h16
17 files changed, 333 insertions, 201 deletions
diff --git a/ChangeLog b/ChangeLog
index 930c900..1b4b65a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);