glamor: Add color conversion support by using new shader.
There are two places we need to do color conversion. 1. When upload a image data to a texture. 2. When download a texture to a memory buffer. As the color format may not be supported in GLES2. We may need to do the following two operations to convert dat. a. revert argb to bgra / abgr to rgba. b. swap argb to abgr / bgra to rgba. Signed-off-by: Zhigang Gong <zhigang.gong@gmail.com>
This commit is contained in:
		
							parent
							
								
									0eea084db5
								
							
						
					
					
						commit
						67da52ec13
					
				|  | @ -133,7 +133,6 @@ Bool | |||
| glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) | ||||
| { | ||||
|   PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); | ||||
| 
 | ||||
|   return glamor_download_pixmap_to_cpu(pixmap, access); | ||||
| } | ||||
| 
 | ||||
|  | @ -154,17 +153,47 @@ glamor_init_finish_access_shaders(ScreenPtr screen) | |||
|   const char *fs_source = | ||||
|     "varying vec2 source_texture;\n" | ||||
|     "uniform sampler2D sampler;\n" | ||||
|     "uniform int no_revert;" | ||||
|     "uniform int swap_rb;" | ||||
|     "void main()\n" | ||||
|     "{\n" | ||||
|     "	gl_FragColor = texture2D(sampler, source_texture);\n" | ||||
|     "   if (no_revert == 1) \n" | ||||
|     "    { \n" | ||||
|     "     if (swap_rb == 1)   \n" | ||||
|     "	  gl_FragColor = texture2D(sampler, source_texture).bgra;\n" | ||||
|     "     else \n" | ||||
|     "	  gl_FragColor = texture2D(sampler, source_texture).rgba;\n" | ||||
|     "    } \n" | ||||
|     "   else \n" | ||||
|     "    { \n" | ||||
|     "     if (swap_rb == 1)   \n" | ||||
|     "	    gl_FragColor = texture2D(sampler, source_texture).argb;\n" | ||||
|     "     else \n" | ||||
|     "	    gl_FragColor = texture2D(sampler, source_texture).abgr;\n" | ||||
|     "    } \n" | ||||
|     "}\n"; | ||||
|      | ||||
|   const char *set_alpha_source = | ||||
|     "varying vec2 source_texture;\n" | ||||
|     "uniform sampler2D sampler;\n" | ||||
|     "uniform int no_revert;" | ||||
|     "uniform int swap_rb;" | ||||
|     "void main()\n" | ||||
|     "{\n" | ||||
|     " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n" | ||||
|     "   if (no_revert == 1) \n" | ||||
|     "    { \n" | ||||
|     "     if (swap_rb == 1)   \n" | ||||
|     "	  gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n" | ||||
|     "     else \n" | ||||
|     "	  gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n" | ||||
|     "    } \n" | ||||
|     "   else \n" | ||||
|     "    { \n" | ||||
|     "     if (swap_rb == 1)   \n" | ||||
|     "	  gl_FragColor = vec4(1,  texture2D(sampler, source_texture).rgb);\n" | ||||
|     "     else \n" | ||||
|     "	  gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n" | ||||
|     "    } \n" | ||||
|     "}\n"; | ||||
|   GLint fs_prog, vs_prog, avs_prog, set_alpha_prog; | ||||
|   GLint sampler_uniform_location; | ||||
|  | @ -190,17 +219,31 @@ glamor_init_finish_access_shaders(ScreenPtr screen) | |||
|   glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); | ||||
|   glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]); | ||||
| 
 | ||||
|   glamor_priv->finish_access_no_revert[0] =  | ||||
|     glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert"); | ||||
| 
 | ||||
|   glamor_priv->finish_access_swap_rb[0] =  | ||||
|     glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb"); | ||||
|   sampler_uniform_location = | ||||
|     glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); | ||||
|   glUseProgram(glamor_priv->finish_access_prog[0]); | ||||
|   glUniform1i(sampler_uniform_location, 0); | ||||
|   glUniform1i(glamor_priv->finish_access_no_revert[0],1); | ||||
|   glUniform1i(glamor_priv->finish_access_swap_rb[0],0); | ||||
|   glUseProgram(0); | ||||
| 
 | ||||
