From 3c44e3e0ce1e286e0540298d5db547c43903629f Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 1 Jun 2011 19:35:15 +0800 Subject: [PATCH] glamor: Optimize composite when soure/mask is xrgb. Added a new shader aswizlle_prog to wired the alpha to 1 when the image color depth is 24 (xrgb). Then we don't need to fallback the xrgb source/mask to software composite in render phase. Also don't wire the alpha bit to 1 in the render phase. This can get about 2x performance gain with the cairo performance trace's firefox-planet case. Signed-off-by: Zhigang Gong --- glamor/glamor_core.c | 41 ++++++++++++++++++++++++++++++++++------ glamor/glamor_priv.h | 1 + glamor/glamor_putimage.c | 9 ++++++--- glamor/glamor_render.c | 24 ++++------------------- 4 files changed, 46 insertions(+), 29 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index f9e43c50c..0bfa7600a 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -289,7 +289,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - unsigned int stride, row_length, x, y; + unsigned int stride, row_length, y; GLenum format, type; uint8_t *data, *read; glamor_screen_private *glamor_priv = @@ -399,20 +399,38 @@ glamor_init_finish_access_shaders(ScreenPtr screen) "{\n" " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" "}\n"; - GLint fs_prog, vs_prog; + + const char *aswizzle_source = + "varying vec2 texcoords;\n" + "uniform sampler2D sampler;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n" + "}\n"; + + GLint fs_prog, vs_prog, avs_prog, aswizzle_prog; glamor_priv->finish_access_prog = glCreateProgramObjectARB(); + glamor_priv->aswizzle_prog = glCreateProgramObjectARB(); + if (GLEW_ARB_fragment_shader) { vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source); glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog); glAttachObjectARB(glamor_priv->finish_access_prog, fs_prog); + + avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); + aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, aswizzle_source); + glAttachObjectARB(glamor_priv->aswizzle_prog, avs_prog); + glAttachObjectARB(glamor_priv->aswizzle_prog, aswizzle_prog); } else { vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog); + ErrorF("Lack of framgment shader support.\n"); } glamor_link_glsl_prog(glamor_priv->finish_access_prog); + glamor_link_glsl_prog(glamor_priv->aswizzle_prog); if (GLEW_ARB_fragment_shader) { GLint sampler_uniform_location; @@ -422,6 +440,12 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glUseProgramObjectARB(glamor_priv->finish_access_prog); glUniform1iARB(sampler_uniform_location, 0); glUseProgramObjectARB(0); + + sampler_uniform_location = + glGetUniformLocationARB(glamor_priv->aswizzle_prog, "sampler"); + glUseProgramObjectARB(glamor_priv->aswizzle_prog); + glUniform1iARB(sampler_uniform_location, 0); + glUseProgramObjectARB(0); } } @@ -429,7 +453,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen) * Load texture from the pixmap's data pointer and then * draw the texture to the fbo, and flip the y axis. * */ -void +static void glamor_load_texture_pixmap(PixmapPtr pixmap) { @@ -454,9 +478,12 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) void * texel; GLuint tex; + int alfa_mode = 0; if (glamor_priv->yInverted) ptexcoords = texcoords_inverted; + else + ptexcoords = texcoords; stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; @@ -473,6 +500,7 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) case 24: assert(pixmap->drawable.bitsPerPixel == 32); /* FALLTHROUGH */ + alfa_mode = 1; case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -515,7 +543,10 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) glEnable(GL_TEXTURE_2D); assert(GLEW_ARB_fragment_shader); - glUseProgramObjectARB(glamor_priv->finish_access_prog); + if (alfa_mode == 0) + glUseProgramObjectARB(glamor_priv->finish_access_prog); + else + glUseProgramObjectARB(glamor_priv->aswizzle_prog); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisable(GL_TEXTURE_2D); @@ -547,14 +578,12 @@ glamor_finish_access(DrawablePtr drawable) return; } - if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) { glamor_load_texture_pixmap(pixmap); } if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT); glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0); glDeleteBuffersARB (1, &pixmap_priv->pbo); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index d88626f51..8c9ff857c 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -159,6 +159,7 @@ typedef struct glamor_screen_private { /* glamor_finishaccess */ GLint finish_access_prog; + GLint aswizzle_prog; /* glamor_solid */ GLint solid_prog; diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 6a9c1aa60..f1081b055 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -256,7 +256,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int x_off, y_off; float vertices[4][2], texcoords[4][2]; GLuint tex; - + int alfa_mode = 0; if (image_format == XYBitmap) { assert(depth == 1); glamor_put_image_xybitmap(drawable, gc, x, y, w, h, @@ -299,6 +299,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, case 24: assert(drawable->bitsPerPixel == 32); /* FALLTHROUGH */ + alfa_mode = 1; case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -340,8 +341,10 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glEnable(GL_TEXTURE_2D); assert(GLEW_ARB_fragment_shader); - glUseProgramObjectARB(glamor_priv->finish_access_prog); - + if (alfa_mode == 0) + glUseProgramObjectARB(glamor_priv->finish_access_prog); + else + glUseProgramObjectARB(glamor_priv->aswizzle_prog); x += drawable->x; y += drawable->y; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 6139b0d02..e69d370d9 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -86,8 +86,7 @@ glamor_create_composite_fs(struct shader_key *key) "uniform sampler2D source_sampler;\n" "vec4 get_source()\n" "{\n" - " return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb,\n" - " 1.0);\n" + " return texture2D(source_sampler, gl_TexCoord[0].xy);\n" "}\n"; const char *mask_solid_fetch = "uniform vec4 mask;\n" @@ -105,8 +104,7 @@ glamor_create_composite_fs(struct shader_key *key) "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n" - " return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, \n" - " 1.0);\n" + " return texture2D(mask_sampler, gl_TexCoord[1].xy);\n" "}\n"; const char *in_source_only = "void main()\n" @@ -495,15 +493,8 @@ good_source_format(PicturePtr picture) case PICT_a1: case PICT_a8: case PICT_a8r8g8b8: - return TRUE; case PICT_x8r8g8b8: - /* In order to support formats with no alpha, we have to wire the - * alpha to 1 in the shader, which conflicts with - * GL_CLAMP_TO_BORDERing to transparent. We could possibly compute - * coverage of the texels in the sampling area if we need to, but - * that isn't implemented today. - */ - return (picture->repeatType != RepeatNone); + return TRUE; default: glamor_fallback("Bad source format 0x%08x\n", picture->format); return FALSE; @@ -517,15 +508,8 @@ good_mask_format(PicturePtr picture) case PICT_a1: case PICT_a8: case PICT_a8r8g8b8: - return TRUE; case PICT_x8r8g8b8: - /* In order to support formats with no alpha, we have to wire the - * alpha to 1 in the shader, which conflicts with - * GL_CLAMP_TO_BORDERing to transparent. We could possibly compute - * coverage of the texels in the sampling area if we need to, but - * that isn't implemented today. - */ - return (picture->repeatType != RepeatNone); + return TRUE; default: glamor_fallback("Bad mask format 0x%08x\n", picture->format); return FALSE;