bring back pmem/ashmem allocators

o removed RefBase usages
o ifdef for TARGET_USES_ION

Change-Id: Ief331f4c847b86be0e37d24983097af1f53234a2
This commit is contained in:
Andrew Sutherland 2012-08-02 21:38:40 -05:00
parent becfd45151
commit e25f40c946
17 changed files with 1310 additions and 11 deletions

View File

@ -16,6 +16,9 @@ common_libs := liblog libutils libcutils libhardware
#Common C flags
common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
ifeq ($(TARGET_USES_ION),true)
common_flags += -DUSE_ION
endif
ifeq ($(ARCH_ARM_HAVE_NEON),true)
common_flags += -D__ARM_HAVE_NEON
endif

View File

@ -426,7 +426,8 @@ static int stretch_copybit(
}
if(src->format == HAL_PIXEL_FORMAT_YV12) {
int usage = GRALLOC_USAGE_PRIVATE_MM_HEAP;
int usage = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
GRALLOC_USAGE_PRIVATE_MM_HEAP;
if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
src->format, usage)){
if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){

View File

@ -932,7 +932,7 @@ static int get_temp_buffer(const bufferInfo& info, alloc_data& data)
int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
if (sAlloc == 0) {
sAlloc = gralloc::IAllocController::getInstance();
sAlloc = gralloc::IAllocController::getInstance(false);
}
if (sAlloc == 0) {

View File

@ -35,5 +35,12 @@ LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes)
LOCAL_SHARED_LIBRARIES := $(common_libs) libgenlock
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"memalloc\"
LOCAL_SRC_FILES := ionalloc.cpp alloc_controller.cpp
LOCAL_SRC_FILES := alloc_controller.cpp
ifeq ($(TARGET_USES_ION),true)
LOCAL_SRC_FILES += ionalloc.cpp
else
LOCAL_SRC_FILES += pmemalloc.cpp \
ashmemalloc.cpp \
pmem_bestfit_alloc.cpp
endif
include $(BUILD_SHARED_LIBRARY)

View File

@ -32,7 +32,12 @@
#include "gralloc_priv.h"
#include "alloc_controller.h"
#include "memalloc.h"
#ifdef USE_ION
#include "ionalloc.h"
#else
#include "pmemalloc.h"
#include "ashmemalloc.h"
#endif
#include "gr.h"
#include "comptype.h"
@ -75,15 +80,23 @@ static bool useUncached(int usage)
}
IAllocController* IAllocController::sController = NULL;
IAllocController* IAllocController::getInstance(void)
IAllocController* IAllocController::getInstance(bool useMasterHeap)
{
if(sController == NULL) {
#ifdef USE_ION
sController = new IonController();
#else
if(useMasterHeap)
sController = new PmemAshmemController();
else
sController = new PmemKernelController();
#endif
}
return sController;
}
#ifdef USE_ION
//-------------- IonController-----------------------//
IonController::IonController()
{
@ -161,6 +174,148 @@ IMemAlloc* IonController::getAllocator(int flags)
return memalloc;
}
#else
//-------------- PmemKernelController-----------------------//
PmemKernelController::PmemKernelController()
{
mPmemAdspAlloc = new PmemKernelAlloc(DEVICE_PMEM_ADSP);
// XXX: Right now, there is no need to maintain an instance
// of the SMI allocator as we need it only in a few cases
}
PmemKernelController::~PmemKernelController()
{
}
int PmemKernelController::allocate(alloc_data& data, int usage)
{
int ret = 0;
bool adspFallback = false;
if (!(usage & GRALLOC_USAGE_PRIVATE_SMI_HEAP))
adspFallback = true;
// Try SMI first
if ((usage & GRALLOC_USAGE_PRIVATE_SMI_HEAP) ||
(usage & GRALLOC_USAGE_EXTERNAL_DISP) ||
(usage & GRALLOC_USAGE_PROTECTED))
{
int tempFd = open(DEVICE_PMEM_SMIPOOL, O_RDWR, 0);
if(tempFd > 0) {
close(tempFd);
IMemAlloc* memalloc;
memalloc = new PmemKernelAlloc(DEVICE_PMEM_SMIPOOL);
ret = memalloc->alloc_buffer(data);
if(ret >= 0)
return ret;
else {
if(adspFallback)
ALOGW("Allocation from SMI failed, trying ADSP");
}
}
}
if ((usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) || adspFallback) {
ret = mPmemAdspAlloc->alloc_buffer(data);
}
return ret;
}
IMemAlloc* PmemKernelController::getAllocator(int flags)
{
IMemAlloc* memalloc;
if (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP)
memalloc = mPmemAdspAlloc;
else {
ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
memalloc = NULL;
}
return memalloc;
}
//-------------- PmemAshmmemController-----------------------//
PmemAshmemController::PmemAshmemController()
{
mPmemUserspaceAlloc = new PmemUserspaceAlloc();
mAshmemAlloc = new AshmemAlloc();
mPmemKernelCtrl = new PmemKernelController();
}
PmemAshmemController::~PmemAshmemController()
{
}
int PmemAshmemController::allocate(alloc_data& data, int usage)
{
int ret = 0;
data.allocType = 0;
// Make buffers cacheable by default
data.uncached = false;
// Override if we explicitly need uncached buffers
if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
data.uncached = true;
// If ADSP or SMI is requested use the kernel controller
if(usage & (GRALLOC_USAGE_PRIVATE_ADSP_HEAP|
GRALLOC_USAGE_PRIVATE_SMI_HEAP)) {
ret = mPmemKernelCtrl->allocate(data, usage);
if(ret < 0)
ALOGE("%s: Failed to allocate ADSP/SMI memory", __func__);
else
data.allocType = private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
return ret;
}
if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) {
ret = mAshmemAlloc->alloc_buffer(data);
if(ret >= 0) {
data.allocType = private_handle_t::PRIV_FLAGS_USES_ASHMEM;
data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM;
}
return ret;
}
// if no memory specific flags are set,
// default to EBI heap, so that bypass
// can work. We can fall back to system
// heap if we run out.
ret = mPmemUserspaceAlloc->alloc_buffer(data);
// Fallback
if(ret >= 0 ) {
data.allocType = private_handle_t::PRIV_FLAGS_USES_PMEM;
} else if(ret < 0 && canFallback(usage, false)) {
ALOGW("Falling back to ashmem");
ret = mAshmemAlloc->alloc_buffer(data);
if(ret >= 0) {
data.allocType = private_handle_t::PRIV_FLAGS_USES_ASHMEM;
data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM;
}
}
return ret;
}
IMemAlloc* PmemAshmemController::getAllocator(int flags)
{
IMemAlloc* memalloc;
if (flags & private_handle_t::PRIV_FLAGS_USES_PMEM)
memalloc = mPmemUserspaceAlloc;
else if (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP)
memalloc = mPmemKernelCtrl->getAllocator(flags);
else if (flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
memalloc = mAshmemAlloc;
else {
ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
memalloc = NULL;
}
return memalloc;
}
#endif
size_t getBufferSizeAndDimensions(int width, int height, int format,
int& alignedw, int &alignedh)
@ -243,7 +398,7 @@ int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
alloc_data data;
int alignedw, alignedh;
gralloc::IAllocController* sAlloc =
gralloc::IAllocController::getInstance();
gralloc::IAllocController::getInstance(false);
data.base = 0;
data.fd = -1;
data.offset = 0;
@ -271,7 +426,7 @@ int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
void free_buffer(private_handle_t *hnd)
{
gralloc::IAllocController* sAlloc =
gralloc::IAllocController::getInstance();
gralloc::IAllocController::getInstance(false);
if (hnd && hnd->fd > 0) {
IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);

View File

@ -47,13 +47,14 @@ class IAllocController {
virtual ~IAllocController() {};
static IAllocController* getInstance(void);
static IAllocController* getInstance(bool useMasterHeap);
private:
static IAllocController* sController;
};
#ifdef USE_ION
class IonController : public IAllocController {
public:
@ -67,5 +68,43 @@ class IonController : public IAllocController {
IonAlloc* mIonAlloc;
};
#else
class PmemKernelController : public IAllocController {
public:
virtual int allocate(alloc_data& data, int usage);
virtual IMemAlloc* getAllocator(int flags);
PmemKernelController ();
~PmemKernelController ();
private:
IMemAlloc* mPmemAdspAlloc;
};
// Main pmem controller - this should only
// be used within gralloc
class PmemAshmemController : public IAllocController {
public:
virtual int allocate(alloc_data& data, int usage);
virtual IMemAlloc* getAllocator(int flags);
PmemAshmemController();
~PmemAshmemController();
private:
IMemAlloc* mPmemUserspaceAlloc;
IMemAlloc* mAshmemAlloc;
IAllocController* mPmemKernelCtrl;
};
#endif
} //end namespace gralloc
#endif // GRALLOC_ALLOCCONTROLLER_H

138
libgralloc/ashmemalloc.cpp Normal file
View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <cutils/log.h>
#include <linux/ashmem.h>
#include <cutils/ashmem.h>
#include <errno.h>
#include "ashmemalloc.h"
using gralloc::AshmemAlloc;
int AshmemAlloc::alloc_buffer(alloc_data& data)
{
int err = 0;
int fd = -1;
void* base = 0;
int offset = 0;
char name[ASHMEM_NAME_LEN];
snprintf(name, ASHMEM_NAME_LEN, "gralloc-buffer-%x", data.pHandle);
int prot = PROT_READ | PROT_WRITE;
fd = ashmem_create_region(name, data.size);
if (fd < 0) {
ALOGE("couldn't create ashmem (%s)", strerror(errno));
err = -errno;
} else {
if (ashmem_set_prot_region(fd, prot) < 0) {
ALOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
fd, prot, strerror(errno));
close(fd);
err = -errno;
} else {
base = mmap(0, data.size, prot, MAP_SHARED|MAP_POPULATE|MAP_LOCKED, fd, 0);
if (base == MAP_FAILED) {
ALOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
fd, data.size, prot, strerror(errno));
close(fd);
err = -errno;
} else {
memset((char*)base + offset, 0, data.size);
}
}
}
if(err == 0) {
data.fd = fd;
data.base = base;
data.offset = offset;
clean_buffer(base, data.size, offset, fd);
ALOGD("ashmem: Allocated buffer base:%p size:%d fd:%d",
base, data.size, fd);
}
return err;
}
int AshmemAlloc::free_buffer(void* base, size_t size, int offset, int fd)
{
ALOGD("ashmem: Freeing buffer base:%p size:%d fd:%d",
base, size, fd);
int err = 0;
if(!base) {
ALOGE("Invalid free");
return -EINVAL;
}
err = unmap_buffer(base, size, offset);
close(fd);
return err;
}
int AshmemAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
{
int err = 0;
void *base = 0;
base = mmap(0, size, PROT_READ| PROT_WRITE,
MAP_SHARED|MAP_POPULATE, fd, 0);
*pBase = base;
if(base == MAP_FAILED) {
ALOGE("ashmem: Failed to map memory in the client: %s",
strerror(errno));
err = -errno;
} else {
ALOGD("ashmem: Mapped buffer base:%p size:%d fd:%d",
base, size, fd);
}
return err;
}
int AshmemAlloc::unmap_buffer(void *base, size_t size, int offset)
{
ALOGD("ashmem: Unmapping buffer base: %p size: %d", base, size);
int err = munmap(base, size);
if(err) {
ALOGE("ashmem: Failed to unmap memory at %p: %s",
base, strerror(errno));
}
return err;
}
int AshmemAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
{
int err = 0;
if (ioctl(fd, ASHMEM_CACHE_FLUSH_RANGE, NULL)) {
ALOGE("ashmem: ASHMEM_CACHE_FLUSH_RANGE failed fd = %d", fd);
}
return err;
}

