[Mesa-dev] [v6 6/9] intel: prepare for dri images having more than one plane

Topi Pohjolainen topi.pohjolainen at intel.com
Tue May 28 02:17:49 PDT 2013


v2 (Eric):
   - use ARRAY_SIZE
   - re-use 'image_destroy' for cleaning up after failure
   - check directly the region pointer instead of the buffer object
     when determining if a region exists

v3 (Chad):
   - do not duplicate an image without any valid planes
   - do not refactor region setting for multiple fds
   - record the offsets (and strides) also when planes are in
     separate buffers
   - use the region count utility instead of always iterating
     through the entire array

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/intel/intel_screen.c | 58 +++++++++++++++++++++----------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 57c8417..e8ed622 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -491,8 +491,18 @@ intel_create_image_from_texture(__DRIcontext *context, int target,
 static void
 intel_destroy_image(__DRIimage *image)
 {
-    intel_region_release(&image->regions[0]);
-    free(image);
+   int i;
+
+   for (i = 0; i < intel_image_get_region_count(image); ++i) {
+      /**
+       * Failures during creation are cleaned up here and hence not all the
+       * regions may not be valid.
+       */
+      if (image->regions[i])
+         intel_region_release(&image->regions[i]);
+   }
+
+   free(image);
 }
 
 static __DRIimage *
@@ -569,16 +579,23 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
 static __DRIimage *
 intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
 {
+   int i;
    __DRIimage *image;
 
+   /* There needs to be at least one plane per image. */
+   if (!orig_image->regions[0])
+      return NULL;
+
    image = calloc(1, sizeof *image);
    if (image == NULL)
       return NULL;
 
-   intel_region_reference(&image->regions[0], orig_image->regions[0]);
-   if (image->regions[0] == NULL) {
-      free(image);
-      return NULL;
+   for (i = 0; i < intel_image_get_region_count(orig_image); ++i) {
+      intel_region_reference(&image->regions[i], orig_image->regions[i]);
+      if (image->regions[i] == NULL) {
+         intel_destroy_image(image);
+         return NULL;
+      }
    }
 
    image->internal_format = orig_image->internal_format;
@@ -653,15 +670,15 @@ intel_create_image_from_fds(__DRIscreen *screen,
                             void *loaderPrivate)
 {
    struct intel_screen *intelScreen = screen->driverPrivate;
-   struct intel_image_format *f;
+   struct intel_image_format *f = intel_image_format_lookup(fourcc);
    __DRIimage *image;
    int i, index;
 
-   if (fds == NULL || num_fds != 1)
-      return NULL;
-
-   f = intel_image_format_lookup(fourcc);
-   if (f == NULL)
+   /**
+    * In case the image is to consist of multiple regions, there must be exactly
+    * one region per plane.
+    */
+   if (fds == NULL || f == NULL || (num_fds > 1 && f->nplanes != num_fds))
       return NULL;
 
    if (f->nplanes == 1)
@@ -672,12 +689,17 @@ intel_create_image_from_fds(__DRIscreen *screen,
    if (image == NULL)
       return NULL;
 
-   image->regions[0] = intel_region_alloc_for_fd(intelScreen,
-                                             1, width, height,
-                                             strides[0], fds[0], "image");
-   if (image->regions[0] == NULL) {
-      free(image);
-      return NULL;
+   for (i = 0; i < num_fds; i++) {
+      image->regions[i] = intel_region_alloc_for_fd(
+                             intelScreen, f->planes[i].cpp,
+                             width >> f->planes[i].width_shift,
+                             height >> f->planes[i].height_shift,
+                             strides[i], fds[i], "image");
+
+      if (image->regions[i] == NULL) {
+         intel_destroy_image(image);
+         return NULL;
+      }
    }
 
    image->planar_format = f;
-- 
1.8.1.2



More information about the mesa-dev mailing list