Merge "gralloc: Optimize ION cache clean and invalidate calls"

This commit is contained in:
Linux Build Service Account
2014-09-27 10:09:59 -07:00
committed by Gerrit - the friendly Code Review server
4 changed files with 51 additions and 36 deletions

View File

@@ -76,16 +76,6 @@ static bool canFallback(int usage, bool triedSystem)
return true; return true;
} }
static bool useUncached(int usage)
{
if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
return true;
if(((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY)
||((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY))
return true;
return false;
}
//-------------- AdrenoMemInfo-----------------------// //-------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo::AdrenoMemInfo() AdrenoMemInfo::AdrenoMemInfo()
{ {
@@ -664,3 +654,14 @@ void free_buffer(private_handle_t *hnd)
delete hnd; delete hnd;
} }
bool useUncached(const int& usage) {
if(usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
return true;
if(not (usage & (GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_SW_READ_OFTEN)))
return true;
return false;
}

View File

@@ -71,6 +71,10 @@ int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage);
void free_buffer(private_handle_t *hnd); void free_buffer(private_handle_t *hnd);
int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr); int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr);
// Use uncached for all scenarios except when the CPU needs to read or write
// often
bool useUncached(const int& usage);
/*****************************************************************************/ /*****************************************************************************/
class Locker { class Locker {

View File

@@ -180,6 +180,7 @@ struct private_handle_t : public native_handle {
PRIV_FLAGS_USES_ION = 0x00000008, PRIV_FLAGS_USES_ION = 0x00000008,
PRIV_FLAGS_USES_ASHMEM = 0x00000010, PRIV_FLAGS_USES_ASHMEM = 0x00000010,
PRIV_FLAGS_NEEDS_FLUSH = 0x00000020, PRIV_FLAGS_NEEDS_FLUSH = 0x00000020,
// Uncached memory or no CPU writers
PRIV_FLAGS_DO_NOT_FLUSH = 0x00000040, PRIV_FLAGS_DO_NOT_FLUSH = 0x00000040,
PRIV_FLAGS_SW_LOCK = 0x00000080, PRIV_FLAGS_SW_LOCK = 0x00000080,
PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100, PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,

View File

@@ -229,21 +229,37 @@ static int gralloc_map_and_invalidate (gralloc_module_t const* module,
err = gralloc_map(module, handle); err = gralloc_map(module, handle);
pthread_mutex_unlock(lock); pthread_mutex_unlock(lock);
} }
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION and
//Invalidate if reading in software. No need to do this for the not useUncached(usage)) {
//metadata buffer as it is only read/written in software. bool nonCPUWriters = usage & (
IMemAlloc* memalloc = getAllocator(hnd->flags) ; GRALLOC_USAGE_HW_RENDER |
err = memalloc->clean_buffer((void*)hnd->base, GRALLOC_USAGE_HW_FB |
hnd->size, hnd->offset, hnd->fd, GRALLOC_USAGE_HW_VIDEO_ENCODER |
CACHE_INVALIDATE); GRALLOC_USAGE_HW_CAMERA_WRITE);
//Invalidate if CPU reads in software and there are non-CPU
//writers. No need to do this for the metadata buffer as it is
//only read/written in software.
//Corner case: If we reach here with a READ_RARELY, then there must
//be a WRITE_OFTEN that caused caching to be used.
if ((usage & GRALLOC_USAGE_SW_READ_MASK) and nonCPUWriters) {
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
err = memalloc->clean_buffer((void*)hnd->base,
hnd->size, hnd->offset, hnd->fd,
CACHE_INVALIDATE);
}
//Mark the buffer to be flushed after CPU write.
//Corner case: If we reach here with a WRITE_RARELY, then there
//must be a READ_OFTEN that caused caching to be used.
if (usage & GRALLOC_USAGE_SW_WRITE_MASK) { if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
// 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;
} }
if(useUncached(usage))
hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
return err; return err;
} }
@@ -283,24 +299,17 @@ int gralloc_unlock(gralloc_module_t const* module,
int err = 0; int err = 0;
private_handle_t* hnd = (private_handle_t*)handle; private_handle_t* hnd = (private_handle_t*)handle;
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { IMemAlloc* memalloc = getAllocator(hnd->flags);
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) { 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, CACHE_CLEAN);
CACHE_CLEAN_AND_INVALIDATE); 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);
}
} }
if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH)
hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
return err; return err;
} }