56
libgralloc/ashmemalloc.h Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GRALLOC_ASHMEMALLOC_H
#define GRALLOC_ASHMEMALLOC_H
#include "memalloc.h"
#include <linux/ion.h>
namespace gralloc {
class AshmemAlloc : public IMemAlloc {
public:
virtual int alloc_buffer(alloc_data& data);
virtual int free_buffer(void *base, size_t size,
int offset, int fd);
virtual int map_buffer(void **pBase, size_t size,
int offset, int fd);
virtual int unmap_buffer(void *base, size_t size,
int offset);
virtual int clean_buffer(void*base, size_t size,
int offset, int fd);
};
}
#endif /* GRALLOC_ASHMEMALLOC_H */

View File

@ -100,7 +100,7 @@ int gralloc_device_open(const hw_module_t* module, const char* name,
const private_module_t* m = reinterpret_cast<const private_module_t*>(
module);
gpu_context_t *dev;
IAllocController* alloc_ctrl = IAllocController::getInstance();
IAllocController* alloc_ctrl = IAllocController::getInstance(true);
dev = new gpu_context_t(m, alloc_ctrl);
*device = &dev->common;
status = 0;

View File

@ -34,6 +34,7 @@ enum {
/* gralloc usage bits indicating the type
* of allocation that should be used */
#ifdef USE_ION
/* SYSTEM heap comes from kernel vmalloc,
* can never be uncached, is not secured*/
GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP = GRALLOC_USAGE_PRIVATE_0,
@ -83,6 +84,65 @@ enum {
*/
GRALLOC_USAGE_PRIVATE_ADSP_HEAP = 0x0,
GRALLOC_USAGE_PRIVATE_SMI_HEAP = 0x0,
#else
/* ADSP heap is deprecated, use only if using pmem */
GRALLOC_USAGE_PRIVATE_ADSP_HEAP = GRALLOC_USAGE_PRIVATE_0,
/* SF heap is used for application buffers, is not secured */
GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP = GRALLOC_USAGE_PRIVATE_1,
/* SMI heap is deprecated, use only if using pmem */
GRALLOC_USAGE_PRIVATE_SMI_HEAP = GRALLOC_USAGE_PRIVATE_2,
/* SYSTEM heap comes from kernel vmalloc,
* can never be uncached, is not secured*/
GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP = GRALLOC_USAGE_PRIVATE_3,
/* IOMMU heap comes from manually allocated pages,
* can be cached/uncached, is not secured */
GRALLOC_USAGE_PRIVATE_IOMMU_HEAP = 0x01000000,
/* MM heap is a carveout heap for video, can be secured*/
GRALLOC_USAGE_PRIVATE_MM_HEAP = 0x02000000,
/* WRITEBACK heap is a carveout heap for writeback, can be secured*/
GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP = 0x04000000,
/* CAMERA heap is a carveout heap for camera, is not secured*/
GRALLOC_USAGE_PRIVATE_CAMERA_HEAP = 0x08000000,
/* Set this for allocating uncached memory (using O_DSYNC)
* cannot be used with noncontiguous heaps */
GRALLOC_USAGE_PRIVATE_UNCACHED = 0x00100000,
/* This flag needs to be set when using a non-contiguous heap from ION.
* If not set, the system heap is assumed to be coming from ashmem
*/
GRALLOC_USAGE_PRIVATE_ION = 0x00200000,
/* This flag can be set to disable genlock synchronization
* for the gralloc buffer. If this flag is set the caller
* is required to perform explicit synchronization.
* WARNING - flag is outside the standard PRIVATE region
* and may need to be moved if the gralloc API changes
*/
GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED = 0X00400000,
/* Set this flag when you need to avoid mapping the memory in userspace */
GRALLOC_USAGE_PRIVATE_DO_NOT_MAP = 0X00800000,
/* Buffer content should be displayed on an external display only */
GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY = 0x00010000,
/* Only this buffer content should be displayed on external, even if
* other EXTERNAL_ONLY buffers are available. Used during suspend.
*/
GRALLOC_USAGE_PRIVATE_EXTERNAL_BLOCK = 0x00020000,
/* Use this flag to request content protected buffers. Please note
* that this flag is different from the GRALLOC_USAGE_PROTECTED flag
* which can be used for buffers that are not secured for DRM
* but still need to be protected from screen captures
* 0x00040000 is reserved and these values are subject to change.
*/
GRALLOC_USAGE_PRIVATE_CP_BUFFER = 0x00080000,
/* Close Caption displayed on an external display only */
GRALLOC_USAGE_PRIVATE_EXTERNAL_CC = 0x000F0000,
#endif
};
enum {
@ -91,11 +151,25 @@ enum {
GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 0x080000001,
};
#ifdef USE_ION
#define GRALLOC_HEAP_MASK (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP |\
GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |\
GRALLOC_USAGE_PRIVATE_MM_HEAP |\
GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
#else
#define GRALLOC_HEAP_MASK (GRALLOC_USAGE_PRIVATE_ADSP_HEAP |\
GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
GRALLOC_USAGE_PRIVATE_SMI_HEAP |\
GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP |\
GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |\
GRALLOC_USAGE_PRIVATE_MM_HEAP |\
GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP |\
GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
#define DEVICE_PMEM "/dev/pmem"
#define DEVICE_PMEM_ADSP "/dev/pmem_adsp"
#define DEVICE_PMEM_SMIPOOL "/dev/pmem_smipool"
#endif
/*****************************************************************************/
enum {

View File

@ -51,7 +51,7 @@ using namespace gralloc;
static IMemAlloc* getAllocator(int flags)
{
IMemAlloc* memalloc;
IAllocController* alloc_ctrl = IAllocController::getInstance();
IAllocController* alloc_ctrl = IAllocController::getInstance(true);
memalloc = alloc_ctrl->getAllocator(flags);
return memalloc;
}
@ -327,7 +327,12 @@ int gralloc_perform(struct gralloc_module_t const* module,
private_handle_t::sNumFds, private_handle_t::sNumInts);
hnd->magic = private_handle_t::sMagic;
hnd->fd = fd;
#ifdef USE_ION
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
#else
hnd->flags = private_handle_t::PRIV_FLAGS_USES_PMEM |
private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
#endif
hnd->size = size;
hnd->offset = offset;
hnd->base = intptr_t(base) + offset;

View File

@ -0,0 +1,195 @@
/*
* Copyright (C) 2009 The Android Open Source Project
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cutils/log.h>
#include "pmem_bestfit_alloc.h"
// align all the memory blocks on a cache-line boundary
const int SimpleBestFitAllocator::kMemoryAlign = 32;
SimpleBestFitAllocator::SimpleBestFitAllocator()
: mHeapSize(0)
{
}
SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
: mHeapSize(0)
{
setSize(size);
}
SimpleBestFitAllocator::~SimpleBestFitAllocator()
{
while(!mList.isEmpty()) {
delete mList.remove(mList.head());
}
}
ssize_t SimpleBestFitAllocator::setSize(size_t size)
{
Locker::Autolock _l(mLock);
if (mHeapSize != 0) return -EINVAL;
size_t pagesize = getpagesize();
mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
mList.insertHead(node);
return size;
}
size_t SimpleBestFitAllocator::size() const
{
return mHeapSize;
}
ssize_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
{
Locker::Autolock _l(mLock);
if (mHeapSize == 0) return -EINVAL;
ssize_t offset = alloc(size, flags);
return offset;
}
ssize_t SimpleBestFitAllocator::deallocate(size_t offset)
{
Locker::Autolock _l(mLock);
if (mHeapSize == 0) return -EINVAL;
chunk_t const * const freed = dealloc(offset);
if (freed) {
return 0;
}
return -ENOENT;
}
ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
{
if (size == 0) {
return 0;
}
size = (size + kMemoryAlign-1) / kMemoryAlign;
chunk_t* free_chunk = 0;
chunk_t* cur = mList.head();
size_t pagesize = getpagesize();
while (cur) {
int extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;
// best fit
if (cur->free && (cur->size >= (size+extra))) {
if ((!free_chunk) || (cur->size < free_chunk->size)) {
free_chunk = cur;
}
if (cur->size == size) {
break;
}
}
cur = cur->next;
}
if (free_chunk) {
const size_t free_size = free_chunk->size;
free_chunk->free = 0;
free_chunk->size = size;
if (free_size > size) {
int extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
if (extra) {
chunk_t* split = new chunk_t(free_chunk->start, extra);
free_chunk->start += extra;
mList.insertBefore(free_chunk, split);
}
ALOGE_IF(((free_chunk->start*kMemoryAlign)&(pagesize-1)),
"page is not aligned!!!");
const ssize_t tail_free = free_size - (size+extra);
if (tail_free > 0) {
chunk_t* split = new chunk_t(
free_chunk->start + free_chunk->size, tail_free);
mList.insertAfter(free_chunk, split);
}
}
return (free_chunk->start)*kMemoryAlign;
}
// we are out of PMEM. Print pmem stats
// check if there is any leak or fragmentation
ALOGD (" Out of PMEM. Dumping PMEM stats for debugging");
ALOGD (" ------------- PRINT PMEM STATS --------------");
cur = mList.head();
static uint32_t node_count;
static uint64_t allocated, free_space;
while (cur) {
ALOGD (" Node %d -> Start Address : %u Size %u Free info %d",\
node_count++, cur->start, cur->size, cur->free);
// if cur-> free is 1 , the node is free
// calculate the total allocated and total free stats also
if (cur->free)
free_space += cur->size;
else
allocated += cur->size;
// read next node
cur = cur->next;
}
ALOGD (" Total Allocated: %l Total Free: %l", allocated, free_space );
node_count = 0;
allocated = 0;
free_space = 0;
ALOGD ("----------------------------------------------");
return -ENOMEM;
}
SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
{
start = start / kMemoryAlign;
chunk_t* cur = mList.head();
while (cur) {
if (cur->start == start) {
LOG_FATAL_IF(cur->free,
"block at offset 0x%08lX of size 0x%08lX already freed",
cur->start*kMemoryAlign, cur->size*kMemoryAlign);
// merge freed blocks together
chunk_t* freed = cur;
cur->free = 1;
do {
chunk_t* const p = cur->prev;
chunk_t* const n = cur->next;
if (p && (p->free || !cur->size)) {
freed = p;
p->size += cur->size;
mList.remove(cur);
delete cur;
}
cur = n;
} while (cur && cur->free);
LOG_FATAL_IF(!freed->free,
"freed block at offset 0x%08lX of size 0x%08lX is not free!",
freed->start * kMemoryAlign, freed->size * kMemoryAlign);
return freed;
}
cur = cur->next;
}
return 0;
}

View File

@ -0,0 +1,129 @@
/*
* Copyright (C) 2009 The Android Open Source Project
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GRALLOC_ALLOCATOR_H_
#define GRALLOC_ALLOCATOR_H_
#include <stdint.h>
#include <sys/types.h>
#include "gr.h"
#include "pmemalloc.h"
// ----------------------------------------------------------------------------
/*
* A simple templatized doubly linked-list implementation
*/
template <typename NODE>
class LinkedList
{
NODE* mFirst;
NODE* mLast;
public:
LinkedList() : mFirst(0), mLast(0) { }
bool isEmpty() const { return mFirst == 0; }
NODE const* head() const { return mFirst; }
NODE* head() { return mFirst; }
NODE const* tail() const { return mLast; }
NODE* tail() { return mLast; }
void insertAfter(NODE* node, NODE* newNode) {
newNode->prev = node;
newNode->next = node->next;
if (node->next == 0) mLast = newNode;
else node->next->prev = newNode;
node->next = newNode;
}
void insertBefore(NODE* node, NODE* newNode) {
newNode->prev = node->prev;
newNode->next = node;
if (node->prev == 0) mFirst = newNode;
else node->prev->next = newNode;
node->prev = newNode;
}
void insertHead(NODE* newNode) {
if (mFirst == 0) {
mFirst = mLast = newNode;
newNode->prev = newNode->next = 0;
} else {
newNode->prev = 0;
newNode->next = mFirst;
mFirst->prev = newNode;
mFirst = newNode;
}
}
void insertTail(NODE* newNode) {
if (mLast == 0) {
insertHead(newNode);
} else {
newNode->prev = mLast;
newNode->next = 0;
mLast->next = newNode;
mLast = newNode;
}
}
NODE* remove(NODE* node) {
if (node->prev == 0) mFirst = node->next;
else node->prev->next = node->next;
if (node->next == 0) mLast = node->prev;
else node->next->prev = node->prev;
return node;
}
};
class SimpleBestFitAllocator : public gralloc::PmemUserspaceAlloc::Allocator
{
public:
SimpleBestFitAllocator();
SimpleBestFitAllocator(size_t size);
virtual ~SimpleBestFitAllocator();
virtual ssize_t setSize(size_t size);
virtual ssize_t allocate(size_t size, uint32_t flags = 0);
virtual ssize_t deallocate(size_t offset);
virtual size_t size() const;
private:
struct chunk_t {
chunk_t(size_t start, size_t size)
: start(start), size(size), free(1), prev(0), next(0) {
}
size_t start;
size_t size : 28;
int free : 4;
mutable chunk_t* prev;
mutable chunk_t* next;
};
ssize_t alloc(size_t size, uint32_t flags);
chunk_t* dealloc(size_t start);
static const int kMemoryAlign;
mutable Locker mLock;
LinkedList<chunk_t> mList;
size_t mHeapSize;
};
#endif /* GRALLOC_ALLOCATOR_H_ */

388
libgralloc/pmemalloc.cpp Normal file
View File

@ -0,0 +1,388 @@
/*
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//#define LOG_NDEBUG 0
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <cutils/log.h>
#include <errno.h>
#include <linux/android_pmem.h>
#include "gralloc_priv.h"
#include "pmemalloc.h"
#include "pmem_bestfit_alloc.h"
using namespace gralloc;
// Common functions between userspace
// and kernel allocators
static int getPmemTotalSize(int fd, size_t* size)
{
//XXX: 7x27
int err = 0;
pmem_region region;
if (ioctl(fd, PMEM_GET_TOTAL_SIZE, &region)) {
err = -errno;
} else {
*size = region.len;
}
return err;
}
static int getOpenFlags(bool uncached)
{
if(uncached)
return O_RDWR | O_SYNC;
else
return O_RDWR;
}
static int connectPmem(int fd, int master_fd) {
if (ioctl(fd, PMEM_CONNECT, master_fd))
return -errno;
return 0;
}
static int mapSubRegion(int fd, int offset, size_t size) {
struct pmem_region sub = { offset, size };
if (ioctl(fd, PMEM_MAP, &sub))
return -errno;
return 0;
}
static int unmapSubRegion(int fd, int offset, size_t size) {
struct pmem_region sub = { offset, size };
if (ioctl(fd, PMEM_UNMAP, &sub))
return -errno;
return 0;
}
static int alignPmem(int fd, size_t size, int align) {
struct pmem_allocation allocation;
allocation.size = size;
allocation.align = align;
if (ioctl(fd, PMEM_ALLOCATE_ALIGNED, &allocation))
return -errno;
return 0;
}
static int cleanPmem(void *base, size_t size, int offset, int fd) {
struct pmem_addr pmem_addr;
pmem_addr.vaddr = (unsigned long) base;
pmem_addr.offset = offset;
pmem_addr.length = size;
if (ioctl(fd, PMEM_CLEAN_INV_CACHES, &pmem_addr))
return -errno;
return 0;
}
//-------------- PmemUserspaceAlloc-----------------------//
PmemUserspaceAlloc::PmemUserspaceAlloc()
{
mPmemDev = DEVICE_PMEM;
mMasterFd = FD_INIT;
mAllocator = new SimpleBestFitAllocator();
pthread_mutex_init(&mLock, NULL);
}
PmemUserspaceAlloc::~PmemUserspaceAlloc()
{
}
int PmemUserspaceAlloc::init_pmem_area_locked()
{
ALOGD("%s: Opening master pmem FD", __FUNCTION__);
int err = 0;
int fd = open(mPmemDev, O_RDWR, 0);
if (fd >= 0) {
size_t size = 0;
err = getPmemTotalSize(fd, &size);
ALOGD("%s: Total pmem size: %d", __FUNCTION__, size);
if (err < 0) {
ALOGE("%s: PMEM_GET_TOTAL_SIZE failed (%d), limp mode", mPmemDev,
err);
size = 8<<20; // 8 MiB
}
mAllocator->setSize(size);
void* base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd,
0);
if (base == MAP_FAILED) {
err = -errno;
ALOGE("%s: Failed to map pmem master fd: %s", mPmemDev,
strerror(errno));
base = 0;
close(fd);
fd = -1;
} else {
mMasterFd = fd;
mMasterBase = base;
}
} else {
err = -errno;
ALOGE("%s: Failed to open pmem device: %s", mPmemDev,
strerror(errno));
}
return err;
}
int PmemUserspaceAlloc::init_pmem_area()
{
pthread_mutex_lock(&mLock);
int err = mMasterFd;
if (err == FD_INIT) {
// first time, try to initialize pmem
ALOGD("%s: Initializing pmem area", __FUNCTION__);
err = init_pmem_area_locked();
if (err) {
ALOGE("%s: failed to initialize pmem area", mPmemDev);
mMasterFd = err;
}
} else if (err < 0) {
// pmem couldn't be initialized, never use it
} else {
// pmem OK
err = 0;
}
pthread_mutex_unlock(&mLock);
return err;
}
int PmemUserspaceAlloc::alloc_buffer(alloc_data& data)
{
int err = init_pmem_area();
if (err == 0) {
void* base = mMasterBase;
size_t size = data.size;
int offset = mAllocator->allocate(size);
if (offset < 0) {
// no more pmem memory
ALOGE("%s: No more pmem available", mPmemDev);
err = -ENOMEM;
} else {
int openFlags = getOpenFlags(data.uncached);
// now create the "sub-heap"
int fd = open(mPmemDev, openFlags, 0);
err = fd < 0 ? fd : 0;
// and connect to it
if (err == 0)
err = connectPmem(fd, mMasterFd);
// and make it available to the client process
if (err == 0)
err = mapSubRegion(fd, offset, size);
if (err < 0) {
ALOGE("%s: Failed to initialize pmem sub-heap: %d", mPmemDev,
err);
close(fd);
mAllocator->deallocate(offset);
fd = -1;
} else {
ALOGV("%s: Allocated buffer base:%p size:%d offset:%d fd:%d",
mPmemDev, base, size, offset, fd);
memset((char*)base + offset, 0, size);
//Clean cache before flushing to ensure pmem is properly flushed
err = clean_buffer((void*)((intptr_t) base + offset), size, offset, fd);
if (err < 0) {
ALOGE("cleanPmem failed: (%s)", strerror(errno));
}
cacheflush(intptr_t(base) + offset, intptr_t(base) + offset + size, 0);
data.base = base;
data.offset = offset;
data.fd = fd;
}
}
}
return err;
}
int PmemUserspaceAlloc::free_buffer(void* base, size_t size, int offset, int fd)
{
ALOGV("%s: Freeing buffer base:%p size:%d offset:%d fd:%d",
mPmemDev, base, size, offset, fd);
int err = 0;
if (fd >= 0) {
int err = unmapSubRegion(fd, offset, size);
ALOGE_IF(err<0, "PMEM_UNMAP failed (%s), fd=%d, sub.offset=%u, "
"sub.size=%u", strerror(errno), fd, offset, size);
if (err == 0) {
// we can't deallocate the memory in case of UNMAP failure
// because it would give that process access to someone else's
// surfaces, which would be a security breach.
mAllocator->deallocate(offset);
}
close(fd);
}
return err;
}
int PmemUserspaceAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
{
int err = 0;
size += offset;
void *base = mmap(0, size, PROT_READ| PROT_WRITE,
MAP_SHARED, fd, 0);
*pBase = base;
if(base == MAP_FAILED) {
err = -errno;
ALOGE("%s: Failed to map buffer size:%d offset:%d fd:%d Error: %s",
mPmemDev, size, offset, fd, strerror(errno));
} else {
ALOGV("%s: Mapped buffer base:%p size:%d offset:%d fd:%d",
mPmemDev, base, size, offset, fd);
}
return err;
}
int PmemUserspaceAlloc::unmap_buffer(void *base, size_t size, int offset)
{
int err = 0;
//pmem hack
base = (void*)(intptr_t(base) - offset);
size += offset;
ALOGV("%s: Unmapping buffer base:%p size:%d offset:%d",
mPmemDev , base, size, offset);
if (munmap(base, size) < 0) {
err = -errno;
ALOGE("%s: Failed to unmap memory at %p :%s",
mPmemDev, base, strerror(errno));
}
return err;
}
int PmemUserspaceAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
{
return cleanPmem(base, size, offset, fd);
}
//-------------- PmemKernelAlloc-----------------------//
PmemKernelAlloc::PmemKernelAlloc(const char* pmemdev) :
mPmemDev(pmemdev)
{
}
PmemKernelAlloc::~PmemKernelAlloc()
{
}
int PmemKernelAlloc::alloc_buffer(alloc_data& data)
{
int err, offset = 0;
int openFlags = getOpenFlags(data.uncached);
int size = data.size;
int fd = open(mPmemDev, openFlags, 0);
if (fd < 0) {
err = -errno;
ALOGE("%s: Error opening %s", __FUNCTION__, mPmemDev);
return err;
}
if (data.align == 8192) {
// Tile format buffers need physical alignment to 8K
// Default page size does not need this ioctl
err = alignPmem(fd, size, 8192);
if (err < 0) {
ALOGE("alignPmem failed");
}
}
void* base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (base == MAP_FAILED) {
err = -errno;
ALOGE("%s: failed to map pmem fd: %s", mPmemDev,
strerror(errno));
close(fd);
return err;
}
memset(base, 0, size);
clean_buffer((void*)((intptr_t) base + offset), size, offset, fd);
data.base = base;
data.offset = 0;
data.fd = fd;
ALOGV("%s: Allocated buffer base:%p size:%d fd:%d",
mPmemDev, base, size, fd);
return 0;
}
int PmemKernelAlloc::free_buffer(void* base, size_t size, int offset, int fd)
{
ALOGV("%s: Freeing buffer base:%p size:%d fd:%d",
mPmemDev, base, size, fd);
int err = unmap_buffer(base, size, offset);
close(fd);
return err;
}
int PmemKernelAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
{
int err = 0;
void *base = mmap(0, size, PROT_READ| PROT_WRITE,
MAP_SHARED, fd, 0);
*pBase = base;
if(base == MAP_FAILED) {
err = -errno;
ALOGE("%s: Failed to map memory in the client: %s",
mPmemDev, strerror(errno));
} else {
ALOGV("%s: Mapped buffer base:%p size:%d, fd:%d",
mPmemDev, base, size, fd);
}
return err;
}
int PmemKernelAlloc::unmap_buffer(void *base, size_t size, int offset)
{
int err = 0;
if (munmap(base, size)) {
err = -errno;
ALOGW("%s: Error unmapping memory at %p: %s",
mPmemDev, base, strerror(err));
}
return err;
}
int PmemKernelAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
{
return cleanPmem(base, size, offset, fd);
}

105
libgralloc/pmemalloc.h Normal file
View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GRALLOC_PMEMALLOC_H
#define GRALLOC_PMEMALLOC_H
#include <linux/ion.h>
#include "memalloc.h"
namespace gralloc {
class PmemUserspaceAlloc : public IMemAlloc {
public:
class Allocator {
public:
virtual ~Allocator() {};
virtual ssize_t setSize(size_t size) = 0;
virtual size_t size() const = 0;
virtual ssize_t allocate(size_t size, uint32_t flags = 0) = 0;
virtual ssize_t deallocate(size_t offset) = 0;
};
virtual int alloc_buffer(alloc_data& data);
virtual int free_buffer(void *base, size_t size,
int offset, int fd);
virtual int map_buffer(void **pBase, size_t size,
int offset, int fd);
virtual int unmap_buffer(void *base, size_t size,
int offset);
virtual int clean_buffer(void*base, size_t size,
int offset, int fd);
PmemUserspaceAlloc();
~PmemUserspaceAlloc();
private:
int mMasterFd;
void* mMasterBase;
const char* mPmemDev;
Allocator* mAllocator;
pthread_mutex_t mLock;
int init_pmem_area();
int init_pmem_area_locked();
};
class PmemKernelAlloc : public IMemAlloc {
public:
virtual int alloc_buffer(alloc_data& data);
virtual int free_buffer(void *base, size_t size,
int offset, int fd);
virtual int map_buffer(void **pBase, size_t size,
int offset, int fd);
virtual int unmap_buffer(void *base, size_t size,
int offset);
virtual int clean_buffer(void*base, size_t size,
int offset, int fd);
PmemKernelAlloc(const char* device);
~PmemKernelAlloc();
private:
const char* mPmemDev;
};
}
#endif /* GRALLOC_PMEMALLOC_H */

View File

@ -382,7 +382,8 @@ int CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_t *layer,
}
ALOGE("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
int usage = GRALLOC_USAGE_PRIVATE_MM_HEAP;
int usage = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
GRALLOC_USAGE_PRIVATE_MM_HEAP;
if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, fbHandle->format, usage)){
copybit_image_t tmp_dst;

View File

@ -108,7 +108,7 @@ inline OvMem::OvMem() {
mAllocType = 0;
mBufSz = 0;
mNumBuffers = 0;
mAlloc = gralloc::IAllocController::getInstance();
mAlloc = gralloc::IAllocController::getInstance(false);
}
inline OvMem::~OvMem() { }
@ -121,6 +121,9 @@ inline bool OvMem::open(uint32_t numbufs,
if(isSecure) {
allocFlags |= GRALLOC_USAGE_PRIVATE_MM_HEAP;
allocFlags |= GRALLOC_USAGE_PRIVATE_CP_BUFFER;
#ifndef USE_ION
allocFlags |= GRALLOC_USAGE_PRIVATE_DO_NOT_MAP;
#endif
}
int err = 0;