summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@linux.intel.com>2012-06-25 23:24:37 +0800
committerZhigang Gong <zhigang.gong@linux.intel.com>2012-07-03 18:30:15 +0800
commitfc3674fbf40cbe5ddb3e3a29ce86be7db743892b (patch)
tree504c38d8593a842c76bdab2274feae41e6a74905
parent63fb516af37d07f11b4e8d52338354de98885425 (diff)
glamor_render: Optimize the two pass ca rendering.
For the componentAlpha with PictOpOver, we use two pass rendering to implement it. Previous implementation call two times the glamor_composite_... independently which is very inefficient. Now we change the control flow, and do the two pass internally and avoid duplicate works. For the x11perf -rgb10text, this optimization can get about 30% improvement. Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
-rw-r--r--src/glamor_priv.h71
-rw-r--r--src/glamor_render.c204
-rw-r--r--src/glamor_trapezoid.c5
3 files changed, 169 insertions, 111 deletions
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index 989bacc..4fad5cd 100644
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -72,6 +72,7 @@
#define xorg_list_init list_init
#endif
+struct glamor_pixmap_private;
typedef struct glamor_composite_shader {
GLuint prog;
@@ -84,25 +85,22 @@ typedef struct glamor_composite_shader {
GLint mask_wh;
GLint source_repeat_mode;
GLint mask_repeat_mode;
-} glamor_composite_shader;
-
-typedef struct {
- INT16 x_src;
- INT16 y_src;
- INT16 x_mask;
- INT16 y_mask;
- INT16 x_dst;
- INT16 y_dst;
- INT16 width;
- INT16 height;
-} glamor_composite_rect_t;
-
+ union {
+ float source_solid_color[4];
+ struct {
+ struct glamor_pixmap_private *source_priv;
+ PicturePtr source;
+ };
+ };
-enum glamor_vertex_type {
- GLAMOR_VERTEX_POS,
- GLAMOR_VERTEX_SOURCE,
- GLAMOR_VERTEX_MASK
-};
+ union {
+ float mask_solid_color[4];
+ struct {
+ struct glamor_pixmap_private *mask_priv;
+ PicturePtr mask;
+ };
+ };
+} glamor_composite_shader;
enum shader_source {
SHADER_SOURCE_SOLID,
@@ -133,6 +131,32 @@ struct shader_key {
enum shader_in in;
};
+struct blendinfo {
+ Bool dest_alpha;
+ Bool source_alpha;
+ GLenum source_blend;
+ GLenum dest_blend;
+};
+
+typedef struct {
+ INT16 x_src;
+ INT16 y_src;
+ INT16 x_mask;
+ INT16 y_mask;
+ INT16 x_dst;
+ INT16 y_dst;
+ INT16 width;
+ INT16 height;
+} glamor_composite_rect_t;
+
+
+enum glamor_vertex_type {
+ GLAMOR_VERTEX_POS,
+ GLAMOR_VERTEX_SOURCE,
+ GLAMOR_VERTEX_MASK
+};
+
+
enum gradient_shader {
SHADER_GRADIENT_LINEAR,
SHADER_GRADIENT_RADIAL,
@@ -463,7 +487,6 @@ typedef enum glamor_pixmap_status {
GLAMOR_UPLOAD_FAILED
} glamor_pixmap_status_t;
-
extern DevPrivateKey glamor_screen_private_key;
extern DevPrivateKey glamor_pixmap_private_key;
static inline glamor_screen_private *
@@ -716,6 +739,7 @@ PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
PicturePtr source,
int x_source,
int y_source, int width, int height);
+
Bool glamor_composite_choose_shader(CARD8 op,
PicturePtr source,
PicturePtr mask,
@@ -724,7 +748,16 @@ Bool glamor_composite_choose_shader(CARD8 op,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
struct shader_key *s_key,
+ glamor_composite_shader **shader,
+ struct blendinfo *op_info,
PictFormatShort *psaved_source_format);
+
+void
+glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
+ struct shader_key *key,
+ glamor_composite_shader *shader,
+ struct blendinfo *op_info);
+
void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
void glamor_emit_composite_vert(ScreenPtr screen,
const float *src_coords,
diff --git a/src/glamor_render.c b/src/glamor_render.c
index e2be4d7..5e5ae78 100644
--- a/src/glamor_render.c
+++ b/src/glamor_render.c
@@ -43,14 +43,6 @@
//#define DEBUGRegionPrint(x) do {} while (0)
#define DEBUGRegionPrint RegionPrint
#endif
-
-struct blendinfo {
- Bool dest_alpha;
- Bool source_alpha;
- GLenum source_blend;
- GLenum dest_blend;
-};
-
static struct blendinfo composite_op_info[] = {
[PictOpClear] = {0, 0, GL_ZERO, GL_ZERO},
[PictOpSrc] = {0, 0, GL_ONE, GL_ZERO},
@@ -481,13 +473,11 @@ glamor_fini_composite_shaders(ScreenPtr screen)
static Bool
glamor_set_composite_op(ScreenPtr screen,
- CARD8 op, PicturePtr dest, PicturePtr mask)
+ CARD8 op, struct blendinfo *op_info_result,
+ PicturePtr dest, PicturePtr mask)
{
GLenum source_blend, dest_blend;
struct blendinfo *op_info;
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(screen);
- glamor_gl_dispatch *dispatch;
if (op >= ARRAY_SIZE(composite_op_info)) {
glamor_fallback("unsupported render op %d \n", op);
@@ -518,25 +508,20 @@ glamor_set_composite_op(ScreenPtr screen,
dest_blend = GL_ONE_MINUS_SRC_COLOR;
}
- dispatch = glamor_get_dispatch(glamor_priv);
- if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
- dispatch->glDisable(GL_BLEND);
- } else {
- dispatch->glEnable(GL_BLEND);
- dispatch->glBlendFunc(source_blend, dest_blend);
- }
- glamor_put_dispatch(glamor_priv);
+ op_info_result->source_blend = source_blend;
+ op_info_result->dest_blend = dest_blend;
+ op_info_result->source_alpha = op_info->source_alpha;
+ op_info_result->dest_alpha = op_info->dest_alpha;
+
return TRUE;
}
static void
-glamor_set_composite_texture(ScreenPtr screen, int unit,
+glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
PicturePtr picture,
glamor_pixmap_private * pixmap_priv,
GLuint wh_location, GLuint repeat_location)
{
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch;
float wh[4];
int repeat_type;
@@ -956,10 +941,11 @@ Bool glamor_composite_choose_shader(CARD8 op,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
struct shader_key *s_key,
+ glamor_composite_shader **shader,
+ struct blendinfo *op_info,
PictFormatShort *psaved_source_format)
{
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;
@@ -969,8 +955,6 @@ Bool glamor_composite_choose_shader(CARD8 op,
struct shader_key key;
GLfloat source_solid_color[4];
GLfloat mask_solid_color[4];
- glamor_composite_shader *shader = NULL;
- glamor_gl_dispatch *dispatch = NULL;
Bool ret = FALSE;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
@@ -1175,54 +1159,93 @@ Bool glamor_composite_choose_shader(CARD8 op,
goto fail;
}
- glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
- if (!glamor_set_composite_op(screen, op, dest, mask)) {
+ if (!glamor_set_composite_op(screen, op, op_info, dest, mask))
goto fail;
- }
- shader = glamor_lookup_composite_shader(screen, &key);
- if (shader->prog == 0) {
+ *shader = glamor_lookup_composite_shader(screen, &key);
+ if ((*shader)->prog == 0) {
glamor_fallback("no shader program for this"
"render acccel mode\n");
goto fail;
}
+ if (key.source == SHADER_SOURCE_SOLID)
+ memcpy(&(*shader)->source_solid_color[0],
+ source_solid_color, 4*sizeof(float));
+ else {
+ (*shader)->source_priv = source_pixmap_priv;
+ (*shader)->source = source;
+ }
+
+ if (key.mask == SHADER_MASK_SOLID)
+ memcpy(&(*shader)->mask_solid_color[0],
+ mask_solid_color, 4*sizeof(float));
+ else {
+ (*shader)->mask_priv = mask_pixmap_priv;
+ (*shader)->mask = mask;
+ }
+
+ 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;
+}
+
+void
+glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
+ struct shader_key *key,
+ glamor_composite_shader *shader,
+ struct blendinfo *op_info)
+{
+ glamor_gl_dispatch *dispatch;
+ glamor_screen_private *glamor_priv;
+
+ glamor_priv = dest_priv->base.glamor_priv;
+
dispatch = glamor_get_dispatch(glamor_priv);
dispatch->glUseProgram(shader->prog);
- if (key.source == SHADER_SOURCE_SOLID) {
- glamor_set_composite_solid(dispatch, source_solid_color,
+ if (key->source == SHADER_SOURCE_SOLID) {
+ glamor_set_composite_solid(dispatch,
+ shader->source_solid_color,
shader->source_uniform_location);
} else {
- glamor_set_composite_texture(screen, 0, source,
- source_pixmap_priv, shader->source_wh,
+ glamor_set_composite_texture(glamor_priv, 0,
+ shader->source,
+ shader->source_priv, shader->source_wh,
shader->source_repeat_mode);
}
- if (key.mask != SHADER_MASK_NONE) {
- if (key.mask == SHADER_MASK_SOLID) {
+ if (key->mask != SHADER_MASK_NONE) {
+ if (key->mask == SHADER_MASK_SOLID) {
glamor_set_composite_solid(dispatch,
- mask_solid_color,
+ shader->mask_solid_color,
shader->mask_uniform_location);
} else {
- glamor_set_composite_texture(screen, 1, mask,
- mask_pixmap_priv, shader->mask_wh,
+ glamor_set_composite_texture(glamor_priv, 1,
+ shader->mask,
+ shader->mask_priv, shader->mask_wh,
shader->mask_repeat_mode);
}
}
- glamor_put_dispatch(glamor_priv);
- ret = TRUE;
- memcpy(s_key, &key, sizeof(key));
- *psaved_source_format = saved_source_format;
- goto done;
+ if (op_info->source_blend == GL_ONE
+ && op_info->dest_blend == GL_ZERO) {
+ dispatch->glDisable(GL_BLEND);
+ } else {
+ dispatch->glEnable(GL_BLEND);
+ dispatch->glBlendFunc(op_info->source_blend,
+ op_info->dest_blend);
+ }
-fail:
- if (saved_source_format)
- source->format = saved_source_format;
-done:
- return ret;
+ glamor_put_dispatch(glamor_priv);
}
static Bool
@@ -1233,7 +1256,8 @@ glamor_composite_with_shader(CARD8 op,
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)
+ int nrect, glamor_composite_rect_t * rects,
+ Bool two_pass_ca)
{
ScreenPtr screen = dest->pDrawable->pScreen;
glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
@@ -1244,7 +1268,7 @@ glamor_composite_with_shader(CARD8 op,
GLfloat dst_xscale, dst_yscale;
GLfloat mask_xscale = 1, mask_yscale = 1,
src_xscale = 1, src_yscale = 1;
- struct shader_key key;
+ struct shader_key key, key_ca;
float *vertices;
int dest_x_off, dest_y_off;
int source_x_off, source_y_off;
@@ -1255,14 +1279,30 @@ glamor_composite_with_shader(CARD8 op,
int vert_stride = 4;
int nrect_max;
Bool ret = FALSE;
+ glamor_composite_shader *shader = NULL, *shader_ca = NULL;
+ struct blendinfo op_info, op_info_ca;
if(!glamor_composite_choose_shader(op, source, mask, dest,
source_pixmap_priv, mask_pixmap_priv,
dest_pixmap_priv,
- &key, &saved_source_format)) {
+ &key, &shader, &op_info,
+ &saved_source_format)) {
glamor_fallback("glamor_composite_choose_shader failed\n");
return ret;
}
+ if (two_pass_ca) {
+ if(!glamor_composite_choose_shader(PictOpAdd, source, mask, dest,
+ source_pixmap_priv, mask_pixmap_priv,
+ dest_pixmap_priv,
+ &key_ca, &shader_ca, &op_info_ca,
+ &saved_source_format)) {
+ glamor_fallback("glamor_composite_choose_shader failed\n");
+ return ret;
+ }
+ }
+
+ glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
+ glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
dispatch = glamor_get_dispatch(glamor_priv);
@@ -1277,8 +1317,7 @@ glamor_composite_with_shader(CARD8 op,
pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
if (glamor_priv->has_source_coords) {
- source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
- source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+ source_pixmap = source_pixmap_priv->base.pixmap;
glamor_get_drawable_deltas(source->pDrawable,
source_pixmap, &source_x_off,
&source_y_off);
@@ -1292,8 +1331,7 @@ glamor_composite_with_shader(CARD8 op,
}
if (glamor_priv->has_mask_coords) {
- mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
- mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+ mask_pixmap = mask_pixmap_priv->base.pixmap;
glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
&mask_x_off, &mask_y_off);
pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
@@ -1369,6 +1407,16 @@ glamor_composite_with_shader(CARD8 op,
}
glamor_flush_composite_rects(screen);
nrect -= rect_processed;
+ if (two_pass_ca) {
+ glamor_composite_set_shader_blend(dest_pixmap_priv,
+ &key_ca, shader_ca,
+ &op_info_ca);
+ glamor_flush_composite_rects(screen);
+ if (nrect)
+ glamor_composite_set_shader_blend(dest_pixmap_priv,
+ &key, shader,
+ &op_info);
+ }
}
dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -1475,7 +1523,6 @@ glamor_composite_clipped_region(CARD8 op,
glamor_pixmap_private *temp_src_priv = source_pixmap_priv;
glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv;
int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
-
BoxPtr extent;
glamor_composite_rect_t rect[10];
glamor_composite_rect_t *prect = rect;
@@ -1486,6 +1533,8 @@ glamor_composite_clipped_region(CARD8 op,
int height;
BoxPtr box;
int nbox;
+ Bool two_pass_ca = FALSE;
+
extent = RegionExtents(region);
box = RegionRects(region);
nbox = RegionNumRects(region);
@@ -1557,23 +1606,8 @@ glamor_composite_clipped_region(CARD8 op,
if (mask && mask->componentAlpha) {
if (op == PictOpOver) {
- glamor_composite_clipped_region(PictOpOutReverse,
- temp_src, temp_mask, dest,
- temp_src_priv, temp_mask_priv, dest_pixmap_priv,
- region,
- x_temp_src, y_temp_src,
- x_temp_mask, y_temp_mask,
- x_dest, y_dest);
-
- glamor_composite_clipped_region(PictOpAdd,
- temp_src, temp_mask, dest,
- temp_src_priv, temp_mask_priv, dest_pixmap_priv,
- region,
- x_temp_src, y_temp_src,
- x_temp_mask, y_temp_mask,
- x_dest, y_dest);
- ok = TRUE;
- goto out;
+ two_pass_ca = TRUE;
+ op = PictOpOutReverse;
}
}
@@ -1624,7 +1658,7 @@ glamor_composite_clipped_region(CARD8 op,
ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
temp_src_priv, temp_mask_priv,
dest_pixmap_priv,
- box_cnt, prect);
+ box_cnt, prect, two_pass_ca);
if (!ok)
break;
nbox -= box_cnt;
@@ -1959,7 +1993,6 @@ glamor_composite_glyph_rects(CARD8 op,
int n;
PicturePtr temp_src = NULL;
glamor_composite_rect_t *r;
- Bool ok;
ValidatePicture(src);
ValidatePicture(dst);
@@ -2004,27 +2037,18 @@ glamor_composite_glyph_rects(CARD8 op,
if (mask && mask->componentAlpha) {
if (op == PictOpOver) {
- ok = glamor_composite_with_shader(PictOpOutReverse,
- temp_src, mask, dst, temp_src_priv,
- mask_pixmap_priv, dst_pixmap_priv, nrect, rects);
- if (!ok) {
- goto fallback;
- }
- ok |= glamor_composite_with_shader(PictOpAdd,
+ if (glamor_composite_with_shader(PictOpOutReverse,
temp_src, mask, dst, temp_src_priv,
- mask_pixmap_priv, dst_pixmap_priv, nrect, rects);
- if (ok)
+ mask_pixmap_priv, dst_pixmap_priv, nrect, rects,
+ TRUE))
goto done;
- assert(0);
}
} else {
if (glamor_composite_with_shader(op, temp_src, mask, dst, temp_src_priv,
- mask_pixmap_priv, dst_pixmap_priv, nrect, rects))
+ mask_pixmap_priv, dst_pixmap_priv, nrect, rects, FALSE))
goto done;
}
}
-
-
fallback:
n = nrect;
r = rects;
diff --git a/src/glamor_trapezoid.c b/src/glamor_trapezoid.c
index 3ad9e50..5dd2792 100644
--- a/src/glamor_trapezoid.c
+++ b/src/glamor_trapezoid.c
@@ -701,12 +701,13 @@ _glamor_trapezoids_with_shader(CARD8 op,
ret = glamor_composite_choose_shader(op, temp_src, NULL, dst,
temp_src_priv, NULL, dest_pixmap_priv,
- &key, &saved_source_format);
+ &key, &shader, &op_info, &saved_source_format);
if (ret == FALSE) {
DEBUGF("can not set the shader program for composite\n");
goto TRAPEZOID_RESET_GL;
}
-
+ glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
+ glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, op_info);
glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
key.mask != SHADER_MASK_SOLID);