display: Clean up gralloc
* Remove pmem and ashmem implementations * Remove usage of RefBase * Reduce log verbosity Change-Id: If8ef543d236e5305bd5430f4f9c62c51b3a13787
This commit is contained in:
parent
6ad0635c7a
commit
be02ab0d74
@ -15,7 +15,7 @@ endif
|
||||
common_libs := liblog libutils libcutils libhardware
|
||||
|
||||
#Common C flags
|
||||
common_flags := -DUSE_ION -DDEBUG_CALC_FPS -Wno-missing-field-initializers
|
||||
common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
|
||||
ifeq ($(ARCH_ARM_HAVE_NEON),true)
|
||||
common_flags += -D__ARM_HAVE_NEON
|
||||
endif
|
||||
|
@ -426,8 +426,7 @@ static int stretch_copybit(
|
||||
}
|
||||
|
||||
if(src->format == HAL_PIXEL_FORMAT_YV12) {
|
||||
int usage = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
|
||||
GRALLOC_USAGE_PRIVATE_MM_HEAP;
|
||||
int usage = GRALLOC_USAGE_PRIVATE_MM_HEAP;
|
||||
if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
|
||||
src->format, usage)){
|
||||
if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
|
||||
|
@ -49,7 +49,6 @@
|
||||
using gralloc::IMemAlloc;
|
||||
using gralloc::IonController;
|
||||
using gralloc::alloc_data;
|
||||
using android::sp;
|
||||
|
||||
C2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
|
||||
uint32 surface_bits,
|
||||
@ -110,7 +109,7 @@ enum eC2DFlags {
|
||||
FLAGS_YUV_DESTINATION = 1<<1
|
||||
};
|
||||
|
||||
static android::sp<gralloc::IAllocController> sAlloc = 0;
|
||||
static gralloc::IAllocController* sAlloc = 0;
|
||||
/******************************************************************************/
|
||||
|
||||
/** State information for each device instance */
|
||||
@ -933,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(false);
|
||||
sAlloc = gralloc::IAllocController::getInstance();
|
||||
}
|
||||
|
||||
if (sAlloc == 0) {
|
||||
@ -941,7 +940,7 @@ static int get_temp_buffer(const bufferInfo& info, alloc_data& data)
|
||||
return COPYBIT_FAILURE;
|
||||
}
|
||||
|
||||
int err = sAlloc->allocate(data, allocFlags, 0);
|
||||
int err = sAlloc->allocate(data, allocFlags);
|
||||
if (0 != err) {
|
||||
ALOGE("%s: allocate failed", __FUNCTION__);
|
||||
return COPYBIT_FAILURE;
|
||||
@ -955,7 +954,7 @@ static int get_temp_buffer(const bufferInfo& info, alloc_data& data)
|
||||
static void free_temp_buffer(alloc_data &data)
|
||||
{
|
||||
if (-1 != data.fd) {
|
||||
sp<IMemAlloc> memalloc = sAlloc->getAllocator(data.allocType);
|
||||
IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
|
||||
memalloc->free_buffer(data.base, data.size, 0, data.fd);
|
||||
}
|
||||
}
|
||||
@ -1174,7 +1173,7 @@ static int stretch_copybit_internal(
|
||||
copy_image((private_handle_t *)src->handle, &src_image, CONVERT_TO_C2D_FORMAT);
|
||||
|
||||
// Flush the cache
|
||||
sp<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,
|
||||
src_hnd->offset, src_hnd->fd)) {
|
||||
ALOGE("%s: clean_buffer failed", __FUNCTION__);
|
||||
@ -1245,7 +1244,7 @@ static int stretch_copybit_internal(
|
||||
// copy the temp. destination without the alignment to the actual destination.
|
||||
copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
|
||||
// Invalidate the cache.
|
||||
sp<IMemAlloc> memalloc = sAlloc->getAllocator(dst_hnd->flags);
|
||||
IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
|
||||
memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
|
||||
dst_hnd->offset, dst_hnd->fd);
|
||||
}
|
||||
|
@ -28,30 +28,16 @@
|
||||
*/
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <fcntl.h>
|
||||
#include "gralloc_priv.h"
|
||||
#include "alloc_controller.h"
|
||||
#include "memalloc.h"
|
||||
#include "ionalloc.h"
|
||||
#include "pmemalloc.h"
|
||||
#include "ashmemalloc.h"
|
||||
#include "gr.h"
|
||||
#include "comptype.h"
|
||||
|
||||
using namespace gralloc;
|
||||
using namespace qdutils;
|
||||
using android::sp;
|
||||
|
||||
const int 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;
|
||||
|
||||
|
||||
//Common functions
|
||||
static bool canFallback(int usage, bool triedSystem)
|
||||
@ -88,18 +74,11 @@ static bool useUncached(int usage)
|
||||
return false;
|
||||
}
|
||||
|
||||
sp<IAllocController> IAllocController::sController = NULL;
|
||||
sp<IAllocController> IAllocController::getInstance(bool useMasterHeap)
|
||||
IAllocController* IAllocController::sController = NULL;
|
||||
IAllocController* IAllocController::getInstance(void)
|
||||
{
|
||||
if(sController == NULL) {
|
||||
#ifdef USE_ION
|
||||
sController = new IonController();
|
||||
#else
|
||||
if(useMasterHeap)
|
||||
sController = new PmemAshmemController();
|
||||
else
|
||||
sController = new PmemKernelController();
|
||||
#endif
|
||||
}
|
||||
return sController;
|
||||
}
|
||||
@ -111,8 +90,7 @@ IonController::IonController()
|
||||
mIonAlloc = new IonAlloc();
|
||||
}
|
||||
|
||||
int IonController::allocate(alloc_data& data, int usage,
|
||||
int compositionType)
|
||||
int IonController::allocate(alloc_data& data, int usage)
|
||||
{
|
||||
int ionFlags = 0;
|
||||
int ret;
|
||||
@ -135,20 +113,12 @@ int IonController::allocate(alloc_data& data, int usage,
|
||||
if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)
|
||||
ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
|
||||
|
||||
if(usage & GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP)
|
||||
ionFlags |= ION_HEAP(ION_CP_WB_HEAP_ID);
|
||||
|
||||
if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
|
||||
ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
|
||||
|
||||
if(usage & GRALLOC_USAGE_PRIVATE_CP_BUFFER)
|
||||
ionFlags |= ION_SECURE;
|
||||
|
||||
if(usage & GRALLOC_USAGE_PRIVATE_DO_NOT_MAP)
|
||||
data.allocType |= private_handle_t::PRIV_FLAGS_NOT_MAPPED;
|
||||
else
|
||||
data.allocType &= ~(private_handle_t::PRIV_FLAGS_NOT_MAPPED);
|
||||
|
||||
// if no flags are set, default to
|
||||
// SF + IOMMU heaps, so that bypass can work
|
||||
// we can fall back to system heap if
|
||||
@ -180,9 +150,9 @@ int IonController::allocate(alloc_data& data, int usage,
|
||||
return ret;
|
||||
}
|
||||
|
||||
sp<IMemAlloc> IonController::getAllocator(int flags)
|
||||
IMemAlloc* IonController::getAllocator(int flags)
|
||||
{
|
||||
sp<IMemAlloc> memalloc;
|
||||
IMemAlloc* memalloc;
|
||||
if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
|
||||
memalloc = mIonAlloc;
|
||||
} else {
|
||||
@ -192,151 +162,6 @@ sp<IMemAlloc> IonController::getAllocator(int flags)
|
||||
return memalloc;
|
||||
}
|
||||
|
||||
//-------------- PmemKernelController-----------------------//
|
||||
//XXX: Remove - we're not using pmem anymore
|
||||
#if 0
|
||||
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 compositionType)
|
||||
{
|
||||
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);
|
||||
sp<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;
|
||||
}
|
||||
|
||||
sp<IMemAlloc> PmemKernelController::getAllocator(int flags)
|
||||
{
|
||||
sp<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 compositionType)
|
||||
{
|
||||
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, compositionType);
|
||||
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;
|
||||
}
|
||||
|
||||
sp<IMemAlloc> PmemAshmemController::getAllocator(int flags)
|
||||
{
|
||||
sp<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)
|
||||
{
|
||||
@ -417,8 +242,8 @@ int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
|
||||
{
|
||||
alloc_data data;
|
||||
int alignedw, alignedh;
|
||||
android::sp<gralloc::IAllocController> sAlloc =
|
||||
gralloc::IAllocController::getInstance(false);
|
||||
gralloc::IAllocController* sAlloc =
|
||||
gralloc::IAllocController::getInstance();
|
||||
data.base = 0;
|
||||
data.fd = -1;
|
||||
data.offset = 0;
|
||||
@ -427,14 +252,15 @@ int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
|
||||
data.uncached = useUncached(usage);
|
||||
int allocFlags = usage;
|
||||
|
||||
int err = sAlloc->allocate(data, allocFlags, 0);
|
||||
int err = sAlloc->allocate(data, allocFlags);
|
||||
if (0 != err) {
|
||||
ALOGE("%s: allocate failed", __FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
private_handle_t* hnd = new private_handle_t(data.fd, data.size,
|
||||
data.allocType, 0, format, alignedw, alignedh);
|
||||
data.allocType, 0, format,
|
||||
alignedw, alignedh);
|
||||
hnd->base = (int) data.base;
|
||||
hnd->offset = data.offset;
|
||||
hnd->gpuaddr = 0;
|
||||
@ -444,10 +270,10 @@ int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
|
||||
|
||||
void free_buffer(private_handle_t *hnd)
|
||||
{
|
||||
android::sp<gralloc::IAllocController> sAlloc =
|
||||
gralloc::IAllocController::getInstance(false);
|
||||
gralloc::IAllocController* sAlloc =
|
||||
gralloc::IAllocController::getInstance();
|
||||
if (hnd && hnd->fd > 0) {
|
||||
sp<IMemAlloc> memalloc = sAlloc->getAllocator(hnd->flags);
|
||||
IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
|
||||
memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
|
||||
}
|
||||
if(hnd)
|
||||
|
@ -29,86 +29,43 @@
|
||||
#ifndef GRALLOC_ALLOCCONTROLLER_H
|
||||
#define GRALLOC_ALLOCCONTROLLER_H
|
||||
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace gralloc {
|
||||
|
||||
struct alloc_data;
|
||||
class IMemAlloc;
|
||||
class IonAlloc;
|
||||
|
||||
class IAllocController : public android::RefBase {
|
||||
class IAllocController {
|
||||
|
||||
public:
|
||||
/* Allocate using a suitable method
|
||||
* Returns the type of buffer allocated
|
||||
*/
|
||||
virtual int allocate(alloc_data& data, int usage,
|
||||
int compositionType) = 0;
|
||||
virtual int allocate(alloc_data& data, int usage) = 0;
|
||||
|
||||
virtual android::sp<IMemAlloc> getAllocator(int flags) = 0;
|
||||
virtual IMemAlloc* getAllocator(int flags) = 0;
|
||||
|
||||
virtual ~IAllocController() {};
|
||||
|
||||
static android::sp<IAllocController> getInstance(bool useMasterHeap);
|
||||
static IAllocController* getInstance(void);
|
||||
|
||||
private:
|
||||
static android::sp<IAllocController> sController;
|
||||
static IAllocController* sController;
|
||||
|
||||
};
|
||||
|
||||
class IonController : public IAllocController {
|
||||
|
||||
public:
|
||||
virtual int allocate(alloc_data& data, int usage,
|
||||
int compositionType);
|
||||
virtual int allocate(alloc_data& data, int usage);
|
||||
|
||||
virtual android::sp<IMemAlloc> getAllocator(int flags);
|
||||
virtual IMemAlloc* getAllocator(int flags);
|
||||
|
||||
IonController();
|
||||
|
||||
private:
|
||||
android::sp<IonAlloc> mIonAlloc;
|
||||
IonAlloc* mIonAlloc;
|
||||
|
||||
};
|
||||
|
||||
class PmemKernelController : public IAllocController {
|
||||
|
||||
public:
|
||||
virtual int allocate(alloc_data& data, int usage,
|
||||
int compositionType);
|
||||
|
||||
virtual android::sp<IMemAlloc> getAllocator(int flags);
|
||||
|
||||
PmemKernelController ();
|
||||
|
||||
~PmemKernelController ();
|
||||
|
||||
private:
|
||||
android::sp<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,
|
||||
int compositionType);
|
||||
|
||||
virtual android::sp<IMemAlloc> getAllocator(int flags);
|
||||
|
||||
PmemAshmemController();
|
||||
|
||||
~PmemAshmemController();
|
||||
|
||||
private:
|
||||
android::sp<IMemAlloc> mPmemUserspaceAlloc;
|
||||
android::sp<IMemAlloc> mAshmemAlloc;
|
||||
android::sp<IAllocController> mPmemKernelCtrl;
|
||||
|
||||
};
|
||||
|
||||
} //end namespace gralloc
|
||||
#endif // GRALLOC_ALLOCCONTROLLER_H
|
||||
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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 */
|
@ -29,10 +29,9 @@
|
||||
#include "alloc_controller.h"
|
||||
|
||||
using namespace gralloc;
|
||||
using android::sp;
|
||||
|
||||
gpu_context_t::gpu_context_t(const private_module_t* module,
|
||||
sp<IAllocController> alloc_ctrl ) :
|
||||
IAllocController* alloc_ctrl ) :
|
||||
mAllocCtrl(alloc_ctrl)
|
||||
{
|
||||
// Zero out the alloc_device_t
|
||||
@ -44,9 +43,6 @@ gpu_context_t::gpu_context_t(const private_module_t* module,
|
||||
common.module = const_cast<hw_module_t*>(&module->base.common);
|
||||
common.close = gralloc_close;
|
||||
alloc = gralloc_alloc;
|
||||
#if 0
|
||||
allocSize = gralloc_alloc_size;
|
||||
#endif
|
||||
free = gralloc_free;
|
||||
|
||||
}
|
||||
@ -56,8 +52,8 @@ int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
{
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
|
||||
|
||||
// we don't support allocations with both the FB and PMEM_ADSP flags
|
||||
if (usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) {
|
||||
// we don't support framebuffer allocations with graphics heap flags
|
||||
if (usage & GRALLOC_HEAP_MASK) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -140,7 +136,7 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage,
|
||||
else
|
||||
data.align = getpagesize();
|
||||
data.pHandle = (unsigned int) pHandle;
|
||||
err = mAllocCtrl->allocate(data, usage, 0);
|
||||
err = mAllocCtrl->allocate(data, usage);
|
||||
|
||||
if (usage & GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED) {
|
||||
flags |= private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED;
|
||||
@ -244,7 +240,7 @@ int gpu_context_t::free_impl(private_handle_t const* hnd) {
|
||||
m->bufferMask &= ~(1<<index);
|
||||
} else {
|
||||
terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
|
||||
sp<IMemAlloc> memalloc = mAllocCtrl->getAllocator(hnd->flags);
|
||||
IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags);
|
||||
int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size,
|
||||
hnd->offset, hnd->fd);
|
||||
if(err)
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/ashmem.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
#include "gralloc_priv.h"
|
||||
#include <fb_priv.h>
|
||||
@ -35,7 +34,7 @@ class IAllocController;
|
||||
class gpu_context_t : public alloc_device_t {
|
||||
public:
|
||||
gpu_context_t(const private_module_t* module,
|
||||
android::sp<IAllocController>alloc_ctrl);
|
||||
IAllocController* alloc_ctrl);
|
||||
|
||||
int gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
buffer_handle_t* pHandle);
|
||||
@ -69,7 +68,7 @@ class gpu_context_t : public alloc_device_t {
|
||||
static int gralloc_close(struct hw_device_t *dev);
|
||||
|
||||
private:
|
||||
android::sp<IAllocController> mAllocCtrl;
|
||||
IAllocController* mAllocCtrl;
|
||||
void getGrallocInformationFromFormat(int inputFormat,
|
||||
int *colorFormat,
|
||||
int *bufferType);
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
#include <linux/android_pmem.h>
|
||||
|
||||
@ -33,7 +32,6 @@
|
||||
#include "alloc_controller.h"
|
||||
|
||||
using namespace gralloc;
|
||||
using android::sp;
|
||||
|
||||
int fb_device_open(const hw_module_t* module, const char* name,
|
||||
hw_device_t** device);
|
||||
@ -102,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;
|
||||
sp<IAllocController> alloc_ctrl = IAllocController::getInstance(true);
|
||||
IAllocController* alloc_ctrl = IAllocController::getInstance();
|
||||
dev = new gpu_context_t(m, alloc_ctrl);
|
||||
*device = &dev->common;
|
||||
status = 0;
|
||||
|
@ -34,33 +34,22 @@ enum {
|
||||
/* gralloc usage bits indicating the type
|
||||
* of allocation that should be used */
|
||||
|
||||
/* 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,
|
||||
GRALLOC_USAGE_PRIVATE_SYSTEM_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,
|
||||
/* IOMMU heap comes from manually allocated pages,
|
||||
* can be cached/uncached, is not secured */
|
||||
GRALLOC_USAGE_PRIVATE_IOMMU_HEAP = 0x01000000,
|
||||
GRALLOC_USAGE_PRIVATE_IOMMU_HEAP = GRALLOC_USAGE_PRIVATE_2,
|
||||
/* 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,
|
||||
GRALLOC_USAGE_PRIVATE_MM_HEAP = GRALLOC_USAGE_PRIVATE_3,
|
||||
/* CAMERA heap is a carveout heap for camera, is not secured*/
|
||||
GRALLOC_USAGE_PRIVATE_CAMERA_HEAP = 0x08000000,
|
||||
GRALLOC_USAGE_PRIVATE_CAMERA_HEAP = 0x01000000,
|
||||
|
||||
/* 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,
|
||||
GRALLOC_USAGE_PRIVATE_UNCACHED = 0x02000000,
|
||||
|
||||
/* This flag can be set to disable genlock synchronization
|
||||
* for the gralloc buffer. If this flag is set the caller
|
||||
@ -68,28 +57,32 @@ enum {
|
||||
* 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,
|
||||
GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED = 0X04000000,
|
||||
|
||||
/* Buffer content should be displayed on an external display only */
|
||||
GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY = 0x00010000,
|
||||
GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY = 0x08000000,
|
||||
|
||||
/* 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,
|
||||
GRALLOC_USAGE_PRIVATE_EXTERNAL_BLOCK = 0x00100000,
|
||||
|
||||
/* Close Caption displayed on an external display only */
|
||||
GRALLOC_USAGE_PRIVATE_EXTERNAL_CC = 0x00040000,
|
||||
GRALLOC_USAGE_PRIVATE_EXTERNAL_CC = 0x00200000,
|
||||
|
||||
/* 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
|
||||
*/
|
||||
GRALLOC_USAGE_PRIVATE_CP_BUFFER = 0x00080000,
|
||||
GRALLOC_USAGE_PRIVATE_CP_BUFFER = 0x00400000,
|
||||
|
||||
/* Legacy heaps - these heaps are no-ops so we are making them zero
|
||||
* The flags need to be around to compile certain HALs which have
|
||||
* not cleaned up the code
|
||||
*/
|
||||
GRALLOC_USAGE_PRIVATE_ADSP_HEAP = 0x0,
|
||||
GRALLOC_USAGE_PRIVATE_SMI_HEAP = 0x0,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -98,12 +91,12 @@ enum {
|
||||
GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 0x080000001,
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
#define INTERLACE_MASK 0x80
|
||||
#define S3D_FORMAT_MASK 0xFF000
|
||||
#define DEVICE_PMEM "/dev/pmem"
|
||||
#define DEVICE_PMEM_ADSP "/dev/pmem_adsp"
|
||||
#define DEVICE_PMEM_SMIPOOL "/dev/pmem_smipool"
|
||||
/*****************************************************************************/
|
||||
enum {
|
||||
/* OEM specific HAL formats */
|
||||
|
@ -27,7 +27,7 @@
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#define DEBUG 0
|
||||
#include <linux/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
@ -118,9 +118,7 @@ int IonAlloc::alloc_buffer(alloc_data& data)
|
||||
return err;
|
||||
}
|
||||
|
||||
if(!(data.flags & ION_SECURE) &&
|
||||
!(data.allocType & private_handle_t::PRIV_FLAGS_NOT_MAPPED)) {
|
||||
|
||||
if(!(data.flags & ION_SECURE)) {
|
||||
base = mmap(0, ionAllocData.len, PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, fd_data.fd, 0);
|
||||
if(base == MAP_FAILED) {
|
||||
@ -144,7 +142,7 @@ int IonAlloc::alloc_buffer(alloc_data& data)
|
||||
data.base = base;
|
||||
data.fd = fd_data.fd;
|
||||
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
|
||||
ALOGD("ion: Allocated buffer base:%p size:%d fd:%d",
|
||||
ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%d fd:%d",
|
||||
data.base, ionAllocData.len, data.fd);
|
||||
return 0;
|
||||
}
|
||||
@ -153,7 +151,7 @@ int IonAlloc::alloc_buffer(alloc_data& data)
|
||||
int IonAlloc::free_buffer(void* base, size_t size, int offset, int fd)
|
||||
{
|
||||
Locker::Autolock _l(mLock);
|
||||
ALOGD("ion: Freeing buffer base:%p size:%d fd:%d",
|
||||
ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%d fd:%d",
|
||||
base, size, fd);
|
||||
int err = 0;
|
||||
err = open_device();
|
||||
@ -181,10 +179,10 @@ int IonAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
|
||||
*pBase = base;
|
||||
if(base == MAP_FAILED) {
|
||||
err = -errno;
|
||||
ALOGD("ion: Failed to map memory in the client: %s",
|
||||
ALOGE("ion: Failed to map memory in the client: %s",
|
||||
strerror(errno));
|
||||
} else {
|
||||
ALOGD("ion: Mapped buffer base:%p size:%d offset:%d fd:%d",
|
||||
ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%d offset:%d fd:%d",
|
||||
base, size, offset, fd);
|
||||
}
|
||||
return err;
|
||||
@ -192,7 +190,7 @@ int IonAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
|
||||
|
||||
int IonAlloc::unmap_buffer(void *base, size_t size, int offset)
|
||||
{
|
||||
ALOGD("ion: Unmapping buffer base:%p size:%d", base, size);
|
||||
ALOGD_IF(DEBUG, "ion: Unmapping buffer base:%p size:%d", base, size);
|
||||
int err = 0;
|
||||
if(munmap(base, size)) {
|
||||
err = -errno;
|
||||
|
@ -44,15 +44,14 @@
|
||||
#include "memalloc.h"
|
||||
|
||||
using namespace gralloc;
|
||||
using android::sp;
|
||||
/*****************************************************************************/
|
||||
|
||||
// Return the type of allocator -
|
||||
// these are used for mapping/unmapping
|
||||
static sp<IMemAlloc> getAllocator(int flags)
|
||||
static IMemAlloc* getAllocator(int flags)
|
||||
{
|
||||
sp<IMemAlloc> memalloc;
|
||||
sp<IAllocController> alloc_ctrl = IAllocController::getInstance(true);
|
||||
IMemAlloc* memalloc;
|
||||
IAllocController* alloc_ctrl = IAllocController::getInstance();
|
||||
memalloc = alloc_ctrl->getAllocator(flags);
|
||||
return memalloc;
|
||||
}
|
||||
@ -66,7 +65,7 @@ static int gralloc_map(gralloc_module_t const* module,
|
||||
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
|
||||
!(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
|
||||
size_t size = hnd->size;
|
||||
sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
|
||||
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
|
||||
int err = memalloc->map_buffer(&mappedAddress, size,
|
||||
hnd->offset, hnd->fd);
|
||||
if(err) {
|
||||
@ -98,7 +97,7 @@ static int gralloc_unmap(gralloc_module_t const* module,
|
||||
int err = -EINVAL;
|
||||
void* base = (void*)hnd->base;
|
||||
size_t size = hnd->size;
|
||||
sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
|
||||
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
|
||||
if(memalloc != NULL)
|
||||
err = memalloc->unmap_buffer(base, size, hnd->offset);
|
||||
if (err) {
|
||||
@ -284,7 +283,7 @@ int gralloc_unlock(gralloc_module_t const* module,
|
||||
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
|
||||
int err;
|
||||
sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
|
||||
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",
|
||||
@ -328,25 +327,7 @@ 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;
|
||||
unsigned int contigFlags = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
|
||||
GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |
|
||||
GRALLOC_USAGE_PRIVATE_SMI_HEAP;
|
||||
|
||||
if (memoryFlags & contigFlags) {
|
||||
// check if the buffer is a pmem buffer
|
||||
pmem_region region;
|
||||
if (ioctl(fd, PMEM_GET_SIZE, ®ion) < 0)
|
||||
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;
|
||||
} else {
|
||||
if (memoryFlags & GRALLOC_USAGE_PRIVATE_ION)
|
||||
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
|
||||
else
|
||||
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ASHMEM;
|
||||
}
|
||||
|
||||
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
|
||||
hnd->size = size;
|
||||
hnd->offset = offset;
|
||||
hnd->base = intptr_t(base) + offset;
|
||||
|
@ -31,7 +31,6 @@
|
||||
#define GRALLOC_MEMALLOC_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace gralloc {
|
||||
|
||||
@ -47,7 +46,7 @@ struct alloc_data {
|
||||
int allocType;
|
||||
};
|
||||
|
||||
class IMemAlloc : public android::RefBase {
|
||||
class IMemAlloc {
|
||||
|
||||
public:
|
||||
// Allocate buffer - fill in the alloc_data
|
||||
|
@ -1,195 +0,0 @@
|
||||
/*
|
||||
* 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) {
|
||||
ALOG_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);
|
||||
|
||||
ALOG_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;
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* 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_ */
|
@ -1,387 +0,0 @@
|
||||
/*
|
||||
* 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 <errno.h>
|
||||
#include <linux/android_pmem.h>
|
||||
#include "gralloc_priv.h"
|
||||
#include "pmemalloc.h"
|
||||
#include "pmem_bestfit_alloc.h"
|
||||
|
||||
using namespace gralloc;
|
||||
using android::sp;
|
||||
|
||||
// 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, ®ion)) {
|
||||
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 {
|
||||
ALOGD("%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)
|
||||
{
|
||||
ALOGD("%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 {
|
||||
ALOGD("%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;
|
||||
ALOGD("%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;
|
||||
ALOGD("%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)
|
||||
{
|
||||
ALOGD("%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 {
|
||||
ALOGD("%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);
|
||||
}
|
||||
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* 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 <utils/RefBase.h>
|
||||
#include "memalloc.h"
|
||||
|
||||
namespace gralloc {
|
||||
class PmemUserspaceAlloc : public IMemAlloc {
|
||||
|
||||
public:
|
||||
class Allocator: public android::RefBase {
|
||||
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;
|
||||
android::sp<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 */
|
0
libhwcomposer/hwc_mdpcomp.cpp
Executable file → Normal file
0
libhwcomposer/hwc_mdpcomp.cpp
Executable file → Normal file
0
libhwcomposer/hwc_mdpcomp.h
Executable file → Normal file
0
libhwcomposer/hwc_mdpcomp.h
Executable file → Normal file
@ -94,12 +94,11 @@ private:
|
||||
uint32_t mNumBuffers;
|
||||
|
||||
/* gralloc alloc controller */
|
||||
android::sp<gralloc::IAllocController> mAlloc;
|
||||
gralloc::IAllocController* mAlloc;
|
||||
};
|
||||
|
||||
//-------------------Inlines-----------------------------------
|
||||
|
||||
using android::sp;
|
||||
using gralloc::IMemAlloc;
|
||||
using gralloc::alloc_data;
|
||||
|
||||
@ -109,7 +108,7 @@ inline OvMem::OvMem() {
|
||||
mAllocType = 0;
|
||||
mBufSz = 0;
|
||||
mNumBuffers = 0;
|
||||
mAlloc = gralloc::IAllocController::getInstance(false);
|
||||
mAlloc = gralloc::IAllocController::getInstance();
|
||||
}
|
||||
|
||||
inline OvMem::~OvMem() { }
|
||||
@ -121,7 +120,6 @@ inline bool OvMem::open(uint32_t numbufs,
|
||||
int allocFlags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
|
||||
if(isSecure) {
|
||||
allocFlags |= GRALLOC_USAGE_PRIVATE_MM_HEAP;
|
||||
allocFlags |= GRALLOC_USAGE_PRIVATE_DO_NOT_MAP;
|
||||
allocFlags |= GRALLOC_USAGE_PRIVATE_CP_BUFFER;
|
||||
}
|
||||
|
||||
@ -138,12 +136,12 @@ inline bool OvMem::open(uint32_t numbufs,
|
||||
data.align = getpagesize();
|
||||
data.uncached = true;
|
||||
|
||||
err = mAlloc->allocate(data, allocFlags, 0);
|
||||
err = mAlloc->allocate(data, allocFlags);
|
||||
//see if we can fallback to other heap
|
||||
//we can try MM_HEAP once if it's not secure playback
|
||||
if (err != 0 && !isSecure) {
|
||||
allocFlags |= GRALLOC_USAGE_PRIVATE_MM_HEAP;
|
||||
err = mAlloc->allocate(data, allocFlags, 0);
|
||||
err = mAlloc->allocate(data, allocFlags);
|
||||
if (err != 0) {
|
||||
ALOGE(" could not allocate from fallback heap");
|
||||
return false;
|
||||
@ -169,7 +167,7 @@ inline bool OvMem::close()
|
||||
return true;
|
||||
}
|
||||
|
||||
sp<IMemAlloc> memalloc = mAlloc->getAllocator(mAllocType);
|
||||
IMemAlloc* memalloc = mAlloc->getAllocator(mAllocType);
|
||||
ret = memalloc->free_buffer(mBaseAddr, mBufSz * mNumBuffers, 0, mFd);
|
||||
if (ret != 0) {
|
||||
ALOGE("OvMem: error freeing buffer");
|
||||
|
@ -182,10 +182,6 @@ inline bool GenericPipe<PANEL>::setSource(
|
||||
const utils::PipeArgs& args)
|
||||
{
|
||||
utils::PipeArgs newargs(args);
|
||||
//Interlace video handling.
|
||||
if(newargs.whf.format & INTERLACE_MASK) {
|
||||
setMdpFlags(newargs.mdpFlags, utils::OV_MDP_DEINTERLACE);
|
||||
}
|
||||
utils::Whf whf(newargs.whf);
|
||||
//Extract HAL format from lower bytes. Deinterlace if interlaced.
|
||||
whf.format = utils::getColorFormat(whf.format);
|
||||
|
0
libqdutils/idle_invalidator.cpp
Executable file → Normal file
0
libqdutils/idle_invalidator.cpp
Executable file → Normal file
Loading…
x
Reference in New Issue
Block a user