xserver: Branch 'master' - 5 commits

Eric Anholt anholt at kemper.freedesktop.org
Wed Nov 18 10:01:34 PST 2015


 glamor/glamor.c                  |    7 +++++++
 glamor/glamor_composite_glyphs.c |    9 ++++++++-
 glamor/glamor_fbo.c              |   18 ++++++++++++++++++
 glamor/glamor_font.c             |    5 +++++
 glamor/glamor_picture.c          |   37 ++++++++++++++++++++++++++++++-------
 glamor/glamor_priv.h             |    3 +++
 glamor/glamor_render.c           |   16 +++++++++-------
 7 files changed, 80 insertions(+), 15 deletions(-)

New commits:
commit 9a5972801f7789833062e5711e77483b643eef92
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 16:35:56 2015 -0800

    glamor: Fix segfault in fallback picture uploading.
    
    If the source/mask pixmap is a pixmap that doesn't have an FBO
    attached, and it doesn't match the Render operation's size, then we'll
    composite it to a CPU temporary (not sure why).  We would take the
    PictFormatShort from the source Picture, make a pixmap of that depth,
    and try to look up the PictFormat description from the depth and the
    PictFormatShort.  However, the screen's PictFormats are only attached
    to the screen's visuals' depths.  So, with an x2r10g10b10 short format
    (depth 30), we wouldn't find the screen's PictFormat for it
    (associated with depth 32).
    
    Instead of trying to look up from the screen, just use the pFormat
    that came from our source picture.  The only time we need to look up a
    PictFormat when we're doing non-shader gradients, which we put in
    a8r8g8b8.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index c3a8f17..d8574ec 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1279,12 +1279,17 @@ glamor_convert_gradient_picture(ScreenPtr screen,
     PixmapPtr pixmap;
     PicturePtr dst = NULL;
     int error;
+    PictFormatPtr pFormat;
     PictFormatShort format;
 
-    if (!source->pDrawable)
+    if (source->pDrawable) {
+        pFormat = source->pFormat;
+        format = pFormat->format;
+    } else {
         format = PICT_a8r8g8b8;
-    else
-        format = source->format;
+        pFormat = PictureMatchFormat(screen, 32, format);
+    }
+
 #ifdef GLAMOR_GRADIENT_SHADER
     if (!source->pDrawable) {
         if (source->pSourcePict->type == SourcePictTypeLinear) {
@@ -1320,10 +1325,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
         return NULL;
 
     dst = CreatePicture(0,
-                        &pixmap->drawable,
-                        PictureMatchFormat(screen,
-                                           PIXMAN_FORMAT_DEPTH(format),
-                                           format), 0, 0, serverClient, &error);
+                        &pixmap->drawable, pFormat, 0, 0, serverClient, &error);
     glamor_destroy_pixmap(pixmap);
     if (!dst)
         return NULL;
commit e7aa4d3c7420d45cca2b7e1e69e22cebc64d5b74
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 16:03:14 2015 -0800

    glamor: Fix assert failures when fallback picture upload alloc fails.
    
    If the glTexImage (or glTexSubImage) out-of-memories, error out
    cleanly so that we can fall back to software.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 9b09454..d6f37cf 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -534,7 +534,7 @@ glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
  * Upload pixmap to a specified texture.
  * This texture may not be the one attached to it.
  **/
-static void
+static Bool
 __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
                                   GLenum format,
                                   GLenum type,
@@ -567,13 +567,24 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
         glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
     }
+    glamor_priv->suppress_gl_out_of_memory_logging = true;
     if (non_sub)
         glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
     else
         glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
+    glamor_priv->suppress_gl_out_of_memory_logging = false;
+    if (glGetError() == GL_OUT_OF_MEMORY) {
+        if (non_sub) {
+            glDeleteTextures(1, tex);
+            *tex = 0;
+        }
+        return FALSE;
+    }
 
     if (bits == NULL)
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+    return TRUE;
 }
 
 static Bool
@@ -645,10 +656,15 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
         assert(x + fbo_x_off + w <= pixmap_priv->fbo->width);
         assert(y + fbo_y_off + h <= pixmap_priv->fbo->height);
-        __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
-                                          format, type,
-                                          x + fbo_x_off, y + fbo_y_off, w, h,
-                                          bits, pbo);
+        if (!__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
+                                               format, type,
+                                               x + fbo_x_off, y + fbo_y_off,
+                                               w, h,
+                                               bits, pbo)) {
+            if (need_free_bits)
+                free(bits);
+            return FALSE;
+        }
     } else {
         ptexcoords = texcoords_inv;
 
@@ -660,6 +676,15 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                      vertices);
         /* Slow path, we need to flip y or wire alpha to 1. */
         glamor_make_current(glamor_priv);
+
+        if (!__glamor_upload_pixmap_to_texture(pixmap, &tex,
+                                               format, type, 0, 0, w, h, bits,
+                                               pbo)) {
+            if (need_free_bits)
+                free(bits);
+            return FALSE;
+        }
+
         glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
                               GL_FALSE, 2 * sizeof(float), vertices);
         glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -669,8 +694,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
 
         glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
         glamor_set_alu(screen, GXcopy);
-        __glamor_upload_pixmap_to_texture(pixmap, &tex,
-                                          format, type, 0, 0, w, h, bits, pbo);
         glActiveTexture(GL_TEXTURE0);
         glBindTexture(GL_TEXTURE_2D, tex);
 
commit ff8ef975df9cd99ec6f0b8b8047445091bf35ef0
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 15:13:55 2015 -0800

    glamor: Fix rendering when core font texture allocation fails.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c
index 6b3a16a..6753d50 100644
--- a/glamor/glamor_font.c
+++ b/glamor/glamor_font.c
@@ -127,8 +127,13 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
     }
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+    glamor_priv->suppress_gl_out_of_memory_logging = true;
     glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, overall_width, overall_height,
                  0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, bits);
+    glamor_priv->suppress_gl_out_of_memory_logging = false;
+    if (glGetError() == GL_OUT_OF_MEMORY)
+        return NULL;
 
     free(bits);
 
commit a6b05d10da2fe476f46e6dc4ad8a603964735905
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 15:05:11 2015 -0800

    glamor: Fix crashes when the glyph atlas allocation fails.
    
    We already have a fallback path, so we just need to jump to it when we
    hit the failure.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c
index 389c8f4..8692904 100644
--- a/glamor/glamor_composite_glyphs.c
+++ b/glamor/glamor_composite_glyphs.c
@@ -127,6 +127,10 @@ glamor_glyph_atlas_init(ScreenPtr screen, struct glamor_glyph_atlas *atlas)
     atlas->atlas = glamor_create_pixmap(screen, glamor_priv->glyph_atlas_dim,
                                         glamor_priv->glyph_atlas_dim, format->depth,
                                         GLAMOR_CREATE_FBO_NO_FBO);
+    if (!glamor_pixmap_has_fbo(atlas->atlas)) {
+        glamor_destroy_pixmap(atlas->atlas);
+        atlas->atlas = NULL;
+    }
     atlas->x = 0;
     atlas->y = 0;
     atlas->row_height = 0;
@@ -420,8 +424,11 @@ glamor_composite_glyphs(CARD8 op,
                                 glyph_atlas->atlas = NULL;
                             }
                         }
-                        if (!glyph_atlas->atlas)
+                        if (!glyph_atlas->atlas) {
                             glamor_glyph_atlas_init(screen, glyph_atlas);
+                            if (!glyph_atlas->atlas)
+                                goto bail_one;
+                        }
                         glamor_glyph_add(glyph_atlas, glyph_draw);
                     }
 
commit de959ec939b262cb1cb4c0b6146826e3092843f9
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 14:47:42 2015 -0800

    glamor: Handle GL_OUT_OF_MEMORY when allocating texture images.
    
    The spec allows general undefined behavior when GL_OOM is thrown.  But
    if the driver happens to throw the error at this point, it probably
    means the pixmap was just too big, so we should delete that texture
    and have this pixmap fall back to software.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index d4a0236..e69f83d 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -379,6 +379,13 @@ glamor_debug_output_callback(GLenum source,
                              const void *userParam)
 {
     ScreenPtr screen = (void *)userParam;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    if (glamor_priv->suppress_gl_out_of_memory_logging &&
+        source == GL_DEBUG_SOURCE_API && type == GL_DEBUG_TYPE_ERROR) {
+        return;
+    }
+
     LogMessageVerb(X_ERROR, 0, "glamor%d: GL error: %*s\n",
                screen->myNum, length, message);
 }
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 262033f..545f89f 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -347,9 +347,25 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
         glBindTexture(GL_TEXTURE_2D, tex);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+        glamor_priv->suppress_gl_out_of_memory_logging = true;
         glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
                      format, GL_UNSIGNED_BYTE, NULL);
+        glamor_priv->suppress_gl_out_of_memory_logging = false;
     }
+
+    if (glGetError() == GL_OUT_OF_MEMORY) {
+        if (!glamor_priv->logged_any_fbo_allocation_failure) {
+            LogMessageVerb(X_WARNING, 0, "glamor: Failed to allocate %dx%d "
+                           "FBO due to GL_OUT_OF_MEMORY.\n", w, h);
+            LogMessageVerb(X_WARNING, 0,
+                           "glamor: Expect reduced performance.\n");
+            glamor_priv->logged_any_fbo_allocation_failure = true;
+        }
+        glDeleteTextures(1, &tex);
+        return 0;
+    }
+
     return tex;
 }
 
@@ -368,6 +384,8 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
         return fbo;
  new_fbo:
     tex = _glamor_create_tex(glamor_priv, w, h, format, flag == CREATE_PIXMAP_USAGE_SHARED);
+    if (!tex)
+        return NULL;
     fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
 
     return fbo;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index f89d56d..a190e67 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -293,6 +293,9 @@ typedef struct glamor_screen_private {
     ScreenPtr screen;
     int dri3_enabled;
 
+    Bool suppress_gl_out_of_memory_logging;
+    Bool logged_any_fbo_allocation_failure;
+
     /* xv */
     GLint xv_prog;
 


More information about the xorg-commit mailing list