display: Use cache invalidate and clean correctly

Make sure cache is invalidated before reading in software and
cleaned after writing in software.

Change-Id: I91c471c47a5f1ff11f9960f08091a17ffe575534
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index fa63b4c..f8b75f7 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -1259,10 +1259,11 @@
             return status;
         }
 
-        // Flush the cache
+        // Clean the cache
         IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
         if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
-                                   src_hnd->offset, src_hnd->fd)) {
+                                   src_hnd->offset, src_hnd->fd,
+                                   gralloc::CACHE_CLEAN)) {
             ALOGE("%s: clean_buffer failed", __FUNCTION__);
             delete_handle(dst_hnd);
             delete_handle(src_hnd);
@@ -1349,10 +1350,11 @@
             unmap_gpuaddr(ctx, mapped_src_idx);
             return status;
         }
-        // Invalidate the cache.
+        // Clean the cache.
         IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
         memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
-                               dst_hnd->offset, dst_hnd->fd);
+                               dst_hnd->offset, dst_hnd->fd,
+                               gralloc::CACHE_CLEAN);
     }
     delete_handle(dst_hnd);
     delete_handle(src_hnd);
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
index 8480f98..83e62e7 100644
--- a/libgralloc/ionalloc.cpp
+++ b/libgralloc/ionalloc.cpp
@@ -145,7 +145,8 @@
         }
         memset(base, 0, ionAllocData.len);
         // Clean cache after memset
-        clean_buffer(base, data.size, data.offset, fd_data.fd);
+        clean_buffer(base, data.size, data.offset, fd_data.fd,
+                     CACHE_CLEAN_AND_INVALIDATE);
     }
 
     data.base = base;
@@ -209,7 +210,7 @@
     return err;
 
 }
-int IonAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
+int IonAlloc::clean_buffer(void *base, size_t size, int offset, int fd, int op)
 {
     struct ion_flush_data flush_data;
     struct ion_fd_data fd_data;
@@ -237,7 +238,18 @@
 
 #ifdef NEW_ION_API
     struct ion_custom_data d;
-    d.cmd = ION_IOC_CLEAN_INV_CACHES;
+    switch(op) {
+    case CACHE_CLEAN:
+        d.cmd = ION_IOC_CLEAN_CACHES;
+        break;
+    case CACHE_INVALIDATE:
+            d.cmd = ION_IOC_INV_CACHES;
+        break;
+    case CACHE_CLEAN_AND_INVALIDATE:
+    default:
+        d.cmd = ION_IOC_CLEAN_INV_CACHES;
+    }
+
     d.arg = (unsigned long int)&flush_data;
 
     if(ioctl(mIonFd, ION_IOC_CUSTOM, &d)) {
diff --git a/libgralloc/ionalloc.h b/libgralloc/ionalloc.h
index 7a11a34..174f44b 100644
--- a/libgralloc/ionalloc.h
+++ b/libgralloc/ionalloc.h
@@ -51,7 +51,7 @@
                              int offset);
 
     virtual int clean_buffer(void*base, size_t size,
-                             int offset, int fd);
+                             int offset, int fd, int op);
 
     IonAlloc() { mIonFd = FD_INIT; }
 
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 9c97aae..5a32975 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -222,12 +222,19 @@
             pthread_mutex_unlock(lock);
         }
         *vaddr = (void*)hnd->base;
-
+        //Invalidate if reading in software. No need to do this for the metadata
+        //buffer as it is only read/written in software.
+        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
+        err = memalloc->clean_buffer((void*)hnd->base,
+                                     hnd->size, hnd->offset, hnd->fd,
+                                     CACHE_INVALIDATE);
         if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) &&
             !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
             // Mark the buffer to be flushed after cpu read/write
             hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
         }
+    } else {
+        hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
     }
     return err;
 }
@@ -237,26 +244,26 @@
 {
     if (private_handle_t::validate(handle) < 0)
         return -EINVAL;
-
+    int err = 0;
     private_handle_t* hnd = (private_handle_t*)handle;
+    IMemAlloc* memalloc = getAllocator(hnd->flags);
 
     if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
-        int err;
-        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
         err = memalloc->clean_buffer((void*)hnd->base,
-                                     hnd->size, hnd->offset, hnd->fd);
-        ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n",
-                 hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno));
-        unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
-        err = memalloc->clean_buffer((void*)hnd->base_metadata, size,
-                hnd->offset_metadata, hnd->fd_metadata);
-        ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%lu, "
-                "flags = 0x%x) err=%s\n", hnd, hnd->offset_metadata, size,
-                hnd->flags, strerror(errno));
+                                     hnd->size, hnd->offset, hnd->fd,
+                                     CACHE_CLEAN_AND_INVALIDATE);
         hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+    } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
+        hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
+    } else {
+        //Probably a round about way to do this, but this avoids adding new
+        //flags
+        err = memalloc->clean_buffer((void*)hnd->base,
+                                     hnd->size, hnd->offset, hnd->fd,
+                                     CACHE_INVALIDATE);
     }
 
-    return 0;
+    return err;
 }
 
 /*****************************************************************************/
diff --git a/libgralloc/memalloc.h b/libgralloc/memalloc.h
index 73ac652..664bfa2 100644
--- a/libgralloc/memalloc.h
+++ b/libgralloc/memalloc.h
@@ -34,6 +34,12 @@
 
 namespace gralloc {
 
+enum {
+    CACHE_CLEAN = 0x1,
+    CACHE_INVALIDATE,
+    CACHE_CLEAN_AND_INVALIDATE,
+};
+
 struct alloc_data {
     void           *base;
     int            fd;
@@ -68,7 +74,7 @@
 
     // Clean and invalidate
     virtual int clean_buffer(void *base, size_t size,
-                             int offset, int fd) = 0;
+                             int offset, int fd, int op) = 0;
 
     // Destructor
     virtual ~IMemAlloc() {};