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:
parent
155d9fa5fb
commit
d1fc805f34
@ -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
81
libgralloc-qsd8k/gpu.cpp
Normal file → Executable 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
4
libgralloc-qsd8k/gpu.h
Normal file → Executable 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
3
libgralloc-qsd8k/gralloc.cpp
Normal file → Executable 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);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@ -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
72
libgralloc-qsd8k/pmemalloc.cpp
Normal file → Executable 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
7
libgralloc-qsd8k/pmemalloc.h
Normal file → Executable 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user