summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-02-09 22:35:04 -0800
committerEric Anholt <eric@anholt.net>2010-02-11 09:12:59 -0800
commitcc9c14c70873c126ed5346533842401a4a82d9cb (patch)
treeb391b3f2d66961d8f809dce7e8efce4a2eb0101f
parent3b1dbb68a8c1313ebbae547cd1215160de148700 (diff)
glamor: Rework the Render shader setup to be easily modified, like cairo-gl.
-rw-r--r--glamor/glamor_priv.h16
-rw-r--r--glamor/glamor_render.c183
2 files changed, 109 insertions, 90 deletions
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index dc1a5ca87..95aad7da1 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -98,6 +98,19 @@ typedef struct {
#define GLAMOR_NUM_GLYPH_CACHES 4
+enum shader_source {
+ SHADER_SOURCE_SOLID,
+ SHADER_SOURCE_TEXTURE_ALPHA,
+ SHADER_SOURCE_COUNT,
+};
+
+enum shader_mask {
+ SHADER_MASK_NONE,
+ SHADER_MASK_SOLID,
+ SHADER_MASK_TEXTURE_ALPHA,
+ SHADER_MASK_COUNT,
+};
+
typedef struct glamor_screen_private {
CreateGCProcPtr saved_create_gc;
CreatePixmapProcPtr saved_create_pixmap;
@@ -130,7 +143,8 @@ typedef struct glamor_screen_private {
GLint put_image_xybitmap_bg_uniform_location;
/* glamor_composite */
- glamor_composite_shader composite_shader[8];
+ glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
+ [SHADER_MASK_COUNT];
glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
} glamor_screen_private;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e4a9441a4..f432b5f29 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -39,9 +39,8 @@
#include "glu3/glu3.h"
struct shader_key {
- Bool solid_source;
- Bool has_mask;
- Bool solid_mask;
+ enum shader_source source;
+ enum shader_mask mask;
};
struct blendinfo {
@@ -67,29 +66,6 @@ static struct blendinfo composite_op_info[] = {
[PictOpAdd] = {0, 0, GL_ONE, GL_ONE},
};
-#define SOLID_SOURCE_INDEX 1
-#define HAS_MASK_INDEX 2
-#define SOLID_MASK_INDEX 3
-
-static glamor_composite_shader *
-glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
-{
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- int index = 0;
-
- if (key->solid_source)
- index += SOLID_SOURCE_INDEX;
- if (key->has_mask) {
- index += HAS_MASK_INDEX;
- if (key->solid_mask)
- index += SOLID_MASK_INDEX;
- }
-
- assert(index < ARRAY_SIZE(glamor_priv->composite_shader));
-
- return &glamor_priv->composite_shader[index];
-}
-
static GLuint
glamor_create_composite_fs(struct shader_key *key)
{
@@ -104,12 +80,12 @@ glamor_create_composite_fs(struct shader_key *key)
const char *main_opening =
"void main()\n"
"{\n";
- const char *source_pixmap_fetch =
+ const char *source_alpha_pixmap_fetch =
" vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n";
- const char *mask_pixmap_fetch =
+ const char *mask_alpha_pixmap_fetch =
" vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n";
const char *source_in_mask =
- " gl_FragColor = source * mask.w;\n";
+ " gl_FragColor = source * mask.a;\n";
const char *source_only =
" gl_FragColor = source;\n";
const char *main_closing =
@@ -119,29 +95,49 @@ glamor_create_composite_fs(struct shader_key *key)
const char *source_fetch = "";
const char *mask_setup = "";
const char *mask_fetch = "";
+ const char *in;
GLuint prog;
- if (key->solid_source) {
+ switch (key->source) {
+ case SHADER_SOURCE_SOLID:
source_setup = source_solid_header;
- } else {
+ break;
+ case SHADER_SOURCE_TEXTURE_ALPHA:
source_setup = source_pixmap_header;
- source_fetch = source_pixmap_fetch;
+ source_fetch = source_alpha_pixmap_fetch;
+ break;
+ FatalError("Bad composite shader source");
+ default:
+ FatalError("Bad composite source mask");
}
- if (key->has_mask) {
- if (key->solid_mask) {
- mask_setup = mask_solid_header;
- } else {
- mask_setup = mask_pixmap_header;
- mask_fetch = mask_pixmap_fetch;
- }
+
+ switch (key->mask) {
+ case SHADER_MASK_NONE:
+ break;
+ case SHADER_MASK_SOLID:
+ mask_setup = mask_solid_header;
+ break;
+ case SHADER_MASK_TEXTURE_ALPHA:
+ mask_setup = mask_pixmap_header;
+ mask_fetch = mask_alpha_pixmap_fetch;
+ break;
+ default:
+ FatalError("Bad composite shader mask");
+ }
+
+ if (key->mask == SHADER_MASK_NONE) {
+ in = source_only;
+ } else {
+ in = source_in_mask;
}
+
source = XNFprintf("%s%s%s%s%s%s%s",
source_setup,
mask_setup,
main_opening,
source_fetch,
mask_fetch,
- key->has_mask ? source_in_mask : source_only,
+ in,
main_closing);
prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
@@ -156,19 +152,28 @@ glamor_create_composite_vs(struct shader_key *key)
const char *main_opening =
"void main()\n"
"{\n"
- " gl_Position = gl_Vertex;\n"
+ " gl_Position = gl_Vertex;\n";
+ const char *source_coords =
" gl_TexCoord[0] = gl_MultiTexCoord0;\n";
const char *mask_coords =
" gl_TexCoord[1] = gl_MultiTexCoord1;\n";
const char *main_closing =
"}\n";
+ const char *source_coords_setup = "";
+ const char *mask_coords_setup = "";
char *source;
GLuint prog;
- Bool compute_mask_coords = key->has_mask && !key->solid_mask;
- source = XNFprintf("%s%s%s",
+ if (key->source != SHADER_SOURCE_SOLID)
+ source_coords_setup = source_coords;
+
+ if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID)
+ mask_coords_setup = mask_coords;
+
+ source = XNFprintf("%s%s%s%s",
main_opening,
- compute_mask_coords ? mask_coords : "",
+ source_coords_setup,
+ mask_coords_setup,
main_closing);
prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
@@ -178,13 +183,11 @@ glamor_create_composite_vs(struct shader_key *key)
}
static void
-glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
+glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
+ glamor_composite_shader *shader)
{
GLuint vs, fs, prog;
GLint source_sampler_uniform_location, mask_sampler_uniform_location;
- glamor_composite_shader *shader;
-
- shader = glamor_lookup_composite_shader(screen, key);
vs = glamor_create_composite_vs(key);
if (vs == 0)
@@ -202,7 +205,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
glUseProgramObjectARB(prog);
- if (key->solid_source) {
+ if (key->source == SHADER_SOURCE_SOLID) {
shader->source_uniform_location = glGetUniformLocationARB(prog,
"source");
} else {
@@ -211,8 +214,8 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
glUniform1i(source_sampler_uniform_location, 0);
}
- if (key->has_mask) {
- if (key->solid_mask) {
+ if (key->mask != SHADER_MASK_NONE) {
+ if (key->mask == SHADER_MASK_SOLID) {
shader->mask_uniform_location = glGetUniformLocationARB(prog,
"mask");
} else {
@@ -223,27 +226,22 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
}
}
-void
-glamor_init_composite_shaders(ScreenPtr screen)
+static glamor_composite_shader *
+glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
{
- struct shader_key key;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ glamor_composite_shader *shader;
- memset(&key, 0, sizeof(key));
- key.has_mask = FALSE;
- glamor_create_composite_shader(screen, &key);
- key.has_mask = TRUE;
- glamor_create_composite_shader(screen, &key);
- key.solid_mask = TRUE;
- glamor_create_composite_shader(screen, &key);
+ shader = &glamor_priv->composite_shader[key->source][key->mask];
+ if (shader->prog == 0)
+ glamor_create_composite_shader(screen, key, shader);
- memset(&key, 0, sizeof(key));
- key.solid_source = TRUE;
- key.has_mask = FALSE;
- glamor_create_composite_shader(screen, &key);
- key.has_mask = TRUE;
- glamor_create_composite_shader(screen, &key);
- key.solid_mask = TRUE;
- glamor_create_composite_shader(screen, &key);
+ return shader;
+}
+
+void
+glamor_init_composite_shaders(ScreenPtr screen)
+{
}
static Bool
@@ -505,33 +503,40 @@ glamor_composite_with_shader(CARD8 op,
BoxPtr box;
memset(&key, 0, sizeof(key));
- key.has_mask = (mask != NULL);
if (!source->pDrawable) {
if (source->pSourcePict->type == SourcePictTypeSolidFill) {
- key.solid_source = TRUE;
+ key.source = SHADER_SOURCE_SOLID;
} else {
- ErrorF("gradient source\n");
+ glamor_fallback("gradient source\n");
goto fail;
}
- }
- if (mask && !mask->pDrawable) {
- if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
- key.solid_mask = TRUE;
+ } else {
+ key.source = SHADER_SOURCE_TEXTURE_ALPHA;
+ }
+ if (mask) {
+ if (!mask->pDrawable) {
+ if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
+ key.mask = SHADER_MASK_SOLID;
+ } else {
+ glamor_fallback("gradient mask\n");
+ goto fail;
+ }
} else {
- ErrorF("gradient mask\n");
- goto fail;
+ key.mask = SHADER_MASK_TEXTURE_ALPHA;
}
+ } else {
+ key.mask = SHADER_MASK_NONE;
}
if (source->alphaMap) {
- ErrorF("source alphaMap\n");
+ glamor_fallback("source alphaMap\n");
goto fail;
}
if (mask && mask->alphaMap) {
- ErrorF("mask alphaMap\n");
+ glamor_fallback("mask alphaMap\n");
goto fail;
}
- if (!key.solid_source) {
+ if (key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
if (source_pixmap == dest_pixmap) {
@@ -545,7 +550,7 @@ glamor_composite_with_shader(CARD8 op,
if (!good_source_format(source))
goto fail;
}
- if (mask && !key.solid_mask) {
+ if (key.mask == SHADER_MASK_TEXTURE_ALPHA) {
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
if (mask_pixmap == dest_pixmap) {
@@ -589,13 +594,13 @@ glamor_composite_with_shader(CARD8 op,
y_mask += mask->pDrawable->y;
}
- if (key.solid_source) {
+ if (key.source == SHADER_SOURCE_SOLID) {
glamor_set_composite_solid(source, shader->source_uniform_location);
} else {
glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
}
- if (key.has_mask) {
- if (key.solid_mask) {
+ if (key.mask != SHADER_MASK_NONE) {
+ if (key.mask == SHADER_MASK_SOLID) {
glamor_set_composite_solid(mask, shader->mask_uniform_location);
} else {
glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
@@ -614,13 +619,13 @@ glamor_composite_with_shader(CARD8 op,
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
- if (!key.solid_source) {
+ if (key.source != SHADER_SOURCE_SOLID) {
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
- if (key.has_mask && !key.solid_mask) {
+ if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -637,7 +642,7 @@ glamor_composite_with_shader(CARD8 op,
vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1);
vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2);
- if (!key.solid_source) {
+ if (key.source != SHADER_SOURCE_SOLID) {
int tx1 = box[i].x1 + x_source - x_dest;
int ty1 = box[i].y1 + y_source - y_dest;
int tx2 = box[i].x2 + x_source - x_dest;
@@ -652,7 +657,7 @@ glamor_composite_with_shader(CARD8 op,
source_texcoords[3][1] = t_from_x_coord_y(source_pixmap, ty2);
}
- if (key.has_mask && !key.solid_mask) {
+ if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
int tx1 = box[i].x1 + x_mask - x_dest;
int ty1 = box[i].y1 + y_mask - y_dest;
int tx2 = box[i].x2 + x_mask - x_dest;