libgralloc-qsd8k: Initial gralloc changes for honeycomb

This commit contains the following changes in the gralloc:
- Add buffertype in the gralloc handle i.e video buffer or UI buffer
- Add support for allocating memory from the /dev/pmem_smipool
- Add support for obtaining the buffer type and the HAL formats from the
input format which could be an OMX format.
- Add buffer type, format, width and height in the gralloc handle

Change-Id: Ie801cfcf5cea9c4b718b75e88abf71be6b087de7
This commit is contained in:
Naomi Luis 2011-03-07 17:35:59 -08:00 committed by Govind Surti
parent 155d9fa5fb
commit d1fc805f34
7 changed files with 157 additions and 41 deletions

View File

@ -718,7 +718,7 @@ int mapFrameBufferLocked(struct private_module_t* module)
int err;
size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual);
module->framebuffer = new private_handle_t(dup(fd), fbSize,
private_handle_t::PRIV_FLAGS_USES_PMEM);
private_handle_t::PRIV_FLAGS_USES_PMEM, BUFFER_TYPE_UI, module->fbFormat, info.xres, info.yres);
module->numBuffers = info.yres_virtual / info.yres;
module->bufferMask = 0;

81
libgralloc-qsd8k/gpu.cpp Normal file → Executable file
View File

