Align secure video surfaces to 1 MB
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos5.git] / gralloc / gralloc.cpp
index e69be6e1ec6da082fa081dca1df2e85d39e1b9c3..d10dc274af7484b3aa8bfb4785e19e15b25eb3b2 100644 (file)
 #include "gr.h"
 
 #define ION_HEAP_EXYNOS_CONTIG_MASK     (1 << 4)
-#define ION_EXYNOS_VIDEO_MASK           (1 << 29)
+#define ION_EXYNOS_FIMD_VIDEO_MASK  (1 << 28)
+#define ION_EXYNOS_MFC_OUTPUT_MASK  (1 << 26)
+#define ION_EXYNOS_MFC_INPUT_MASK   (1 << 25)
+#define MB_1 (1024*1024)
+
 
 /*****************************************************************************/
 
@@ -127,7 +131,7 @@ static unsigned int _select_heap(int usage)
 static int gralloc_alloc_rgb(int ionfd, int w, int h, int format, int usage,
                              unsigned int ion_flags, private_handle_t **hnd, int *stride)
 {
-    size_t size, bpr;
+    size_t size, bpr, alignment = 0;
     int bpp = 0, vstride, fd, err;
     unsigned int heap_mask = _select_heap(usage);
 
@@ -147,21 +151,31 @@ static int gralloc_alloc_rgb(int ionfd, int w, int h, int format, int usage,
             bpp = 2;
             break;
         case HAL_PIXEL_FORMAT_BLOB:
-            bpp = 1;
+            *stride = w;
+            vstride = h;
+            size = w * h;
             break;
         default:
             return -EINVAL;
     }
-    bpr = ALIGN(w*bpp, 16);
-    vstride = ALIGN(h, 16);
-    if (vstride == h)
-        size = bpr * (vstride + 1);
-    else
-        size = bpr * vstride;
-    *stride = bpr / bpp;
-    size = ALIGN(size, PAGE_SIZE);
 
-    err = ion_alloc_fd(ionfd, size, 0, heap_mask, ion_flags,
+    if (format != HAL_PIXEL_FORMAT_BLOB) {
+        bpr = ALIGN(w*bpp, 16);
+        vstride = ALIGN(h, 16);
+        if (vstride < h + 2)
+            size = bpr * (h + 2);
+        else
+            size = bpr * vstride;
+        *stride = bpr / bpp;
+        size = ALIGN(size, PAGE_SIZE);
+    }
+
+    if (usage & GRALLOC_USAGE_PROTECTED) {
+        alignment = MB_1;
+        ion_flags |= ION_EXYNOS_FIMD_VIDEO_MASK;
+    }
+
+    err = ion_alloc_fd(ionfd, size, alignment, heap_mask, ion_flags,
                        &fd);
     *hnd = new private_handle_t(fd, size, usage, w, h, format, *stride,
                                 vstride);
@@ -222,6 +236,7 @@ static int gralloc_alloc_yuv(int ionfd, int w, int h, int format,
     switch (format) {
         case HAL_PIXEL_FORMAT_EXYNOS_YV12:
             {
+                *stride = ALIGN(w, 32);
                 luma_vstride = ALIGN(h, 16);
                 luma_size = luma_vstride * *stride;
                 chroma_size = (luma_vstride / 2) * ALIGN(*stride / 2, 16);
@@ -256,6 +271,9 @@ static int gralloc_alloc_yuv(int ionfd, int w, int h, int format,
             return -EINVAL;
     }
 
+    if (usage & GRALLOC_USAGE_PROTECTED)
+       ion_flags |= ION_EXYNOS_MFC_OUTPUT_MASK;
+
     err = ion_alloc_fd(ionfd, luma_size, 0, heap_mask, ion_flags, &fd);
     if (err)
         return err;
@@ -300,9 +318,7 @@ static int gralloc_alloc(alloc_device_t* dev,
         return -EINVAL;
 
     if( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
-        ion_flags = ION_FLAG_CACHED;
-    if (usage & GRALLOC_USAGE_PROTECTED)
-        ion_flags |= ION_EXYNOS_VIDEO_MASK;
+        ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
 
     private_module_t* m = reinterpret_cast<private_module_t*>
         (dev->common.module);
@@ -317,8 +333,6 @@ static int gralloc_alloc(alloc_device_t* dev,
     if (err)
         return err;
 
-    err = grallocMap(module, hnd);
-
     if (err != 0)
         goto err;
 
@@ -345,8 +359,9 @@ static int gralloc_free(alloc_device_t* dev,
     private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
     gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
                                                                    dev->common.module);
+    if (hnd->base)
+        grallocUnmap(module, const_cast<private_handle_t*>(hnd));
 
-    grallocUnmap(module, const_cast<private_handle_t*>(hnd));
     close(hnd->fd);
     if (hnd->fd1 >= 0)
         close(hnd->fd1);