|   glamor_priv->finish_access_no_revert[1] =  | ||||
|     glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert"); | ||||
|   glamor_priv->finish_access_swap_rb[1] =  | ||||
|     glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb"); | ||||
|   sampler_uniform_location = | ||||
|     glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler"); | ||||
|   glUseProgram(glamor_priv->finish_access_prog[1]); | ||||
|   glUniform1i(glamor_priv->finish_access_no_revert[1],1); | ||||
|   glUniform1i(sampler_uniform_location, 0); | ||||
|   glUniform1i(glamor_priv->finish_access_swap_rb[1],0); | ||||
|   glUseProgram(0); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void | ||||
|  | @ -224,8 +267,9 @@ glamor_finish_access(DrawablePtr drawable) | |||
|     pixmap_priv->pbo_valid = FALSE; | ||||
|     glDeleteBuffers(1, &pixmap_priv->pbo); | ||||
|     pixmap_priv->pbo = 0; | ||||
|   } else | ||||
|   } else { | ||||
|     free(pixmap->devPrivate.ptr); | ||||
|   } | ||||
| 
 | ||||
|   pixmap->devPrivate.ptr = NULL; | ||||
| } | ||||
|  |  | |||
|  | @ -143,7 +143,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, | |||
|     GLfloat color[4]; | ||||
|     float vertices[8]; | ||||
|     GLfloat xscale, yscale; | ||||
|      | ||||
|     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { | ||||
|         glamor_fallback("dest %p has no fbo.\n", pixmap); | ||||
| 	goto fail; | ||||
|  |  | |||
|  | @ -83,12 +83,15 @@ glamor_validate_pixmap(PixmapPtr pixmap) | |||
| void | ||||
| glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) | ||||
| { | ||||
|   glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); | ||||
| #ifndef GLAMOR_GLES2 | ||||
|   glMatrixMode(GL_PROJECTION);                                                                                                                                                                  glLoadIdentity(); | ||||
|   glMatrixMode(GL_MODELVIEW);                                                                                                                                                                   glLoadIdentity();                                         | ||||
| #endif | ||||
| //  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
 | ||||
| 
 | ||||
|   glamor_pixmap_ensure_fb(pixmap_priv->container); | ||||
| #ifndef GLAMOR_GLES2 | ||||
|   glMatrixMode(GL_PROJECTION); | ||||
|   glLoadIdentity(); | ||||
|   glMatrixMode(GL_MODELVIEW); | ||||
|   glLoadIdentity();                                         | ||||
| #endif | ||||
|   glViewport(0, 0, | ||||
| 	     pixmap_priv->container->drawable.width, | ||||
| 	     pixmap_priv->container->drawable.height); | ||||
|  | @ -199,7 +202,7 @@ glamor_set_alu(unsigned char alu) | |||
|  * Upload pixmap to a specified texture. | ||||
|  * This texture may not be the one attached to it. | ||||
|  **/ | ||||
| 
 | ||||
| int in_restore = 0; | ||||
| static void  | ||||
| __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, GLuint tex) | ||||
| { | ||||
|  | @ -225,7 +228,6 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, | |||
| 
 | ||||
|   if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { | ||||
|     iformat = format; | ||||
|     type = GL_UNSIGNED_BYTE; | ||||
|   } | ||||
| 
 | ||||
|   stride = pixmap->devKind; | ||||
|  | @ -264,7 +266,8 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, | |||
| 
 | ||||
| static void | ||||
| _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,  | ||||
|                                  GLenum type, int no_alpha, int flip) | ||||
|                                  GLenum type, int no_alpha, int no_revert,  | ||||
|                                  int flip) | ||||
| { | ||||
| 
 | ||||
|   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); | ||||
|  | @ -290,8 +293,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, | |||
| 
 | ||||
|   /* Try fast path firstly, upload the pixmap to the texture attached
 | ||||
|    * to the fbo directly. */ | ||||
| 
 | ||||
|   if (no_alpha == 0 && !need_flip) { | ||||
|   if (no_alpha == 0 && no_revert == 1 && !need_flip) { | ||||
|     __glamor_upload_pixmap_to_texture(pixmap, format, type, pixmap_priv->tex); | ||||
|     return; | ||||
|   } | ||||
|  | @ -303,14 +305,6 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, | |||
|     ptexcoords = texcoords_inv; | ||||
| 
 | ||||
|   /* Slow path, we need to flip y or wire alpha to 1. */ | ||||
| #if 0 | ||||
|   glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); | ||||
|   glEnableClientState(GL_VERTEX_ARRAY); | ||||
| 
 | ||||
|   glClientActiveTexture(GL_TEXTURE0); | ||||
|   glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords); | ||||
|   glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||||
| #else | ||||
|   glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, | ||||
|                         2 * sizeof(float), | ||||
|                         vertices); | ||||
|  | @ -319,10 +313,8 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, | |||
|                         2 * sizeof(float), | ||||
|                         ptexcoords); | ||||
|   glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); | ||||
| #endif | ||||
|   glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); | ||||
|   glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); | ||||
| 
 | ||||
|   glamor_set_destination_pixmap_priv_nc(pixmap_priv); | ||||
|   glGenTextures(1, &tex); | ||||
| 
 | ||||
|   __glamor_upload_pixmap_to_texture(pixmap, format, type, tex); | ||||
|  | @ -331,12 +323,18 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, | |||
| 
 | ||||
|   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
| #ifndef GLAMOR_GLES2 | ||||
|   glEnable(GL_TEXTURE_2D); | ||||
| #endif | ||||
|   glUseProgram(glamor_priv->finish_access_prog[no_alpha]); | ||||
|   glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); | ||||
|       glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0); | ||||
| 
 | ||||
|   glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | ||||
| 
 | ||||
| #ifndef GLAMOR_GLES2 | ||||
|   glDisable(GL_TEXTURE_2D); | ||||
| #endif | ||||
|   glUseProgram(0); | ||||
|   glDisableVertexAttribArray(GLAMOR_VERTEX_POS); | ||||
|   glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); | ||||
|  | @ -386,7 +384,7 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap) | |||
|  * 2. no_alpha != 0, we need to wire the alpha. | ||||
|  * */ | ||||
| static int | ||||
| glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha) | ||||
| glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert) | ||||
| { | ||||
|   int need_fbo; | ||||
|   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); | ||||
|  | @ -402,7 +400,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha) | |||
|   if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))  | ||||
|     return 0;  | ||||
| 
 | ||||
|   if (no_alpha != 0 || !glamor_priv->yInverted) | ||||
|   if (no_alpha != 0 || no_revert == 0 || !glamor_priv->yInverted) | ||||
|     need_fbo = 1; | ||||
|   else | ||||
|     need_fbo = 0; | ||||
|  | @ -427,16 +425,17 @@ enum glamor_pixmap_status | |||
| glamor_upload_pixmap_to_texture(PixmapPtr pixmap) | ||||
| { | ||||
|   GLenum format, type; | ||||
|   int no_alpha; | ||||
|   int no_alpha, no_revert; | ||||
| 
 | ||||
|   if (glamor_get_tex_format_type_from_pixmap(pixmap,  | ||||
| 					     &format,  | ||||
| 					     &type,  | ||||
| 					     &no_alpha)) { | ||||
| 					     &no_alpha, | ||||
|                                              &no_revert)) { | ||||
|     glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); | ||||
|     return GLAMOR_UPLOAD_FAILED; | ||||
|   } | ||||
|   if (glamor_pixmap_upload_prepare(pixmap, no_alpha)) | ||||
|   if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert)) | ||||
|     return GLAMOR_UPLOAD_FAILED; | ||||
|   glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD, | ||||
| 		      "Uploading pixmap %p  %dx%d depth%d.\n",  | ||||
|  | @ -444,7 +443,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap) | |||
| 		      pixmap->drawable.width,  | ||||
| 		      pixmap->drawable.height, | ||||
| 		      pixmap->drawable.depth); | ||||
|   _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1); | ||||
|   _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, no_revert, 1); | ||||
|   return GLAMOR_UPLOAD_DONE; | ||||
| } | ||||
| 
 | ||||
|  | @ -468,18 +467,101 @@ void | |||
| glamor_restore_pixmap_to_texture(PixmapPtr pixmap) | ||||
| { | ||||
|   GLenum format, type; | ||||
|   int no_alpha; | ||||
|   int no_alpha, no_revert; | ||||
| 
 | ||||
|   if (glamor_get_tex_format_type_from_pixmap(pixmap,  | ||||
| 					     &format,  | ||||
| 					     &type,  | ||||
| 					     &no_alpha)) { | ||||
| 					     &no_alpha,  | ||||
|                                              &no_revert)) { | ||||
|     ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth); | ||||
|     assert(0); | ||||
|   } | ||||
|   _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1); | ||||
| 
 | ||||
|   in_restore = 1; | ||||
|   _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, no_revert, 1); | ||||
|   in_restore = 0; | ||||
| } | ||||
| 
 | ||||
| /* 
 | ||||
|  * as gles2 only support a very small set of color format and | ||||
|  * type when do glReadPixel,   | ||||
|  * Before we use glReadPixels to get back a textured pixmap,  | ||||
|  * Use shader to convert it to a supported format and thus | ||||
|  * get a new temporary pixmap returned. | ||||
|  * */ | ||||
| 
 | ||||
| PixmapPtr | ||||
| glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,  | ||||
|                                GLenum *type, int no_alpha, int no_revert) | ||||
| { | ||||
|     glamor_pixmap_private *source_priv; | ||||
|     glamor_screen_private *glamor_priv; | ||||
|     ScreenPtr screen; | ||||
|     PixmapPtr temp_pixmap; | ||||
|     glamor_pixmap_private *temp_pixmap_priv; | ||||
|     static float vertices[8] = {-1, -1, | ||||
| 			      1, -1, | ||||
| 			      1,  1, | ||||
| 			      -1,  1}; | ||||
|     static float texcoords[8] = {0, 0, | ||||
| 				   1, 0, | ||||
| 				   1, 1, | ||||
| 				   0, 1}; | ||||
| 
 | ||||
|     int swap_rb = 0; | ||||
| 
 | ||||
|     screen = source->drawable.pScreen; | ||||
| 
 | ||||
|     glamor_priv = glamor_get_screen_private(screen); | ||||
|     source_priv = glamor_get_pixmap_private(source); | ||||
|     if (*format == GL_BGRA) { | ||||
|       *format = GL_RGBA; | ||||
|       swap_rb = 1; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     temp_pixmap = (*screen->CreatePixmap)(screen, | ||||
| 			                  source->drawable.width, | ||||
| 					  source->drawable.height, | ||||
| 					  source->drawable.depth, | ||||
| 					  0); | ||||
| 
 | ||||
|     temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap); | ||||
| 
 | ||||
|     glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex); | ||||
|     glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width,  | ||||
| 		 source->drawable.height, 0, | ||||
| 		 *format, *type, NULL); | ||||
|      | ||||
|     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, | ||||
|                         2 * sizeof(float), | ||||
|                         vertices); | ||||
|     glEnableVertexAttribArray(GLAMOR_VERTEX_POS); | ||||
|      | ||||
|     glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, | ||||
|                         2 * sizeof(float), | ||||
|                         texcoords); | ||||
|     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); | ||||
| 
 | ||||
|     glActiveTexture(GL_TEXTURE0); | ||||
|     glBindTexture(GL_TEXTURE_2D, source_priv->tex); | ||||
| 
 | ||||
|     glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv); | ||||
| 
 | ||||
|     glUseProgram(glamor_priv->finish_access_prog[no_alpha]); | ||||
|     glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); | ||||
|       glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb); | ||||
| 
 | ||||
|     glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | ||||
| 
 | ||||
|     glDisableVertexAttribArray(GLAMOR_VERTEX_POS); | ||||
|     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); | ||||
|     glUseProgram(0); | ||||
|     glFlush(); | ||||
|     return temp_pixmap;  | ||||
| } | ||||
|   | ||||
| 
 | ||||
| /**
 | ||||
|  * Move a pixmap to CPU memory. | ||||
|  | @ -497,18 +579,21 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) | |||
|   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); | ||||
|   unsigned int stride, row_length, y; | ||||
|   GLenum format, type, gl_access, gl_usage; | ||||
|   int no_alpha; | ||||
|   int no_alpha, no_revert; | ||||
|   uint8_t *data = NULL, *read; | ||||
|   PixmapPtr temp_pixmap = NULL; | ||||
|   ScreenPtr screen; | ||||
|   glamor_screen_private *glamor_priv = | ||||
|     glamor_get_screen_private(pixmap->drawable.pScreen); | ||||
| 
 | ||||
| 
 | ||||
|    | ||||
|   screen = pixmap->drawable.pScreen; | ||||
|   if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) | ||||
|     return TRUE; | ||||
|   if (glamor_get_tex_format_type_from_pixmap(pixmap,  | ||||
| 					     &format, | ||||
| 					     &type,  | ||||
| 					     &no_alpha)) { | ||||
| 					     &no_alpha, | ||||
|                                              &no_revert)) { | ||||
|     ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth); | ||||
|     assert(0);  // Should never happen.
 | ||||
|     return FALSE; | ||||
|  | @ -521,13 +606,21 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) | |||
| 		      pixmap->drawable.width,  | ||||
| 		      pixmap->drawable.height, | ||||
| 		      pixmap->drawable.depth); | ||||
|   | ||||
| 
 | ||||
|   stride = pixmap->devKind; | ||||
| 
 | ||||
|   glamor_set_destination_pixmap_priv_nc(pixmap_priv); | ||||
|   /* XXX we may don't need to validate it on GPU here,
 | ||||
|    * we can just validate it on CPU. */ | ||||
|   glamor_validate_pixmap(pixmap);  | ||||
|   switch (access) { | ||||
|   | ||||
|   if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 | ||||
|     && ((format != GL_RGBA && format != GL_RGB && format != GL_ALPHA) || no_revert != 1)) { | ||||
|      | ||||
|     temp_pixmap = glamor_es2_pixmap_read_prepare(pixmap, &format, &type, no_alpha, no_revert); | ||||
| 
 | ||||
|   }  | ||||
|  switch (access) { | ||||
|   case GLAMOR_ACCESS_RO: | ||||
|     gl_access = GL_READ_ONLY; | ||||
|     gl_usage = GL_STREAM_READ; | ||||
|  | @ -544,9 +637,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) | |||
|     ErrorF("Glamor: Invalid access code. %d\n", access); | ||||
|     assert(0); | ||||
|   } | ||||
|   if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) | ||||
|   if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { | ||||
|     data = malloc(stride * pixmap->drawable.height); | ||||
|   } | ||||
|   row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; | ||||
| 
 | ||||
|   if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { | ||||
|     glPixelStorei(GL_PACK_ALIGNMENT, 1); | ||||
|     glPixelStorei(GL_PACK_ROW_LENGTH, row_length); | ||||
|  | @ -582,8 +677,10 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) | |||
|     } | ||||
|     glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); | ||||
|     } else { | ||||
|     if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) | ||||
|       type = GL_UNSIGNED_SHORT_5_5_5_1; | ||||
|     glReadPixels (0, 0, | ||||
|                     row_length, pixmap->drawable.height, | ||||
|                     pixmap->drawable.width, pixmap->drawable.height, | ||||
|                     format, type, data); | ||||
|     } | ||||
|   } else { | ||||
|  | @ -614,6 +711,12 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) | |||
|   glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||
| done: | ||||
|   pixmap->devPrivate.ptr = data; | ||||
| 
 | ||||
|   if (temp_pixmap) {  | ||||
|       glFlush(); | ||||
|       (*screen->DestroyPixmap)(temp_pixmap); | ||||
|   } | ||||
| 
 | ||||
|   return TRUE; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,6 +43,7 @@ | |||
| #define GL_UNSIGNED_INT_8_8_8_8                 0x8035 | ||||
| #define GL_UNSIGNED_INT_8_8_8_8_REV             0x8367 | ||||
| #define GL_UNSIGNED_INT_2_10_10_10_REV          0x8368 | ||||
| #define GL_UNSIGNED_INT_10_10_10_2              0x8036 | ||||
| #define GL_UNSIGNED_SHORT_5_6_5_REV             0x8364 | ||||
| #define GL_UNSIGNED_SHORT_1_5_5_5_REV           0x8366 | ||||
| #define GL_UNSIGNED_SHORT_4_4_4_4_REV           0x8365 | ||||
|  | @ -236,6 +237,8 @@ typedef struct glamor_screen_private { | |||
| 
 | ||||
|   /* glamor_finishaccess */ | ||||
|   GLint finish_access_prog[2]; | ||||
|   GLint finish_access_no_revert[2]; | ||||
|   GLint finish_access_swap_rb[2]; | ||||
| 
 | ||||
|   /* glamor_solid */ | ||||
|   GLint solid_prog; | ||||
|  | @ -408,13 +411,16 @@ format_for_pixmap(PixmapPtr pixmap) | |||
|  * | ||||
|  * Return 0 if find a matched texture type. Otherwise return -1. | ||||
|  **/ | ||||
| #ifndef GLAMOR_GLES2 | ||||
| static inline int  | ||||
| glamor_get_tex_format_type_from_pictformat(PictFormatShort format, | ||||
| 					   GLenum *tex_format,  | ||||
| 					   GLenum *tex_type, | ||||
| 					   int *no_alpha) | ||||
| 					   int *no_alpha, | ||||
|                                            int *no_revert) | ||||
| { | ||||
|   *no_alpha = 0; | ||||
|   *no_revert = 1; | ||||
|   switch (format) { | ||||
|   case PICT_a1: | ||||
|     *tex_format = GL_COLOR_INDEX; | ||||
|  | @ -497,13 +503,125 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format, | |||
|   } | ||||
|   return 0; | ||||
| } | ||||
| #else | ||||
| #define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst) | ||||
| 
 | ||||
| static inline int  | ||||
| glamor_get_tex_format_type_from_pictformat(PictFormatShort format, | ||||
| 					   GLenum *tex_format,  | ||||
| 					   GLenum *tex_type, | ||||
| 					   int *no_alpha, | ||||
|                                            int *no_revert) | ||||
| { | ||||
|   *no_alpha = 0; | ||||
|   *no_revert = IS_LITTLE_ENDIAN; | ||||
| 
 | ||||
|   switch (format) { | ||||
|   case PICT_b8g8r8x8: | ||||
|     *no_alpha = 1; | ||||
|   case PICT_b8g8r8a8: | ||||
|     *tex_format = GL_BGRA; | ||||
|     *tex_type = GL_UNSIGNED_BYTE; | ||||
|     *no_revert = !IS_LITTLE_ENDIAN; | ||||
|     break; | ||||
| 
 | ||||
|   case PICT_x8r8g8b8: | ||||
|     *no_alpha = 1; | ||||
|   case PICT_a8r8g8b8: | ||||
|     *tex_format = GL_BGRA; | ||||
|     *tex_type = GL_UNSIGNED_BYTE; | ||||
|     break; | ||||
| 
 | ||||
|   case PICT_x8b8g8r8: | ||||
|     *no_alpha = 1; | ||||
|   case PICT_a8b8g8r8: | ||||
|     *tex_format = GL_RGBA; | ||||
|     *tex_type = GL_UNSIGNED_BYTE; | ||||
|     break; | ||||
| 
 | ||||
|   case PICT_x2r10g10b10: | ||||
|     *no_alpha = 1; | ||||
|   case PICT_a2r10g10b10: | ||||
|     *tex_format = GL_BGRA; | ||||
|     *tex_type = GL_UNSIGNED_INT_10_10_10_2; | ||||
|     *no_revert = TRUE; | ||||
|     break; | ||||
| 
 | ||||
|   case PICT_x2b10g10r10: | ||||
|     *no_alpha = 1; | ||||
|   case PICT_a2b10g10r10: | ||||
|     *tex_format = GL_RGBA; | ||||
|     *tex_type = GL_UNSIGNED_INT_10_10_10_2; | ||||
|     *no_revert = TRUE; | ||||
|     break; | ||||
|   | ||||
|   case PICT_r5g6b5: | ||||
|     *tex_format = GL_RGB; | ||||
|     *tex_type = GL_UNSIGNED_SHORT_5_6_5; | ||||
|     *no_revert = TRUE; | ||||
|     break; | ||||
| 
 | ||||
|   case PICT_b5g6r5: | ||||
|     *tex_format = GL_RGB; | ||||
|     *tex_type = GL_UNSIGNED_SHORT_5_6_5; | ||||
|     *no_revert = FALSE; | ||||
|     break; | ||||
| 
 | ||||
|   case PICT_x1b5g5r5: | ||||
|     *no_alpha = 1; | ||||
|   case PICT_a1b5g5r5: | ||||
|     *tex_format = GL_RGBA; | ||||
|     *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; | ||||
|     *no_revert = TRUE; | ||||
|     break; | ||||
|                 | ||||
|   case PICT_x1r5g5b5: | ||||
|     *no_alpha = 1; | ||||
|   case PICT_a1r5g5b5: | ||||
|     *tex_format = GL_BGRA; | ||||
|     *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; | ||||
|     *no_revert = TRUE; | ||||
|     break; | ||||
| 
 | ||||
|   case PICT_a8: | ||||
|     *tex_format = GL_ALPHA; | ||||
|     *tex_type = GL_UNSIGNED_BYTE; | ||||
|     *no_revert = TRUE; | ||||
|     break; | ||||
| 
 | ||||
|   case PICT_x4r4g4b4: | ||||
|     *no_alpha = 1; | ||||
|   case PICT_a4r4g4b4: | ||||
|     *tex_format = GL_BGRA; | ||||
|     *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; | ||||
|     *no_revert = TRUE; | ||||
|     break; | ||||
| 
 | ||||
|   case PICT_x4b4g4r4: | ||||
|     *no_alpha = 1; | ||||
|   case PICT_a4b4g4r4: | ||||
|     *tex_format = GL_RGBA; | ||||
|     *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; | ||||
|     *no_revert = TRUE; | ||||
|     break; | ||||
|   | ||||
|   default: | ||||
|     LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format); | ||||
|     return -1; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| static inline int  | ||||
| glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, | ||||
|                                        GLenum *format,  | ||||
|                                        GLenum *type,  | ||||
|                                        int *ax) | ||||
|                                        int *no_alpha, | ||||
|                                        int *no_revert) | ||||
| { | ||||
|   glamor_pixmap_private *pixmap_priv; | ||||
|   PictFormatShort pict_format; | ||||
|  | @ -515,7 +633,8 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, | |||
|     pict_format = format_for_depth(pixmap->drawable.depth); | ||||
| 
 | ||||
|   return glamor_get_tex_format_type_from_pictformat(pict_format,  | ||||
| 						    format, type, ax);   | ||||
| 						    format, type,  | ||||
|                                                     no_alpha, no_revert);   | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -658,6 +777,11 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv); | |||
|  * */ | ||||
| void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv); | ||||
| 
 | ||||
| 
 | ||||
| PixmapPtr | ||||
| glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,  | ||||
|                                GLenum *type, int no_alpha, int no_revert); | ||||
| 
 | ||||
| void glamor_set_alu(unsigned char alu); | ||||
| Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); | ||||
| void glamor_get_transform_uniform_locations(GLint prog, | ||||
|  | @ -870,7 +994,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr | |||
| 
 | ||||
| 
 | ||||
| #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD  | ||||
| #define GLAMOR_DELAYED_FILLING | ||||
| //#define GLAMOR_DELAYED_FILLING
 | ||||
| 
 | ||||
| 
 | ||||
| #include"glamor_utils.h"  | ||||
|  |  | |||
|  | @ -265,7 +265,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, | |||
|     float vertices[8], texcoords[8]; | ||||
|     GLfloat xscale, yscale, txscale, tyscale; | ||||
|     GLuint tex; | ||||
|     int no_alpha; | ||||
|     int no_alpha, no_revert; | ||||
|     if (image_format == XYBitmap) { | ||||
| 	assert(depth == 1); | ||||
|         goto fail; | ||||
|  | @ -290,7 +290,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, | |||
|     if (glamor_get_tex_format_type_from_pixmap(pixmap, | ||||
|                                                &format,  | ||||
|                                                &type,  | ||||
|                                                &no_alpha | ||||
|                                                &no_alpha, | ||||
|                                                &no_revert | ||||
|                                                )) { | ||||
|       glamor_fallback("unknown depth. %d \n",  | ||||
|                      drawable->depth); | ||||
|  | @ -300,14 +301,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, | |||
|     /* XXX consider to reuse a function to do the following work. */ | ||||
|     glamor_set_destination_pixmap_priv_nc(pixmap_priv); | ||||
|     glamor_validate_pixmap(pixmap); | ||||
| #if 0 | ||||
|     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); | ||||
|     glEnableClientState(GL_VERTEX_ARRAY); | ||||
| 
 | ||||
|     glClientActiveTexture(GL_TEXTURE0); | ||||
|     glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); | ||||
|     glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||||
| #else | ||||
|     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, | ||||
|                         2 * sizeof(float), | ||||
|                         vertices); | ||||
|  | @ -317,7 +310,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, | |||
|                         2 * sizeof(float), | ||||
|                         texcoords); | ||||
|     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); | ||||
| #endif | ||||
| 
 | ||||
|     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { | ||||
|       glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||||
|  | @ -333,20 +325,25 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, | |||
|     glActiveTexture(GL_TEXTURE0); | ||||
|     glBindTexture(GL_TEXTURE_2D, tex); | ||||
|     if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { | ||||
|       type = GL_UNSIGNED_BYTE; | ||||
|       iformat = format; | ||||
|     }  | ||||
|     else { | ||||
|       iformat = GL_RGBA; | ||||
|     } | ||||
| 
 | ||||
|     glTexImage2D(GL_TEXTURE_2D, 0, iformat, | ||||
| 		 w, h, 0, | ||||
| 		 format, type, bits); | ||||
| 
 | ||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
| #ifndef GLAMOR_GLES2 | ||||
|     glEnable(GL_TEXTURE_2D); | ||||
| #endif | ||||
| 
 | ||||
|     glUseProgram(glamor_priv->finish_access_prog[no_alpha]); | ||||
|     glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); | ||||
|       glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0); | ||||
| 
 | ||||
|     x += drawable->x; | ||||
|     y += drawable->y; | ||||
|  | @ -394,7 +391,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, | |||
| 	glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | ||||
|     } | ||||
| 
 | ||||
| #ifndef GLAMOR_GLES2 | ||||
|     glDisable(GL_TEXTURE_2D); | ||||
| #endif | ||||
|     glUseProgram(0); | ||||
|     glDisableVertexAttribArray(GLAMOR_VERTEX_POS); | ||||
|     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); | ||||
|  | @ -409,9 +408,9 @@ fail: | |||
|     glamor_set_planemask(pixmap, ~0); | ||||
|     glamor_fallback("to %p (%c)\n", | ||||
| 		    drawable, glamor_get_drawable_location(drawable)); | ||||
|     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { | ||||
| 	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format, | ||||
|     if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) { | ||||
| 	fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h, left_pad, image_format, | ||||
| 		   bits); | ||||
| 	glamor_finish_access(drawable); | ||||
| 	glamor_finish_access(&pixmap->drawable); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -38,7 +38,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, | |||
|     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); | ||||
|     glamor_screen_private *glamor_priv; | ||||
|     GLenum format, type; | ||||
|     int no_alpha, i; | ||||
|     int no_alpha, no_revert, i; | ||||
|     uint8_t *drawpixels_src = (uint8_t *)src; | ||||
|     RegionPtr clip = fbGetCompositeClip(gc); | ||||
|     BoxRec *pbox; | ||||
|  | @ -46,18 +46,23 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, | |||
| 
 | ||||
|     glamor_priv = glamor_get_screen_private(drawable->pScreen); | ||||
| 
 | ||||
|     if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) | ||||
|     if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { | ||||
|       glamor_fallback("ES2 fallback.\n"); | ||||
|       goto fail; | ||||
|     } | ||||
| 
 | ||||
|     if (glamor_get_tex_format_type_from_pixmap(dest_pixmap, | ||||
|                                                &format,  | ||||
|                                                &type,  | ||||
|                                                &no_alpha | ||||
|                                                &no_alpha, | ||||
|                                                &no_revert | ||||
|                                                )) { | ||||
|       glamor_fallback("unknown depth. %d \n",  | ||||
|                      drawable->depth); | ||||
|       goto fail; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     if (glamor_set_destination_pixmap(dest_pixmap)) | ||||
| 	goto fail; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue