glamor: Rework the Render shader setup to be easily modified, like cairo-gl.
This commit is contained in:
parent
f4a3194837
commit
126fc09cb5
|
@ -98,6 +98,19 @@ typedef struct {
|
||||||
|
|
||||||
#define GLAMOR_NUM_GLYPH_CACHES 4
|
#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 {
|
typedef struct glamor_screen_private {
|
||||||
CreateGCProcPtr saved_create_gc;
|
CreateGCProcPtr saved_create_gc;
|
||||||
CreatePixmapProcPtr saved_create_pixmap;
|
CreatePixmapProcPtr saved_create_pixmap;
|
||||||
|
@ -130,7 +143,8 @@ typedef struct glamor_screen_private {
|
||||||
GLint put_image_xybitmap_bg_uniform_location;
|
GLint put_image_xybitmap_bg_uniform_location;
|
||||||
|
|
||||||
/* glamor_composite */
|
/* 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_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
|
||||||
} glamor_screen_private;
|
} glamor_screen_private;
|
||||||
|
|
|
@ -39,9 +39,8 @@
|
||||||
#include "glu3/glu3.h"
|
#include "glu3/glu3.h"
|
||||||
|
|
||||||
struct shader_key {
|
struct shader_key {
|
||||||
Bool solid_source;
|
enum shader_source source;
|
||||||
Bool has_mask;
|
enum shader_mask mask;
|
||||||
Bool solid_mask;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct blendinfo {
|
struct blendinfo {
|
||||||
|
@ -67,29 +66,6 @@ static struct blendinfo composite_op_info[] = {
|
||||||
[PictOpAdd] = {0, 0, GL_ONE, GL_ONE},
|
[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
|
static GLuint
|
||||||
glamor_create_composite_fs(struct shader_key *key)
|
glamor_create_composite_fs(struct shader_key *key)
|
||||||
{
|
{
|
||||||
|
@ -104,12 +80,12 @@ glamor_create_composite_fs(struct shader_key *key)
|
||||||
const char *main_opening =
|
const char *main_opening =
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n";
|
"{\n";
|
||||||
const char *source_pixmap_fetch =
|
const char *source_alpha_pixmap_fetch =
|
||||||
" vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n";
|
" 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";
|
" vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n";
|
||||||
const char *source_in_mask =
|
const char *source_in_mask =
|
||||||
" gl_FragColor = source * mask.w;\n";
|
" gl_FragColor = source * mask.a;\n";
|
||||||
const char *source_only =
|
const char *source_only =
|
||||||
" gl_FragColor = source;\n";
|
" gl_FragColor = source;\n";
|
||||||
const char *main_closing =
|
const char *main_closing =
|
||||||
|
@ -119,29 +95,49 @@ glamor_create_composite_fs(struct shader_key *key)
|
||||||
const char *source_fetch = "";
|
const char *source_fetch = "";
|
||||||
const char *mask_setup = "";
|
const char *mask_setup = "";
|
||||||
const char *mask_fetch = "";
|
const char *mask_fetch = "";
|
||||||
|
const char *in;
|
||||||
GLuint prog;
|
GLuint prog;
|
||||||
|
|
||||||
if (key->solid_source) {
|
switch (key->source) {
|
||||||
|
case SHADER_SOURCE_SOLID:
|
||||||
source_setup = source_solid_header;
|
source_setup = source_solid_header;
|
||||||
} else {
|
break;
|
||||||
|
case SHADER_SOURCE_TEXTURE_ALPHA:
|
||||||
source_setup = source_pixmap_header;
|
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) {
|
switch (key->mask) {
|
||||||
|
case SHADER_MASK_NONE:
|
||||||
|
break;
|
||||||
|
case SHADER_MASK_SOLID:
|
||||||
mask_setup = mask_solid_header;
|
mask_setup = mask_solid_header;
|
||||||
} else {
|
break;
|
||||||
|
case SHADER_MASK_TEXTURE_ALPHA:
|
||||||
mask_setup = mask_pixmap_header;
|
mask_setup = mask_pixmap_header;
|
||||||
mask_fetch = mask_pixmap_fetch;
|
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 = XNFprintf("%s%s%s%s%s%s%s",
|
||||||
source_setup,
|
source_setup,
|
||||||
mask_setup,
|
mask_setup,
|
||||||
main_opening,
|
main_opening,
|
||||||
source_fetch,
|
source_fetch,
|
||||||
mask_fetch,
|
mask_fetch,
|
||||||
key->has_mask ? source_in_mask : source_only,
|
in,
|
||||||
main_closing);
|
main_closing);
|
||||||
|
|
||||||
prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
|
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 =
|
const char *main_opening =
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_Position = gl_Vertex;\n"
|
" gl_Position = gl_Vertex;\n";
|
||||||
|
const char *source_coords =
|
||||||
" gl_TexCoord[0] = gl_MultiTexCoord0;\n";
|
" gl_TexCoord[0] = gl_MultiTexCoord0;\n";
|
||||||
const char *mask_coords =
|
const char *mask_coords =
|
||||||
" gl_TexCoord[1] = gl_MultiTexCoord1;\n";
|
" gl_TexCoord[1] = gl_MultiTexCoord1;\n";
|
||||||
const char *main_closing =
|
const char *main_closing =
|
||||||
"}\n";
|
"}\n";
|
||||||
|
const char *source_coords_setup = "";
|
||||||
|
const char *mask_coords_setup = "";
|
||||||
char *source;
|
char *source;
|
||||||
GLuint prog;
|
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,
|
main_opening,
|
||||||
compute_mask_coords ? mask_coords : "",
|
source_coords_setup,
|
||||||
|
mask_coords_setup,
|
||||||
main_closing);
|
main_closing);
|
||||||
|
|
||||||
prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
|
prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
|
||||||
|
@ -178,13 +183,11 @@ glamor_create_composite_vs(struct shader_key *key)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
GLuint vs, fs, prog;
|
||||||
GLint source_sampler_uniform_location, mask_sampler_uniform_location;
|
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);
|
vs = glamor_create_composite_vs(key);
|
||||||
if (vs == 0)
|
if (vs == 0)
|
||||||
|
@ -202,7 +205,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
|
||||||
|
|
||||||
glUseProgramObjectARB(prog);
|
glUseProgramObjectARB(prog);
|
||||||
|
|
||||||
if (key->solid_source) {
|
if (key->source == SHADER_SOURCE_SOLID) {
|
||||||
shader->source_uniform_location = glGetUniformLocationARB(prog,
|
shader->source_uniform_location = glGetUniformLocationARB(prog,
|
||||||
"source");
|
"source");
|
||||||
} else {
|
} else {
|
||||||
|
@ -211,8 +214,8 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
|
||||||
glUniform1i(source_sampler_uniform_location, 0);
|
glUniform1i(source_sampler_uniform_location, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key->has_mask) {
|
if (key->mask != SHADER_MASK_NONE) {
|
||||||
if (key->solid_mask) {
|
if (key->mask == SHADER_MASK_SOLID) {
|
||||||
shader->mask_uniform_location = glGetUniformLocationARB(prog,
|
shader->mask_uniform_location = glGetUniformLocationARB(prog,
|
||||||
"mask");
|
"mask");
|
||||||
} else {
|
} else {
|
||||||
|
@ -223,27 +226,22 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static glamor_composite_shader *
|
||||||
|
glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
|
||||||
|
{
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
glamor_composite_shader *shader;
|
||||||
|
|
||||||
|
shader = &glamor_priv->composite_shader[key->source][key->mask];
|
||||||
|
if (shader->prog == 0)
|
||||||
|
glamor_create_composite_shader(screen, key, shader);
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
glamor_init_composite_shaders(ScreenPtr screen)
|
glamor_init_composite_shaders(ScreenPtr screen)
|
||||||
{
|
{
|
||||||
struct shader_key key;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
|
@ -505,33 +503,40 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
BoxPtr box;
|
BoxPtr box;
|
||||||
|
|
||||||
memset(&key, 0, sizeof(key));
|
memset(&key, 0, sizeof(key));
|
||||||
key.has_mask = (mask != NULL);
|
|
||||||
if (!source->pDrawable) {
|
if (!source->pDrawable) {
|
||||||
if (source->pSourcePict->type == SourcePictTypeSolidFill) {
|
if (source->pSourcePict->type == SourcePictTypeSolidFill) {
|
||||||
key.solid_source = TRUE;
|
key.source = SHADER_SOURCE_SOLID;
|
||||||
} else {
|
} else {
|
||||||
ErrorF("gradient source\n");
|
glamor_fallback("gradient source\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
key.source = SHADER_SOURCE_TEXTURE_ALPHA;
|
||||||
}
|
}
|
||||||
if (mask && !mask->pDrawable) {
|
if (mask) {
|
||||||
|
if (!mask->pDrawable) {
|
||||||
if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
|
if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
|
||||||
key.solid_mask = TRUE;
|
key.mask = SHADER_MASK_SOLID;
|
||||||
} else {
|
} else {
|
||||||
ErrorF("gradient mask\n");
|
glamor_fallback("gradient mask\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
key.mask = SHADER_MASK_TEXTURE_ALPHA;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
key.mask = SHADER_MASK_NONE;
|
||||||
}
|
}
|
||||||
if (source->alphaMap) {
|
if (source->alphaMap) {
|
||||||
ErrorF("source alphaMap\n");
|
glamor_fallback("source alphaMap\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (mask && mask->alphaMap) {
|
if (mask && mask->alphaMap) {
|
||||||
ErrorF("mask alphaMap\n");
|
glamor_fallback("mask alphaMap\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!key.solid_source) {
|
if (key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
|
||||||
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
|
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
|
||||||
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
|
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
|
||||||
if (source_pixmap == dest_pixmap) {
|
if (source_pixmap == dest_pixmap) {
|
||||||
|
@ -545,7 +550,7 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
if (!good_source_format(source))
|
if (!good_source_format(source))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (mask && !key.solid_mask) {
|
if (key.mask == SHADER_MASK_TEXTURE_ALPHA) {
|
||||||
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
|
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
|
||||||
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
|
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
|
||||||
if (mask_pixmap == dest_pixmap) {
|
if (mask_pixmap == dest_pixmap) {
|
||||||
|
@ -589,13 +594,13 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
y_mask += mask->pDrawable->y;
|
y_mask += mask->pDrawable->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.solid_source) {
|
if (key.source == SHADER_SOURCE_SOLID) {
|
||||||
glamor_set_composite_solid(source, shader->source_uniform_location);
|
glamor_set_composite_solid(source, shader->source_uniform_location);
|
||||||
} else {
|
} else {
|
||||||
glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
|
glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
|
||||||
}
|
}
|
||||||
if (key.has_mask) {
|
if (key.mask != SHADER_MASK_NONE) {
|
||||||
if (key.solid_mask) {
|
if (key.mask == SHADER_MASK_SOLID) {
|
||||||
glamor_set_composite_solid(mask, shader->mask_uniform_location);
|
glamor_set_composite_solid(mask, shader->mask_uniform_location);
|
||||||
} else {
|
} else {
|
||||||
glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
|
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);
|
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
if (!key.solid_source) {
|
if (key.source != SHADER_SOURCE_SOLID) {
|
||||||
glClientActiveTexture(GL_TEXTURE0);
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
|
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
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);
|
glClientActiveTexture(GL_TEXTURE1);
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords);
|
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
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][0] = v_from_x_coord_x(dest_pixmap, box[i].x1);
|
||||||
vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2);
|
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 tx1 = box[i].x1 + x_source - x_dest;
|
||||||
int ty1 = box[i].y1 + y_source - y_dest;
|
int ty1 = box[i].y1 + y_source - y_dest;
|
||||||
int tx2 = box[i].x2 + x_source - x_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);
|
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 tx1 = box[i].x1 + x_mask - x_dest;
|
||||||
int ty1 = box[i].y1 + y_mask - y_dest;
|
int ty1 = box[i].y1 + y_mask - y_dest;
|
||||||
int tx2 = box[i].x2 + x_mask - x_dest;
|
int tx2 = box[i].x2 + x_mask - x_dest;
|
||||||
|
|
Loading…
Reference in New Issue