OSDN Git Service

Fix GRALLOC1_PFN_LOCK_FLEX multithread issue.
authorAlexey Dulaev <alexeyx.dulaev@intel.com>
Fri, 5 Oct 2018 08:26:39 +0000 (11:26 +0300)
committerLin Johnson <johnson.lin@intel.com>
Tue, 16 Oct 2018 00:43:27 +0000 (08:43 +0800)
lockFlex fills outFlexLayout->planes with pointer to global variable,
doesn't work from multiple threads.
Solution: rely that caller allocates needed planes structures,
just use them for output.

gralloc1.h about GRALLOC1_PFN_GET_NUM_FLEX_PLANES:
This may be used to efficiently allocate only as many plane structures as necessary before calling into lockFlex.
It means that lockFlex caller is responsible for outFlexLayout->planes allocation.

It also demand fix in GRALLOC1_PFN_GET_NUM_FLEX_PLANES:
should return 3 for HAL_PIXEL_FORMAT_NV12_TILED_INTEL.

Jira: None
Test: check memory regions mapped from different threads don't overlap

cros_gralloc/gralloc1/cros_gralloc1_module.cc

index d9136fa..cdb0083 100644 (file)
@@ -405,10 +405,10 @@ int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage
        return CROS_GRALLOC_ERROR_NONE;
 }
 
-android_flex_plane_t ycbcrplanes[3];
-
 int32_t update_flex_layout(struct android_ycbcr *ycbcr, struct android_flex_layout *outFlexLayout)
 {
+       android_flex_plane_t *ycbcrplanes = outFlexLayout->planes;
+
        outFlexLayout->format = FLEX_FORMAT_YCbCr;
        outFlexLayout->num_planes = 3;
        for (uint32_t i = 0; i < outFlexLayout->num_planes; i++) {
@@ -431,7 +431,6 @@ int32_t update_flex_layout(struct android_ycbcr *ycbcr, struct android_flex_layo
        ycbcrplanes[2].h_increment = static_cast<int32_t>(ycbcr->chroma_step);
        ycbcrplanes[2].v_increment = static_cast<int32_t>(ycbcr->cstride);
 
-       outFlexLayout->planes = ycbcrplanes;
        return 0;
 }
 
@@ -539,7 +538,13 @@ int32_t CrosGralloc1::getNumFlexPlanes(buffer_handle_t buffer, uint32_t *outNumP
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
 
-       *outNumPlanes = drv_num_planes_from_format(hnd->format);
+       if (IsSupportedYUVFormat(hnd->droid_format)) {
+               // for YUV formats flex_lock should provide 3 planes (logical)
+               *outNumPlanes = 3;
+       } else { // otherwise count of physical planes for backward compatibility
+               *outNumPlanes = drv_num_planes_from_format(hnd->droid_format);
+       }
+
        return CROS_GRALLOC_ERROR_NONE;
 }
 
@@ -637,12 +642,15 @@ int32_t CrosGralloc1::getByteStride(buffer_handle_t buffer, uint32_t *outStride,
         return CROS_GRALLOC_ERROR_BAD_HANDLE;
     }
 
-    if (size != drv_num_planes_from_format(hnd->format)) {
+    // size is acquired caller through getNumFlexPlanes,
+    // it returns count of logical planes, might be bigger than needed
+    auto num_planes = drv_num_planes_from_format(hnd->format);
+    if (size < num_planes) {
         ALOGE("Invalid array size- %d", size);
         return -EINVAL;
     }
 
-    memcpy(outStride, hnd->strides, sizeof(*outStride) * size);
+    memcpy(outStride, hnd->strides, sizeof(*outStride) * num_planes);
     return CROS_GRALLOC_ERROR_NONE;
 }