mesa: handle missing read buffer in _mesa_get_color_read_format/type()
authorBrian Paul <brianp@vmware.com>
Mon, 3 Jun 2013 00:07:55 +0000 (18:07 -0600)
committerBrian Paul <brianp@vmware.com>
Mon, 3 Jun 2013 00:12:07 +0000 (18:12 -0600)
We were crashing when GL_READ_BUFFER == GL_NONE.  Check for NULL
pointers and reorganize the code.  The spec doesn't say which error
to generate in this situation, but NVIDIA raises GL_INVALID_OPERATION.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65173
NOTE: This is a candidate for the stable branches.

Tested-by: Vedran Rodic <vrodic@gmail.com>
Reviewed-by: José Fonseca <jfonseca@vmware.com>
src/mesa/main/framebuffer.c

index af3c595258309a5392aaee6ff724e2fa9714794d..0337b8b08e8d7664b95f209c9b33d3b365890b17 100644 (file)
@@ -878,18 +878,29 @@ _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format)
 GLenum
 _mesa_get_color_read_format(struct gl_context *ctx)
 {
-   const GLenum data_type = _mesa_get_format_datatype(
-                               ctx->ReadBuffer->_ColorReadBuffer->Format);
-
-   switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
-   case MESA_FORMAT_ARGB8888:
-      return GL_BGRA;
-   case MESA_FORMAT_RGB565:
-      return GL_BGR;
-   default:
-      if (data_type == GL_UNSIGNED_INT || data_type == GL_INT) {
+   if (!ctx->ReadBuffer || !ctx->ReadBuffer->_ColorReadBuffer) {
+      /* The spec is unclear how to handle this case, but NVIDIA's
+       * driver generates GL_INVALID_OPERATION.
+       */
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT: "
+                  "no GL_READ_BUFFER)");
+      return GL_NONE;
+   }
+   else {
+      const GLenum format = ctx->ReadBuffer->_ColorReadBuffer->Format;
+      const GLenum data_type = _mesa_get_format_datatype(format);
+
+      if (format == MESA_FORMAT_ARGB8888)
+         return GL_BGRA;
+      else if (format == MESA_FORMAT_RGB565)
+         return GL_BGR;
+
+      switch (data_type) {
+      case GL_UNSIGNED_INT:
+      case GL_INT:
          return GL_RGBA_INTEGER;
-      } else {
+      default:
          return GL_RGBA;
       }
    }
@@ -902,26 +913,33 @@ _mesa_get_color_read_format(struct gl_context *ctx)
 GLenum
 _mesa_get_color_read_type(struct gl_context *ctx)
 {
-   const GLenum data_type = _mesa_get_format_datatype(
-                               ctx->ReadBuffer->_ColorReadBuffer->Format);
-
-   switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
-   case MESA_FORMAT_RGB565:
-      return GL_UNSIGNED_SHORT_5_6_5_REV;
-   default:
-      break;
+   if (!ctx->ReadBuffer || !ctx->ReadBuffer->_ColorReadBuffer) {
+      /* The spec is unclear how to handle this case, but NVIDIA's
+       * driver generates GL_INVALID_OPERATION.
+       */
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE: "
+                  "no GL_READ_BUFFER)");
+      return GL_NONE;
    }
-
-   switch (data_type) {
-   case GL_SIGNED_NORMALIZED:
-      return GL_BYTE;
-   case GL_UNSIGNED_INT:
-   case GL_INT:
-   case GL_FLOAT:
-      return data_type;
-   case GL_UNSIGNED_NORMALIZED:
-   default:
-      return GL_UNSIGNED_BYTE;
+   else {
+      const GLenum format = ctx->ReadBuffer->_ColorReadBuffer->Format;
+      const GLenum data_type = _mesa_get_format_datatype(format);
+
+      if (format == MESA_FORMAT_RGB565)
+         return GL_UNSIGNED_SHORT_5_6_5_REV;
+
+      switch (data_type) {
+      case GL_SIGNED_NORMALIZED:
+         return GL_BYTE;
+      case GL_UNSIGNED_INT:
+      case GL_INT:
+      case GL_FLOAT:
+         return data_type;
+      case GL_UNSIGNED_NORMALIZED:
+      default:
+         return GL_UNSIGNED_BYTE;
+      }
    }
 }