diff --git a/libgralloc-qsd8k/framebuffer.cpp b/libgralloc-qsd8k/framebuffer.cpp index 99ec2ad..7669785 100644 --- a/libgralloc-qsd8k/framebuffer.cpp +++ b/libgralloc-qsd8k/framebuffer.cpp @@ -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; diff --git a/libgralloc-qsd8k/gpu.cpp b/libgralloc-qsd8k/gpu.cpp old mode 100644 new mode 100755 index a2ccd16..81b4579 --- a/libgralloc-qsd8k/gpu.cpp +++ b/libgralloc-qsd8k/gpu.cpp @@ -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<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 ; ialloc_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) { diff --git a/libgralloc-qsd8k/gpu.h b/libgralloc-qsd8k/gpu.h old mode 100644 new mode 100755 index 5449999..67a58d8 --- a/libgralloc-qsd8k/gpu.h +++ b/libgralloc-qsd8k/gpu.h @@ -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 diff --git a/libgralloc-qsd8k/gralloc.cpp b/libgralloc-qsd8k/gralloc.cpp old mode 100644 new mode 100755 index a0123d1..019a8cd --- a/libgralloc-qsd8k/gralloc.cpp +++ b/libgralloc-qsd8k/gralloc.cpp @@ -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); /*****************************************************************************/ diff --git a/libgralloc-qsd8k/gralloc_priv.h b/libgralloc-qsd8k/gralloc_priv.h index 650ac6c..e708452 100755 --- a/libgralloc-qsd8k/gralloc_priv.h +++ b/libgralloc-qsd8k/gralloc_priv.h @@ -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 @@ -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; diff --git a/libgralloc-qsd8k/pmemalloc.cpp b/libgralloc-qsd8k/pmemalloc.cpp old mode 100644 new mode 100755 index 91dc527..1d78333 --- a/libgralloc-qsd8k/pmemalloc.cpp +++ b/libgralloc-qsd8k/pmemalloc.cpp @@ -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; diff --git a/libgralloc-qsd8k/pmemalloc.h b/libgralloc-qsd8k/pmemalloc.h old mode 100644 new mode 100755 index b0f45c7..f433010 --- a/libgralloc-qsd8k/pmemalloc.h +++ b/libgralloc-qsd8k/pmemalloc.h @@ -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