Merge "display: Use cache invalidate and clean correctly"

This commit is contained in:
Linux Build Service Account
2013-03-27 14:34:49 -07:00
committed by Gerrit - the friendly Code Review server
5 changed files with 50 additions and 23 deletions

View File

@@ -1259,10 +1259,11 @@ static int stretch_copybit_internal(
return status; return status;
} }
// Flush the cache // Clean the cache
IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags); IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size, 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__); ALOGE("%s: clean_buffer failed", __FUNCTION__);
delete_handle(dst_hnd); delete_handle(dst_hnd);
delete_handle(src_hnd); delete_handle(src_hnd);
@@ -1343,10 +1344,11 @@ static int stretch_copybit_internal(
unmap_gpuaddr(ctx, mapped_src_idx); unmap_gpuaddr(ctx, mapped_src_idx);
return status; return status;
} }
// Invalidate the cache. // Clean the cache.
IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags); IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size, 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(dst_hnd);
delete_handle(src_hnd); delete_handle(src_hnd);

View File

@@ -145,7 +145,8 @@ int IonAlloc::alloc_buffer(alloc_data& data)
} }
memset(base, 0, ionAllocData.len); memset(base, 0, ionAllocData.len);
// Clean cache after memset // 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; data.base = base;
@@ -209,7 +210,7 @@ int IonAlloc::unmap_buffer(void *base, size_t size, int offset)
return err; 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_flush_data flush_data;
struct ion_fd_data fd_data; struct ion_fd_data fd_data;
@@ -237,7 +238,18 @@ int IonAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
#ifdef NEW_ION_API #ifdef NEW_ION_API
struct ion_custom_data d; struct ion_custom_data d;
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.cmd = ION_IOC_CLEAN_INV_CACHES;
}
d.arg = (unsigned long int)&flush_data; d.arg = (unsigned long int)&flush_data;
if(ioctl(mIonFd, ION_IOC_CUSTOM, &d)) { if(ioctl(mIonFd, ION_IOC_CUSTOM, &d)) {

View File

@@ -51,7 +51,7 @@ class IonAlloc : public IMemAlloc {
int offset); int offset);
virtual int clean_buffer(void*base, size_t size, virtual int clean_buffer(void*base, size_t size,
int offset, int fd); int offset, int fd, int op);
IonAlloc() { mIonFd = FD_INIT; } IonAlloc() { mIonFd = FD_INIT; }

View File

@@ -222,12 +222,19 @@ int gralloc_lock(gralloc_module_t const* module,
pthread_mutex_unlock(lock); pthread_mutex_unlock(lock);
} }
*vaddr = (void*)hnd->base; *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) && if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) &&
!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
// Mark the buffer to be flushed after cpu read/write // Mark the buffer to be flushed after cpu read/write
hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
} }
} else {
hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
} }
return err; return err;
} }
@@ -237,26 +244,26 @@ int gralloc_unlock(gralloc_module_t const* module,
{ {
if (private_handle_t::validate(handle) < 0) if (private_handle_t::validate(handle) < 0)
return -EINVAL; return -EINVAL;
int err = 0;
private_handle_t* hnd = (private_handle_t*)handle; private_handle_t* hnd = (private_handle_t*)handle;
IMemAlloc* memalloc = getAllocator(hnd->flags);
if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
int err;
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
err = memalloc->clean_buffer((void*)hnd->base, err = memalloc->clean_buffer((void*)hnd->base,
hnd->size, hnd->offset, hnd->fd); hnd->size, hnd->offset, hnd->fd,
ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n", CACHE_CLEAN_AND_INVALIDATE);
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->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 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;
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -34,6 +34,12 @@
namespace gralloc { namespace gralloc {
enum {
CACHE_CLEAN = 0x1,
CACHE_INVALIDATE,
CACHE_CLEAN_AND_INVALIDATE,
};
struct alloc_data { struct alloc_data {
void *base; void *base;
int fd; int fd;
@@ -68,7 +74,7 @@ class IMemAlloc {
// Clean and invalidate // Clean and invalidate
virtual int clean_buffer(void *base, size_t size, virtual int clean_buffer(void *base, size_t size,
int offset, int fd) = 0; int offset, int fd, int op) = 0;
// Destructor // Destructor
virtual ~IMemAlloc() {}; virtual ~IMemAlloc() {};