diff options
| author | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2014-01-23 05:18:47 +0000 |
|---|---|---|
| committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2014-01-23 16:08:27 +0000 |
| commit | 797e73d26d9153732fae0c75cf4f8f64fb40b06c (patch) | |
| tree | 550244b3fe51416da5853580f0253feeda734468 | |
| parent | fc63c06a510824835366f32a50aea22331b7de7b (diff) | |
| download | android_hardware_qcom_media-797e73d26d9153732fae0c75cf4f8f64fb40b06c.tar.gz android_hardware_qcom_media-797e73d26d9153732fae0c75cf4f8f64fb40b06c.tar.bz2 android_hardware_qcom_media-797e73d26d9153732fae0c75cf4f8f64fb40b06c.zip | |
libc2dcolorconvert: Add compatibility with older libc2d
The C2D implementation on Adreno200 either lacks the map/unmap
functions, or returns invalid values, so fallback to the direct
usage of /dev/kgsl nodes to map GPU memory when the symbols are
absent.
Change-Id: I243d2ef6f4257bace2c785230d71cd032a5b6a09
| -rw-r--r-- | libc2dcolorconvert/C2DColorConverter.cpp | 96 |
1 files changed, 77 insertions, 19 deletions
diff --git a/libc2dcolorconvert/C2DColorConverter.cpp b/libc2dcolorconvert/C2DColorConverter.cpp index 0d6b267f..30409bd5 100644 --- a/libc2dcolorconvert/C2DColorConverter.cpp +++ b/libc2dcolorconvert/C2DColorConverter.cpp @@ -88,6 +88,7 @@ private: uint32_t mSrcSurface, mDstSurface; void * mSrcSurfaceDef; void * mDstSurfaceDef; + int32_t mKgslFd = -1; C2D_OBJECT mBlit; size_t mSrcWidth; @@ -128,7 +129,7 @@ C2DColorConverter::C2DColorConverter(size_t srcWidth, size_t srcHeight, size_t d if (!mC2DCreateSurface || !mC2DUpdateSurface || !mC2DReadSurface || !mC2DDraw || !mC2DFlush || !mC2DFinish || !mC2DWaitTimestamp - || !mC2DDestroySurface || !mC2DMapAddr || !mC2DUnMapAddr) { + || !mC2DDestroySurface) { ALOGE("%s: dlsym ERROR", __FUNCTION__); mError = -1; return; @@ -148,6 +149,22 @@ C2DColorConverter::C2DColorConverter(size_t srcWidth, size_t srcHeight, size_t d mFlags = flags; // can be used for rotation + if (!mC2DMapAddr || !mC2DUnMapAddr) + { + ALOGD("%s: Found older ioctl-based c2d mapping, enabling fallbacks"); + mKgslFd = open("/dev/kgsl-2d0", O_RDWR | O_SYNC); + if (mKgslFd < 0) { + mSrcStride = 0; + ALOGE("Cannot open device kgsl-2d0, trying kgsl-3d0\n"); + mKgslFd = open("/dev/kgsl-3d0", O_RDWR | O_SYNC); + if (mKgslFd < 0) { + ALOGE("Failed to open device kgsl-3d0\n"); + mError = -1; + return; + } + } + } + mSrcSurfaceDef = getDummySurfaceDef(srcFormat, srcWidth, srcHeight, true); mDstSurfaceDef = getDummySurfaceDef(dstFormat, dstWidth, dstHeight, false); @@ -318,7 +335,10 @@ C2D_STATUS C2DColorConverter::updateYUVSurfaceDef(int fd, void *base, void *data if (isSource) { C2D_YUV_SURFACE_DEF * srcSurfaceDef = (C2D_YUV_SURFACE_DEF *)mSrcSurfaceDef; srcSurfaceDef->plane0 = data; - srcSurfaceDef->phys0 = getMappedGPUAddr(fd, data, mSrcSize) + ((uint8_t *)data - (uint8_t *)base); + srcSurfaceDef->phys0 = getMappedGPUAddr(fd, data, mSrcSize); + if (mKgslFd < 0) { + srcSurfaceDef->phys0 += ((uint8_t *)data - (uint8_t *)base); + } srcSurfaceDef->plane1 = (uint8_t *)data + mSrcYSize; srcSurfaceDef->phys1 = (uint8_t *)srcSurfaceDef->phys0 + mSrcYSize; srcSurfaceDef->plane2 = (uint8_t *)srcSurfaceDef->plane1 + mSrcYSize/4; @@ -330,7 +350,10 @@ C2D_STATUS C2DColorConverter::updateYUVSurfaceDef(int fd, void *base, void *data } else { C2D_YUV_SURFACE_DEF * dstSurfaceDef = (C2D_YUV_SURFACE_DEF *)mDstSurfaceDef; dstSurfaceDef->plane0 = data; - dstSurfaceDef->phys0 = getMappedGPUAddr(fd, data, mDstSize) + ((uint8_t *)data - (uint8_t *)base); + dstSurfaceDef->phys0 = getMappedGPUAddr(fd, data, mDstSize); + if (mKgslFd < 0) { + dstSurfaceDef->phys0 += ((uint8_t *)data - (uint8_t *)base); + } dstSurfaceDef->plane1 = (uint8_t *)data + mDstYSize; dstSurfaceDef->phys1 = (uint8_t *)dstSurfaceDef->phys0 + mDstYSize; dstSurfaceDef->plane2 = (uint8_t *)dstSurfaceDef->plane1 + mDstYSize/4; @@ -492,31 +515,66 @@ size_t C2DColorConverter::calcSize(ColorConvertFormat format, size_t width, size */ void * C2DColorConverter::getMappedGPUAddr(int bufFD, void *bufPtr, size_t bufLen) { - C2D_STATUS status; - void *gpuaddr = NULL; - - status = mC2DMapAddr(bufFD, bufPtr, bufLen, 0, KGSL_USER_MEM_TYPE_ION, - &gpuaddr); - if (status != C2D_STATUS_OK) { - ALOGE("c2dMapAddr failed: status %d fd %d ptr %p len %d flags %d\n", - status, bufFD, bufPtr, bufLen, KGSL_USER_MEM_TYPE_ION); + if (mKgslFd > 0) { + struct kgsl_map_user_mem param; + memset(¶m,0x0,sizeof(param)); + param.fd = bufFD; + param.len = bufLen; + param.hostptr = (unsigned int)bufPtr; + param.memtype = KGSL_USER_MEM_TYPE_ION; + + if (!ioctl(mKgslFd, IOCTL_KGSL_MAP_USER_MEM, ¶m, sizeof(param))) { + ALOGV("mapping successful for buffer %p size %d\n", + bufPtr, bufLen); + return (void *)param.gpuaddr; + } + ALOGE("mapping failed w/ errno %s", strerror(errno)); return NULL; - } - ALOGV("c2d mapping created: gpuaddr %p fd %d ptr %p len %d\n", - gpuaddr, bufFD, bufPtr, bufLen); - return gpuaddr; + } else { + C2D_STATUS status; + void *gpuaddr = NULL; + + status = mC2DMapAddr(bufFD, bufPtr, bufLen, 0, KGSL_USER_MEM_TYPE_ION, + &gpuaddr); + if (status != C2D_STATUS_OK) { + ALOGE("c2dMapAddr failed: status %d fd %d ptr %p len %d flags %d\n", + status, bufFD, bufPtr, bufLen, KGSL_USER_MEM_TYPE_ION); + return NULL; + } + ALOGV("c2d mapping created: gpuaddr %p fd %d ptr %p len %d\n", + gpuaddr, bufFD, bufPtr, bufLen); + return gpuaddr; + } + return NULL; } bool C2DColorConverter::unmapGPUAddr(uint32_t gAddr) { + if (mKgslFd > 0) { + int rc = 0; + struct kgsl_sharedmem_free param; + memset(¶m, 0, sizeof(param)); + param.gpuaddr = gAddr; + + rc = ioctl(mKgslFd, IOCTL_KGSL_SHAREDMEM_FREE, (void *)¶m, + sizeof(param)); + if (rc < 0) { + ALOGE("%s: IOCTL_KGSL_SHAREDMEM_FREE failed rc = %d\n", __func__, rc); + return false; + } + return true; - C2D_STATUS status = mC2DUnMapAddr((void*)gAddr); + } else { + + C2D_STATUS status = mC2DUnMapAddr((void*)gAddr); - if (status != C2D_STATUS_OK) - ALOGE("c2dUnMapAddr failed: status %d gpuaddr %08x\n", status, gAddr); + if (status != C2D_STATUS_OK) + ALOGE("c2dUnMapAddr failed: status %d gpuaddr %08x\n", status, gAddr); - return (status == C2D_STATUS_OK); + return (status == C2D_STATUS_OK); + } + return false; } int32_t C2DColorConverter::getBuffReq(int32_t port, C2DBuffReq *req) { |
