Merge "gralloc: Optimize ION cache clean and invalidate calls"
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
08574507b5
@@ -76,16 +76,6 @@ static bool canFallback(int usage, bool triedSystem)
|
||||
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()
|
||||
{
|
||||
@@ -664,3 +654,14 @@ void free_buffer(private_handle_t *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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
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 {
|
||||
|
||||
@@ -180,6 +180,7 @@ struct private_handle_t : public native_handle {
|
||||
PRIV_FLAGS_USES_ION = 0x00000008,
|
||||
PRIV_FLAGS_USES_ASHMEM = 0x00000010,
|
||||
PRIV_FLAGS_NEEDS_FLUSH = 0x00000020,
|
||||
// Uncached memory or no CPU writers
|
||||
PRIV_FLAGS_DO_NOT_FLUSH = 0x00000040,
|
||||
PRIV_FLAGS_SW_LOCK = 0x00000080,
|
||||
PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
|
||||
|
||||
@@ -229,21 +229,37 @@ static int gralloc_map_and_invalidate (gralloc_module_t const* module,
|
||||
err = gralloc_map(module, handle);
|
||||
pthread_mutex_unlock(lock);
|
||||
}
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
|
||||
//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 (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION and
|
||||
not useUncached(usage)) {
|
||||
bool nonCPUWriters = usage & (
|
||||
GRALLOC_USAGE_HW_RENDER |
|
||||
GRALLOC_USAGE_HW_FB |
|
||||
GRALLOC_USAGE_HW_VIDEO_ENCODER |
|
||||
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) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
if(useUncached(usage))
|
||||
hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -283,24 +299,17 @@ int gralloc_unlock(gralloc_module_t const* module,
|
||||
int err = 0;
|
||||
private_handle_t* hnd = (private_handle_t*)handle;
|
||||
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
|
||||
IMemAlloc* memalloc = getAllocator(hnd->flags);
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
|
||||
err = memalloc->clean_buffer((void*)hnd->base,
|
||||
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);
|
||||
}
|
||||
IMemAlloc* memalloc = getAllocator(hnd->flags);
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
|
||||
err = memalloc->clean_buffer((void*)hnd->base,
|
||||
hnd->size, hnd->offset, hnd->fd,
|
||||
CACHE_CLEAN);
|
||||
hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
|
||||
}
|
||||
|
||||
if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH)
|
||||
hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user