Modilfy the composite logic to two phases

We seperate the composite to two phases, firstly to
 select the shader according to source type and logic
 op, setting the right parameters. Then we emit the
 vertex array to generate the dest result.
 The reason why we do this is that the shader may be
 used to composite no only rect, trapezoid and triangle
 render function can also use it to render triangles and
 polygens. The old function glamor_composite_with_shader
 do the whole two phases work and can not match the
 new request.

Signed-off-by: Junyan He <junyan.he@linux.intel.com>
This commit is contained in:
Junyan He 2012-06-04 07:22:27 +08:00 committed by Eric Anholt
parent 0b0391765f
commit 5f1560c84a
4 changed files with 134 additions and 81 deletions

View File

@ -788,7 +788,6 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
PixmapPtr pixmap = NULL; PixmapPtr pixmap = NULL;
glamor_gl_dispatch *dispatch = NULL; glamor_gl_dispatch *dispatch = NULL;
float tmp;
pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable); pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv = glamor_get_pixmap_private(pixmap);

View File

@ -127,6 +127,12 @@ enum shader_in {
SHADER_IN_COUNT, SHADER_IN_COUNT,
}; };
struct shader_key {
enum shader_source source;
enum shader_mask mask;
enum shader_in in;
};
enum gradient_shader { enum gradient_shader {
SHADER_GRADIENT_LINEAR, SHADER_GRADIENT_LINEAR,
SHADER_GRADIENT_RADIAL, SHADER_GRADIENT_RADIAL,
@ -158,6 +164,8 @@ enum glamor_gl_flavor {
#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2 #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
typedef struct { typedef struct {
PicturePtr picture; /* Where the glyphs of the cache are stored */ PicturePtr picture; /* Where the glyphs of the cache are stored */
GlyphPtr *glyphs; GlyphPtr *glyphs;
@ -704,6 +712,15 @@ void glamor_composite_rects (CARD8 op,
xRectangle *rects); xRectangle *rects);
void glamor_init_trapezoid_shader(ScreenPtr screen); void glamor_init_trapezoid_shader(ScreenPtr screen);
void glamor_fini_trapezoid_shader(ScreenPtr screen); void glamor_fini_trapezoid_shader(ScreenPtr screen);
PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
PicturePtr source,
int x_source,
int y_source, int width, int height);
void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
void glamor_emit_composite_vert(ScreenPtr screen,
const float *src_coords,
const float *mask_coords,
const float *dst_coords, int i);
/* glamor_trapezoid.c */ /* glamor_trapezoid.c */
void glamor_trapezoids(CARD8 op, void glamor_trapezoids(CARD8 op,
@ -939,10 +956,10 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
#define GLAMOR_GRADIENT_SHADER #define GLAMOR_GRADIENT_SHADER
//#define GLAMOR_TRAPEZOID_SHADER #define GLAMOR_TRAPEZOID_SHADER
#endif #endif
#define GLAMOR_TEXTURED_LARGE_PIXMAP 1 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
#if 1 #if 0
#define MAX_FBO_SIZE 32 /* For test purpose only. */ #define MAX_FBO_SIZE 32 /* For test purpose only. */
#endif #endif

View File

@ -43,11 +43,6 @@
//#define DEBUGRegionPrint(x) do {} while (0) //#define DEBUGRegionPrint(x) do {} while (0)
#define DEBUGRegionPrint RegionPrint #define DEBUGRegionPrint RegionPrint
#endif #endif
struct shader_key {
enum shader_source source;
enum shader_mask mask;
enum shader_in in;
};
struct blendinfo { struct blendinfo {
Bool dest_alpha; Bool dest_alpha;
@ -385,8 +380,6 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
return shader; return shader;
} }
#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
static void static void
glamor_init_eb(unsigned short *eb, int vert_cnt) glamor_init_eb(unsigned short *eb, int vert_cnt)
{ {
@ -735,7 +728,7 @@ cleanup_region:
return ret; return ret;
} }
static void void
glamor_setup_composite_vbo(ScreenPtr screen, int n_verts) glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
{ {
glamor_screen_private *glamor_priv = glamor_screen_private *glamor_priv =
@ -795,7 +788,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
glamor_put_dispatch(glamor_priv); glamor_put_dispatch(glamor_priv);
} }
static void void
glamor_emit_composite_vert(ScreenPtr screen, glamor_emit_composite_vert(ScreenPtr screen,
const float *src_coords, const float *src_coords,
const float *mask_coords, const float *mask_coords,
@ -963,44 +956,36 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
texcoords); texcoords);
} }
static Bool Bool glamor_composite_choose_shader(CARD8 op,
glamor_composite_with_shader(CARD8 op,
PicturePtr source, PicturePtr source,
PicturePtr mask, PicturePtr mask,
PicturePtr dest, PicturePtr dest,
glamor_pixmap_private *source_pixmap_priv, glamor_pixmap_private *source_pixmap_priv,
glamor_pixmap_private *mask_pixmap_priv, glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv, glamor_pixmap_private *dest_pixmap_priv,
int nrect, struct shader_key *s_key,
glamor_composite_rect_t * rects) PictFormatShort *psaved_source_format)
{ {
ScreenPtr screen = dest->pDrawable->pScreen; ScreenPtr screen = dest->pDrawable->pScreen;
glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv; glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
glamor_gl_dispatch *dispatch;
PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap; PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; PixmapPtr source_pixmap = NULL;
GLfloat dst_xscale, dst_yscale; PixmapPtr mask_pixmap = NULL;
GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
struct shader_key key;
glamor_composite_shader *shader;
float vertices[8], source_texcoords[8], mask_texcoords[8];
int dest_x_off, dest_y_off;
int source_x_off, source_y_off;
int mask_x_off, mask_y_off;
enum glamor_pixmap_status source_status = GLAMOR_NONE; enum glamor_pixmap_status source_status = GLAMOR_NONE;
enum glamor_pixmap_status mask_status = GLAMOR_NONE; enum glamor_pixmap_status mask_status = GLAMOR_NONE;
PictFormatShort saved_source_format = 0; PictFormatShort saved_source_format = 0;
float src_matrix[9], mask_matrix[9]; struct shader_key key;
float *psrc_matrix = NULL, *pmask_matrix = NULL; GLfloat source_solid_color[4];
GLfloat source_solid_color[4], mask_solid_color[4]; GLfloat mask_solid_color[4];
int vert_stride = 4; glamor_composite_shader *shader = NULL;
int nrect_max; glamor_gl_dispatch *dispatch = NULL;
Bool ret = FALSE; Bool ret = FALSE;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
glamor_fallback("dest has no fbo.\n"); glamor_fallback("dest has no fbo.\n");
goto fail; goto fail;
} }
memset(&key, 0, sizeof(key)); memset(&key, 0, sizeof(key));
if (!source) { if (!source) {
key.source = SHADER_SOURCE_SOLID; key.source = SHADER_SOURCE_SOLID;
@ -1023,6 +1008,7 @@ glamor_composite_with_shader(CARD8 op,
} else { } else {
key.source = SHADER_SOURCE_TEXTURE_ALPHA; key.source = SHADER_SOURCE_TEXTURE_ALPHA;
} }
if (mask) { if (mask) {
if (!mask->pDrawable) { if (!mask->pDrawable) {
if (mask->pSourcePict->type == if (mask->pSourcePict->type ==
@ -1051,8 +1037,7 @@ glamor_composite_with_shader(CARD8 op,
else if (op == PictOpOutReverse || op == PictOpInReverse) { else if (op == PictOpOutReverse || op == PictOpInReverse) {
key.in = SHADER_IN_CA_ALPHA; key.in = SHADER_IN_CA_ALPHA;
} else { } else {
glamor_fallback glamor_fallback("Unsupported component alpha op: %d\n", op);
("Unsupported component alpha op: %d\n", op);
goto fail; goto fail;
} }
} }
@ -1069,6 +1054,7 @@ glamor_composite_with_shader(CARD8 op,
glamor_fallback("mask alphaMap\n"); glamor_fallback("mask alphaMap\n");
goto fail; goto fail;
} }
if (key.source == SHADER_SOURCE_TEXTURE || if (key.source == SHADER_SOURCE_TEXTURE ||
key.source == SHADER_SOURCE_TEXTURE_ALPHA) { key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
source_pixmap = source_pixmap_priv->base.pixmap; source_pixmap = source_pixmap_priv->base.pixmap;
@ -1090,6 +1076,7 @@ glamor_composite_with_shader(CARD8 op,
#endif #endif
} }
} }
if (key.mask == SHADER_MASK_TEXTURE || if (key.mask == SHADER_MASK_TEXTURE ||
key.mask == SHADER_MASK_TEXTURE_ALPHA) { key.mask == SHADER_MASK_TEXTURE_ALPHA) {
mask_pixmap = mask_pixmap_priv->base.pixmap; mask_pixmap = mask_pixmap_priv->base.pixmap;
@ -1106,6 +1093,7 @@ glamor_composite_with_shader(CARD8 op,
#endif #endif
} }
} }
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
if (source_status == GLAMOR_UPLOAD_PENDING if (source_status == GLAMOR_UPLOAD_PENDING
&& mask_status == GLAMOR_UPLOAD_PENDING && mask_status == GLAMOR_UPLOAD_PENDING
@ -1114,18 +1102,16 @@ glamor_composite_with_shader(CARD8 op,
if (source->format != mask->format) { if (source->format != mask->format) {
saved_source_format = source->format; saved_source_format = source->format;
if (!combine_pict_format if (!combine_pict_format(&source->format, source->format,
(&source->format, source->format,
mask->format, key.in)) { mask->format, key.in)) {
glamor_fallback glamor_fallback("combine source %x mask %x failed.\n",
("combine source %x mask %x failed.\n",
source->format, mask->format); source->format, mask->format);
goto fail; goto fail;
} }
if (source->format != saved_source_format) { if (source->format != saved_source_format) {
//glamor_picture_format_fixup(source, glamor_picture_format_fixup(source,
// source_pixmap_priv); source_pixmap_priv);
} }
/* XXX /* XXX
* By default, glamor_upload_picture_to_texture will wire alpha to 1 * By default, glamor_upload_picture_to_texture will wire alpha to 1
@ -1156,16 +1142,14 @@ glamor_composite_with_shader(CARD8 op,
source_status = glamor_upload_picture_to_texture(source); source_status = glamor_upload_picture_to_texture(source);
if (source_status != GLAMOR_UPLOAD_DONE) { if (source_status != GLAMOR_UPLOAD_DONE) {
glamor_fallback glamor_fallback("Failed to upload source texture.\n");
("Failed to upload source texture.\n");
goto fail; goto fail;
} }
} else { } else {
if (source_status == GLAMOR_UPLOAD_PENDING) { if (source_status == GLAMOR_UPLOAD_PENDING) {
source_status = glamor_upload_picture_to_texture(source); source_status = glamor_upload_picture_to_texture(source);
if (source_status != GLAMOR_UPLOAD_DONE) { if (source_status != GLAMOR_UPLOAD_DONE) {
glamor_fallback glamor_fallback("Failed to upload source texture.\n");
("Failed to upload source texture.\n");
goto fail; goto fail;
} }
} }
@ -1173,8 +1157,7 @@ glamor_composite_with_shader(CARD8 op,
if (mask_status == GLAMOR_UPLOAD_PENDING) { if (mask_status == GLAMOR_UPLOAD_PENDING) {
mask_status = glamor_upload_picture_to_texture(mask); mask_status = glamor_upload_picture_to_texture(mask);
if (mask_status != GLAMOR_UPLOAD_DONE) { if (mask_status != GLAMOR_UPLOAD_DONE) {
glamor_fallback glamor_fallback("Failed to upload mask texture.\n");
("Failed to upload mask texture.\n");
goto fail; goto fail;
} }
} }
@ -1206,8 +1189,8 @@ glamor_composite_with_shader(CARD8 op,
shader = glamor_lookup_composite_shader(screen, &key); shader = glamor_lookup_composite_shader(screen, &key);
if (shader->prog == 0) { if (shader->prog == 0) {
glamor_fallback glamor_fallback("no shader program for this"
("no shader program for this render acccel mode\n"); "render acccel mode\n");
goto fail; goto fail;
} }
@ -1222,6 +1205,7 @@ glamor_composite_with_shader(CARD8 op,
source_pixmap_priv, shader->source_wh, source_pixmap_priv, shader->source_wh,
shader->source_repeat_mode); shader->source_repeat_mode);
} }
if (key.mask != SHADER_MASK_NONE) { if (key.mask != SHADER_MASK_NONE) {
if (key.mask == SHADER_MASK_SOLID) { if (key.mask == SHADER_MASK_SOLID) {
glamor_set_composite_solid(dispatch, glamor_set_composite_solid(dispatch,
@ -1234,15 +1218,73 @@ glamor_composite_with_shader(CARD8 op,
} }
} }
glamor_put_dispatch(glamor_priv);
ret = TRUE;
memcpy(s_key, &key, sizeof(key));
*psaved_source_format = saved_source_format;
goto done;
fail:
if (saved_source_format)
source->format = saved_source_format;
done:
return ret;
}
static Bool
glamor_composite_with_shader(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
glamor_pixmap_private *source_pixmap_priv,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
int nrect, glamor_composite_rect_t * rects)
{
ScreenPtr screen = dest->pDrawable->pScreen;
glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
PixmapPtr source_pixmap = NULL;
PixmapPtr mask_pixmap = NULL;
glamor_gl_dispatch *dispatch = NULL;
GLfloat dst_xscale, dst_yscale;
GLfloat mask_xscale = 1, mask_yscale = 1,
src_xscale = 1, src_yscale = 1;
struct shader_key key;
float vertices[8], source_texcoords[8], mask_texcoords[8];
int dest_x_off, dest_y_off;
int source_x_off, source_y_off;
int mask_x_off, mask_y_off;
PictFormatShort saved_source_format = 0;
float src_matrix[9], mask_matrix[9];
float *psrc_matrix = NULL, *pmask_matrix = NULL;
int vert_stride = 4;
int nrect_max;
Bool ret = FALSE;
if(!glamor_composite_choose_shader(op, source, mask, dest,
source_pixmap_priv, mask_pixmap_priv,
dest_pixmap_priv,
&key, &saved_source_format)) {
glamor_fallback("glamor_composite_choose_shader failed\n");
return ret;
}
dispatch = glamor_get_dispatch(glamor_priv);
glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
key.mask != SHADER_MASK_SOLID); key.mask != SHADER_MASK_SOLID);
dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
&dest_x_off, &dest_y_off); &dest_x_off, &dest_y_off);
pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale); pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
if (glamor_priv->has_source_coords) { if (glamor_priv->has_source_coords) {
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
glamor_get_drawable_deltas(source->pDrawable, glamor_get_drawable_deltas(source->pDrawable,
source_pixmap, &source_x_off, source_pixmap, &source_x_off,
&source_y_off); &source_y_off);
@ -1256,6 +1298,8 @@ glamor_composite_with_shader(CARD8 op,
} }
if (glamor_priv->has_mask_coords) { if (glamor_priv->has_mask_coords) {
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
&mask_x_off, &mask_y_off); &mask_x_off, &mask_y_off);
pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
@ -1350,16 +1394,10 @@ glamor_composite_with_shader(CARD8 op,
glamor_put_dispatch(glamor_priv); glamor_put_dispatch(glamor_priv);
ret = TRUE; ret = TRUE;
goto done;
fail:
if (saved_source_format)
source->format = saved_source_format;
done:
return ret; return ret;
} }
static PicturePtr PicturePtr
glamor_convert_gradient_picture(ScreenPtr screen, glamor_convert_gradient_picture(ScreenPtr screen,
PicturePtr source, PicturePtr source,
int x_source, int x_source,

View File

@ -395,7 +395,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
BoxRec one_trap_bound; BoxRec one_trap_bound;
float vertices[8]; float vertices[8];
float tex_vertices[8]; float tex_vertices[8];
float tmp;
int i; int i;
glamor_priv = glamor_get_screen_private(screen); glamor_priv = glamor_get_screen_private(screen);
@ -410,8 +409,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
} }
/* First, clear all to zero */ /* First, clear all to zero */
if (!glamor_solid(pixmap, 0, 0, pixmap_priv->container->drawable.width, if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
pixmap_priv->container->drawable.height, pixmap_priv->base.pixmap->drawable.height,
GXclear, 0xFFFFFFFF, 0)) { GXclear, 0xFFFFFFFF, 0)) {
DEBUGF("glamor_solid failed, fallback\n"); DEBUGF("glamor_solid failed, fallback\n");
return FALSE; return FALSE;
@ -490,8 +489,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y); xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y);
miTrapezoidBounds(1, ptrap, &one_trap_bound); miTrapezoidBounds(1, ptrap, &one_trap_bound);
glamor_set_tcoords_tri_strip((pixmap_priv->container->drawable.width), glamor_set_tcoords_tri_strip((pixmap_priv->base.pixmap->drawable.width),
(pixmap_priv->container->drawable.height), (pixmap_priv->base.pixmap->drawable.height),
(one_trap_bound.x1), (one_trap_bound.x1),
(one_trap_bound.y1), (one_trap_bound.y1),
(one_trap_bound.x2), (one_trap_bound.x2),