@ -69,7 +69,7 @@ int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
// we return a regular buffer which will be memcpy'ed to the main
// screen when post is called.
int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
return gralloc_alloc_buffer(bufferSize, newUsage, pHandle);
return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI, m->fbFormat, m->info.xres, m->info.yres);
}
if (bufferMask >= ((1LU<<numBuffers)-1)) {
@ -81,7 +81,8 @@ int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
intptr_t vaddr = intptr_t(m->framebuffer->base);
private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), bufferSize,
private_handle_t::PRIV_FLAGS_USES_PMEM |
private_handle_t::PRIV_FLAGS_FRAMEBUFFER);
private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
BUFFER_TYPE_UI, m->fbFormat, m->info.xres, m->info.yres);
// find a free slot
for (uint32_t i=0 ; i<numBuffers ; i++) {
@ -151,7 +152,8 @@ int gpu_context_t::alloc_ashmem_buffer(size_t size, unsigned int postfix, void**
return err;
}
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle)
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle,
int bufferType, int format, int width, int height)
{
int err = 0;
int flags = 0;
@ -161,7 +163,6 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t*
// the PmemAllocator rather than getting the base & offset separately
int offset = 0;
int lockState = 0;
size = roundUpToPageSize(size);
#ifndef USE_ASHMEM
if (usage & GRALLOC_USAGE_HW_TEXTURE) {
@ -178,7 +179,7 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t*
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
}
#endif
if (usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) {
if ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) || (usage & GRALLOC_USAGE_PRIVATE_PMEM_SMIPOOL)) {
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
}
@ -211,7 +212,6 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t*
// PMEM buffers are always mmapped
lockState |= private_handle_t::LOCK_STATE_MAPPED;
// Allocate the buffer from pmem
err = pma->alloc_pmem_buffer(size, usage, &base, &offset, &fd);
if (err < 0) {
if (((usage & GRALLOC_USAGE_HW_MASK) == 0) &&
@ -234,7 +234,7 @@ try_ashmem:
}
if (err == 0) {
private_handle_t* hnd = new private_handle_t(fd, size, flags);
private_handle_t* hnd = new private_handle_t(fd, size, flags, bufferType, format, width, height);
hnd->offset = offset;
hnd->base = int(base)+offset;
hnd->lockState = lockState;
@ -250,6 +250,61 @@ static inline size_t ALIGN(size_t x, size_t align) {
return (x + align-1) & ~(align-1);
}
void gpu_context_t::getGrallocInformationFromFormat(int inputFormat, int *colorFormat, int *bufferType, int *halFormat)
{
*bufferType = BUFFER_TYPE_VIDEO;
*halFormat = inputFormat;
*colorFormat = inputFormat;
switch(inputFormat) {
case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
{
*colorFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
*halFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
} break;
case (OMX_QCOM_COLOR_FormatYVU420SemiPlanar ^ QOMX_INTERLACE_FLAG):
{
*colorFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
*halFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP ^ HAL_PIXEL_FORMAT_INTERLACE;
} break;
case (QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka ^ QOMX_INTERLACE_FLAG):
{
*colorFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
*halFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED ^ HAL_PIXEL_FORMAT_INTERLACE;
} break;
case (QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka ^ QOMX_3D_VIDEO_FLAG):
{
*colorFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
*halFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED | HAL_3D_IN_LR_SIDE | HAL_3D_OUT_LR_SIDE;
} break;
case QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka:
{
*colorFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
*halFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
} break;
default:
{
if (inputFormat & S3D_FORMAT_MASK) {
// S3D format
*colorFormat = COLOR_FORMAT(inputFormat);
} else if (inputFormat & INTERLACE_MASK) {
// Interlaced
*colorFormat = inputFormat ^ HAL_PIXEL_FORMAT_INTERLACE;
} else if (inputFormat < 0x7) {
// RGB formats
*colorFormat = inputFormat;
*bufferType = BUFFER_TYPE_UI;
} else if ((inputFormat == HAL_PIXEL_FORMAT_R_8) ||
(inputFormat == HAL_PIXEL_FORMAT_RG_88)) {
*colorFormat = inputFormat;
*bufferType = BUFFER_TYPE_UI;
}
break;
}
}
}
int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
buffer_handle_t* pHandle, int* pStride) {
if (!pHandle || !pStride)
@ -259,7 +314,10 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
alignedw = ALIGN(w, 32);
alignedh = ALIGN(h, 32);
switch (format) {
int colorFormat, bufferType, halFormat;
getGrallocInformationFromFormat(format, &colorFormat, &bufferType, &halFormat);
switch (colorFormat) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
@ -287,10 +345,11 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
size = ALIGN( alignedw * alignedh, 8192);
size += ALIGN( alignedw * ALIGN(h/2, 32), 4096);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YV12:
if ((w&1) || (h&1)) {
LOGE("w or h is odd for HAL_PIXEL_FORMAT_YV12");
LOGE("w or h is odd for the YUV format");
return -EINVAL;
}
alignedw = ALIGN(w, 16);
@ -311,7 +370,7 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
if (usage & GRALLOC_USAGE_HW_FB) {
err = gralloc_alloc_framebuffer(size, usage, pHandle);
} else {
err = gralloc_alloc_buffer(size, usage, pHandle);
err = gralloc_alloc_buffer(size, usage, pHandle, bufferType, halFormat, w, h);
}
if (err < 0) {

4
libgralloc-qsd8k/gpu.h Normal file → Executable file
View File

@ -56,7 +56,8 @@ class gpu_context_t : public alloc_device_t {
buffer_handle_t* pHandle);
int gralloc_alloc_framebuffer(size_t size, int usage,
buffer_handle_t* pHandle);
int gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle);
int gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle, int bufferType, int format,
int width, int height);
int free_impl(private_handle_t const* hnd);
int alloc_impl(int w, int h, int format, int usage,
buffer_handle_t* pHandle, int* pStride);
@ -73,6 +74,7 @@ class gpu_context_t : public alloc_device_t {
PmemAllocator& pmemAdspAllocator;
int alloc_ashmem_buffer(size_t size, unsigned int postfix, void** pBase,
int* pOffset, int* pFd);
void getGrallocInformationFromFormat(int inputFormat, int *colorFormat, int *bufferType, int *halFormat);
};
#endif // GRALLOC_QSD8K_GPU_H

3
libgralloc-qsd8k/gralloc.cpp Normal file → Executable file
View File

@ -149,8 +149,7 @@ static SimpleBestFitAllocator pmemAllocMgr;
static PmemUserspaceAllocator pmemAllocator(pmemAllocatorDeviceDepsImpl, pmemAllocMgr,
"/dev/pmem");
static PmemKernelAllocator pmemAdspAllocator(pmemAllocatorDeviceDepsImpl,
"/dev/pmem_adsp");
static PmemKernelAllocator pmemAdspAllocator(pmemAllocatorDeviceDepsImpl);
/*****************************************************************************/

View File

@ -38,12 +38,16 @@ using namespace overlay;
enum {
/* gralloc usage bit indicating a pmem_adsp allocation should be used */
GRALLOC_USAGE_PRIVATE_PMEM_ADSP = GRALLOC_USAGE_PRIVATE_0,
GRALLOC_USAGE_PRIVATE_PMEM = GRALLOC_USAGE_PRIVATE_1,
GRALLOC_USAGE_PRIVATE_PMEM_SMIPOOL = GRALLOC_USAGE_PRIVATE_1,
};
#define NUM_BUFFERS 2
#define NO_SURFACEFLINGER_SWAPINTERVAL
#define INTERLACE_MASK 0x80
#define S3D_FORMAT_MASK 0xFF000
#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
#define DEVICE_PMEM_ADSP "/dev/pmem_adsp"
#define DEVICE_PMEM_SMIPOOL "/dev/pmem_smipool"
/*****************************************************************************/
#ifdef __cplusplus
template <class T>
@ -154,6 +158,15 @@ enum {
HAL_3D_OUT_LR_INTERLEAVE = 0x4
};
enum {
BUFFER_TYPE_UI = 0,
BUFFER_TYPE_VIDEO
};
static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
static const int QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03;
static const int QOMX_INTERLACE_FLAG = 0x49283654;
static const int QOMX_3D_VIDEO_FLAG = 0x23784238;
/*****************************************************************************/
struct private_module_t;
@ -248,7 +261,7 @@ struct private_handle_t {
int flags;
int size;
int offset;
int gpu_fd; // stored as an int, b/c we don't want it marshalled
int bufferType;
// FIXME: the attributes below should be out-of-line
int base;
@ -256,15 +269,19 @@ struct private_handle_t {
int writeOwner;
int gpuaddr; // The gpu address mapped into the mmu. If using ashmem, set to 0 They don't care
int pid;
int format;
int width;
int height;
#ifdef __cplusplus
static const int sNumInts = 10;
static const int sNumInts = 13;
static const int sNumFds = 1;
static const int sMagic = 'gmsm';
private_handle_t(int fd, int size, int flags) :
fd(fd), magic(sMagic), flags(flags), size(size), offset(0), gpu_fd(-1),
base(0), lockState(0), writeOwner(0), gpuaddr(0), pid(getpid())
private_handle_t(int fd, int size, int flags, int bufferType, int format, int width, int height) :
fd(fd), magic(sMagic), flags(flags), size(size), offset(0), bufferType(bufferType),
base(0), lockState(0), writeOwner(0), gpuaddr(0), pid(getpid()), format(format), width(width),
height(height)
{
version = sizeof(native_handle);
numInts = sNumInts;

72
libgralloc-qsd8k/pmemalloc.cpp Normal file → Executable file
View File

@ -225,9 +225,8 @@ PmemUserspaceAllocator::Deps::~Deps()
END_FUNC;
}
PmemKernelAllocator::PmemKernelAllocator(Deps& deps, const char* pmemdev):
deps(deps),
pmemdev(pmemdev)
PmemKernelAllocator::PmemKernelAllocator(Deps& deps):
deps(deps)
{
BEGIN_FUNC;
END_FUNC;
@ -268,33 +267,66 @@ int PmemKernelAllocator::alloc_pmem_buffer(size_t size, int usage,
*pOffset = 0;
*pFd = -1;
int err;
int err, offset = 0;
int openFlags = get_open_flags(usage);
int fd = deps.open(pmemdev, openFlags, 0);
if (fd < 0) {
const char *device;
if (usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) {
device = DEVICE_PMEM_ADSP;
} else if (usage & GRALLOC_USAGE_PRIVATE_PMEM_SMIPOOL) {
device = DEVICE_PMEM_SMIPOOL;
} else {
LOGE("Invalid device");
return -EINVAL;
}
int master_fd = deps.open(device, openFlags, 0);
if (master_fd < 0) {
err = -deps.getErrno();
END_FUNC;
LOGE("Error opening %s", device);
return err;
}
// The size should already be page aligned, now round it up to a power of 2.
size = clp2(size);
//size = clp2(size);
void* base = deps.mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
void* base = deps.mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, master_fd, 0);
if (base == MAP_FAILED) {
LOGE("%s: failed to map pmem fd: %s", pmemdev,
LOGE("%s: failed to map pmem fd: %s", device,
strerror(deps.getErrno()));
err = -deps.getErrno();
deps.close(fd);
deps.close(master_fd);
END_FUNC;
return err;
}
memset(base, 0, size);
// Connect and map the PMEM region to give to the client process
int fd = deps.open(device, O_RDWR, 0);
err = fd < 0 ? fd : 0;
*pBase = base;
*pOffset = 0;
*pFd = fd;
// and connect to it
if (err == 0) {
err = deps.connectPmem(fd, master_fd);
}
// and make it available to the client process
if (err == 0) {
err = deps.mapPmem(fd, offset, size);
}
if (err == 0) {
*pBase = base;
*pOffset = 0;
*pFd = fd;
} else {
deps.munmap(base, size);
deps.unmapPmem(fd, offset, size);
deps.close(fd);
deps.close(master_fd);
return err;
}
END_FUNC;
return 0;
@ -306,12 +338,18 @@ int PmemKernelAllocator::free_pmem_buffer(size_t size, void* base, int offset, i
BEGIN_FUNC;
// The size should already be page aligned, now round it up to a power of 2
// like we did when allocating.
size = clp2(size);
//size = clp2(size);
int err = deps.munmap(base, size);
int err = deps.unmapPmem(fd, offset, size);
if (err < 0) {
err = deps.getErrno();
LOGW("%s: error unmapping pmem fd: %s", pmemdev, strerror(err));
LOGW("error unmapping pmem fd: %s", strerror(err));
return -err;
}
err = deps.munmap(base, size);
if (err < 0) {
err = deps.getErrno();
LOGW("error unmapping pmem master_fd: %s", strerror(err));
return -err;
}
END_FUNC;

7
libgralloc-qsd8k/pmemalloc.h Normal file → Executable file
View File

@ -139,9 +139,12 @@ class PmemKernelAllocator: public PmemAllocator {
virtual int munmap(void* start, size_t length) = 0;
virtual int open(const char* pathname, int flags, int mode) = 0;
virtual int close(int fd) = 0;
virtual int connectPmem(int fd, int master_fd) = 0;
virtual int mapPmem(int fd, int offset, size_t size) = 0;
virtual int unmapPmem(int fd, int offset, size_t size) = 0;
};
PmemKernelAllocator(Deps& deps, const char* pmemdev);
PmemKernelAllocator(Deps& deps);
virtual ~PmemKernelAllocator();
// Only valid after init_pmem_area() has completed successfully.
@ -154,8 +157,6 @@ class PmemKernelAllocator: public PmemAllocator {
private:
Deps& deps;
const char* pmemdev;
};
#endif // GRALLOC_QSD8K_PMEMALLOC_H