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 <zhigang.gong@linux.intel.com>
This commit is contained in:
		
							parent
							
								
									0e2af4d0c9
								
							
						
					
					
						commit
						3c44e3e0ce
					
				| 
						 | 
					@ -289,7 +289,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 | 
					    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 | 
				
			||||||
    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
 | 
					    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;
 | 
					    GLenum format, type;
 | 
				
			||||||
    uint8_t *data, *read;
 | 
					    uint8_t *data, *read;
 | 
				
			||||||
    glamor_screen_private *glamor_priv =
 | 
					    glamor_screen_private *glamor_priv =
 | 
				
			||||||
| 
						 | 
					@ -399,20 +399,38 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 | 
				
			||||||
	"{\n"
 | 
						"{\n"
 | 
				
			||||||
	"	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
 | 
						"	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
 | 
				
			||||||
	"}\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->finish_access_prog = glCreateProgramObjectARB();
 | 
				
			||||||
 | 
					    glamor_priv->aswizzle_prog = glCreateProgramObjectARB();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (GLEW_ARB_fragment_shader) {
 | 
					    if (GLEW_ARB_fragment_shader) {
 | 
				
			||||||
	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
 | 
						vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
 | 
				
			||||||
	fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_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, vs_prog);
 | 
				
			||||||
	glAttachObjectARB(glamor_priv->finish_access_prog, fs_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 {
 | 
					    } else {
 | 
				
			||||||
	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
 | 
						vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
 | 
				
			||||||
	glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog);
 | 
						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->finish_access_prog);
 | 
				
			||||||
 | 
					    glamor_link_glsl_prog(glamor_priv->aswizzle_prog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (GLEW_ARB_fragment_shader) {
 | 
					    if (GLEW_ARB_fragment_shader) {
 | 
				
			||||||
	GLint sampler_uniform_location;
 | 
						GLint sampler_uniform_location;
 | 
				
			||||||
| 
						 | 
					@ -422,6 +440,12 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 | 
				
			||||||
	glUseProgramObjectARB(glamor_priv->finish_access_prog);
 | 
						glUseProgramObjectARB(glamor_priv->finish_access_prog);
 | 
				
			||||||
	glUniform1iARB(sampler_uniform_location, 0);
 | 
						glUniform1iARB(sampler_uniform_location, 0);
 | 
				
			||||||
	glUseProgramObjectARB(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
 | 
					 * Load texture from the pixmap's data pointer and then
 | 
				
			||||||
 * draw the texture to the fbo, and flip the y axis.
 | 
					 * draw the texture to the fbo, and flip the y axis.
 | 
				
			||||||
 * */
 | 
					 * */
 | 
				
			||||||
void
 | 
					static void
 | 
				
			||||||
glamor_load_texture_pixmap(PixmapPtr pixmap)
 | 
					glamor_load_texture_pixmap(PixmapPtr pixmap)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -454,9 +478,12 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void * texel;
 | 
					    void * texel;
 | 
				
			||||||
    GLuint tex;
 | 
					    GLuint tex;
 | 
				
			||||||
 | 
					    int alfa_mode = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (glamor_priv->yInverted)
 | 
					    if (glamor_priv->yInverted)
 | 
				
			||||||
       ptexcoords = texcoords_inverted;
 | 
					       ptexcoords = texcoords_inverted;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					       ptexcoords = texcoords;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stride = pixmap->devKind;
 | 
					    stride = pixmap->devKind;
 | 
				
			||||||
    row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 | 
					    row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 | 
				
			||||||
| 
						 | 
					@ -473,6 +500,7 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
 | 
				
			||||||
    case 24:
 | 
					    case 24:
 | 
				
			||||||
	assert(pixmap->drawable.bitsPerPixel == 32);
 | 
						assert(pixmap->drawable.bitsPerPixel == 32);
 | 
				
			||||||
	/* FALLTHROUGH */
 | 
						/* FALLTHROUGH */
 | 
				
			||||||
 | 
					        alfa_mode = 1;
 | 
				
			||||||
    case 32:
 | 
					    case 32:
 | 
				
			||||||
	format = GL_BGRA;
 | 
						format = GL_BGRA;
 | 
				
			||||||
	type = GL_UNSIGNED_INT_8_8_8_8_REV;
 | 
						type = GL_UNSIGNED_INT_8_8_8_8_REV;
 | 
				
			||||||
| 
						 | 
					@ -515,7 +543,10 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
 | 
				
			||||||
    glEnable(GL_TEXTURE_2D);
 | 
					    glEnable(GL_TEXTURE_2D);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(GLEW_ARB_fragment_shader);
 | 
					    assert(GLEW_ARB_fragment_shader);
 | 
				
			||||||
 | 
					    if (alfa_mode == 0)
 | 
				
			||||||
      glUseProgramObjectARB(glamor_priv->finish_access_prog);
 | 
					      glUseProgramObjectARB(glamor_priv->finish_access_prog);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      glUseProgramObjectARB(glamor_priv->aswizzle_prog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 | 
					    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 | 
				
			||||||
    glDisable(GL_TEXTURE_2D);
 | 
					    glDisable(GL_TEXTURE_2D);
 | 
				
			||||||
| 
						 | 
					@ -547,14 +578,12 @@ glamor_finish_access(DrawablePtr drawable)
 | 
				
			||||||
	    return;
 | 
						    return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
 | 
					    if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
 | 
				
			||||||
      glamor_load_texture_pixmap(pixmap);
 | 
					      glamor_load_texture_pixmap(pixmap);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
 | 
					   if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
 | 
				
			||||||
     glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
 | 
					     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_PACK_BUFFER_EXT, 0);
 | 
				
			||||||
     glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0);
 | 
					     glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0);
 | 
				
			||||||
     glDeleteBuffersARB (1, &pixmap_priv->pbo);
 | 
					     glDeleteBuffersARB (1, &pixmap_priv->pbo);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,6 +159,7 @@ typedef struct glamor_screen_private {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* glamor_finishaccess */
 | 
					    /* glamor_finishaccess */
 | 
				
			||||||
    GLint finish_access_prog;
 | 
					    GLint finish_access_prog;
 | 
				
			||||||
 | 
					    GLint aswizzle_prog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* glamor_solid */
 | 
					    /* glamor_solid */
 | 
				
			||||||
    GLint solid_prog;
 | 
					    GLint solid_prog;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -256,7 +256,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 | 
				
			||||||
    int x_off, y_off;
 | 
					    int x_off, y_off;
 | 
				
			||||||
    float vertices[4][2], texcoords[4][2];
 | 
					    float vertices[4][2], texcoords[4][2];
 | 
				
			||||||
    GLuint tex;
 | 
					    GLuint tex;
 | 
				
			||||||
 | 
					    int alfa_mode = 0;
 | 
				
			||||||
    if (image_format == XYBitmap) {
 | 
					    if (image_format == XYBitmap) {
 | 
				
			||||||
	assert(depth == 1);
 | 
						assert(depth == 1);
 | 
				
			||||||
	glamor_put_image_xybitmap(drawable, gc, x, y, w, h,
 | 
						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:
 | 
					    case 24:
 | 
				
			||||||
	assert(drawable->bitsPerPixel == 32);
 | 
						assert(drawable->bitsPerPixel == 32);
 | 
				
			||||||
	/* FALLTHROUGH */
 | 
						/* FALLTHROUGH */
 | 
				
			||||||
 | 
					        alfa_mode = 1;
 | 
				
			||||||
    case 32:
 | 
					    case 32:
 | 
				
			||||||
	format = GL_BGRA;
 | 
						format = GL_BGRA;
 | 
				
			||||||
	type = GL_UNSIGNED_INT_8_8_8_8_REV;
 | 
						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);
 | 
					    glEnable(GL_TEXTURE_2D);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(GLEW_ARB_fragment_shader);
 | 
					    assert(GLEW_ARB_fragment_shader);
 | 
				
			||||||
 | 
					    if (alfa_mode == 0)
 | 
				
			||||||
      glUseProgramObjectARB(glamor_priv->finish_access_prog);
 | 
					      glUseProgramObjectARB(glamor_priv->finish_access_prog);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      glUseProgramObjectARB(glamor_priv->aswizzle_prog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    x += drawable->x;
 | 
					    x += drawable->x;
 | 
				
			||||||
    y += drawable->y;
 | 
					    y += drawable->y;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,8 +86,7 @@ glamor_create_composite_fs(struct shader_key *key)
 | 
				
			||||||
	"uniform sampler2D source_sampler;\n"
 | 
						"uniform sampler2D source_sampler;\n"
 | 
				
			||||||
	"vec4 get_source()\n"
 | 
						"vec4 get_source()\n"
 | 
				
			||||||
	"{\n"
 | 
						"{\n"
 | 
				
			||||||
	"	return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb,\n"
 | 
					        "       return texture2D(source_sampler, gl_TexCoord[0].xy);\n"
 | 
				
			||||||
	"		    1.0);\n"
 | 
					 | 
				
			||||||
	"}\n";
 | 
						"}\n";
 | 
				
			||||||
    const char *mask_solid_fetch =
 | 
					    const char *mask_solid_fetch =
 | 
				
			||||||
	"uniform vec4 mask;\n"
 | 
						"uniform vec4 mask;\n"
 | 
				
			||||||
| 
						 | 
					@ -105,8 +104,7 @@ glamor_create_composite_fs(struct shader_key *key)
 | 
				
			||||||
	"uniform sampler2D mask_sampler;\n"
 | 
						"uniform sampler2D mask_sampler;\n"
 | 
				
			||||||
	"vec4 get_mask()\n"
 | 
						"vec4 get_mask()\n"
 | 
				
			||||||
	"{\n"
 | 
						"{\n"
 | 
				
			||||||
	"	return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, \n"
 | 
					        "       return texture2D(mask_sampler, gl_TexCoord[1].xy);\n"
 | 
				
			||||||
	"		    1.0);\n"
 | 
					 | 
				
			||||||
	"}\n";
 | 
						"}\n";
 | 
				
			||||||
    const char *in_source_only =
 | 
					    const char *in_source_only =
 | 
				
			||||||
	"void main()\n"
 | 
						"void main()\n"
 | 
				
			||||||
| 
						 | 
					@ -495,15 +493,8 @@ good_source_format(PicturePtr picture)
 | 
				
			||||||
    case PICT_a1:
 | 
					    case PICT_a1:
 | 
				
			||||||
    case PICT_a8:
 | 
					    case PICT_a8:
 | 
				
			||||||
    case PICT_a8r8g8b8:
 | 
					    case PICT_a8r8g8b8:
 | 
				
			||||||
	return TRUE;
 | 
					 | 
				
			||||||
    case PICT_x8r8g8b8:
 | 
					    case PICT_x8r8g8b8:
 | 
				
			||||||
	/* In order to support formats with no alpha, we have to wire the
 | 
						return TRUE;
 | 
				
			||||||
	 * 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);
 | 
					 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
	glamor_fallback("Bad source format 0x%08x\n", picture->format);
 | 
						glamor_fallback("Bad source format 0x%08x\n", picture->format);
 | 
				
			||||||
	return FALSE;
 | 
						return FALSE;
 | 
				
			||||||
| 
						 | 
					@ -517,15 +508,8 @@ good_mask_format(PicturePtr picture)
 | 
				
			||||||
    case PICT_a1:
 | 
					    case PICT_a1:
 | 
				
			||||||
    case PICT_a8:
 | 
					    case PICT_a8:
 | 
				
			||||||
    case PICT_a8r8g8b8:
 | 
					    case PICT_a8r8g8b8:
 | 
				
			||||||
	return TRUE;
 | 
					 | 
				
			||||||
    case PICT_x8r8g8b8:
 | 
					    case PICT_x8r8g8b8:
 | 
				
			||||||
	/* In order to support formats with no alpha, we have to wire the
 | 
						return TRUE;
 | 
				
			||||||
	 * 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);
 | 
					 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
	glamor_fallback("Bad mask format 0x%08x\n", picture->format);
 | 
						glamor_fallback("Bad mask format 0x%08x\n", picture->format);
 | 
				
			||||||
	return FALSE;
 | 
						return FALSE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue