diff options
author | Zhigang Gong <zhigang.gong@gmail.com> | 2011-08-16 00:21:09 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@linux.intel.com> | 2011-09-26 16:47:01 +0800 |
commit | 67da52ec13a87846201a99d5a31db28668d9fdfd (patch) | |
tree | f79a1303b30abad9667970df9b8fb74493aa1e86 | |
parent | 0eea084db54fb88b9933fd1326a2b0b059b3f9d7 (diff) |
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>
-rw-r--r-- | glamor/glamor_core.c | 52 | ||||
-rw-r--r-- | glamor/glamor_fill.c | 1 | ||||
-rw-r--r-- | glamor/glamor_pixmap.c | 177 | ||||
-rw-r--r-- | glamor/glamor_priv.h | 132 | ||||
-rw-r--r-- | glamor/glamor_putimage.c | 29 | ||||
-rw-r--r-- | glamor/glamor_setspans.c | 11 |
6 files changed, 338 insertions, 64 deletions
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 9f0457380..d4588e28a 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -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; } diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 660ffe014..873f383a5 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -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; diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 1dc1ee93c..1e17069f1 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -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); +// glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); + + glamor_pixmap_ensure_fb(pixmap_priv->container); #ifndef GLAMOR_GLES2 - glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + 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; } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 400988574..1f3e8c464 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -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" diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index addfdf2bd..a7a6186ee 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -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); } } diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index a1d5dc1a6..8b2676b4b 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -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; |