From 2ce4ec69b89e382dec6786e721c6ce8c4832972a Mon Sep 17 00:00:00 2001 From: Naomi Luis Date: Wed, 14 Dec 2011 13:11:43 -0800 Subject: [PATCH 1/8] libcopybit: Temporary buffer optimization. Add the following optimizations for the temporary buffer: - Initialize the temp buffer only when required. - The temp buffer is not deallocated/released unless there is a change in size of the temporary buffer. Change-Id: I833851b1feff0a7457ad6847f18a988e002d61d5 CRs-fixed: 319337 --- libcopybit/Android.mk | 2 +- libcopybit/copybit_c2d.cpp | 301 +++++++++++++++++++------------------ 2 files changed, 153 insertions(+), 150 deletions(-) diff --git a/libcopybit/Android.mk b/libcopybit/Android.mk index 1d2a0e5..047a2eb 100644 --- a/libcopybit/Android.mk +++ b/libcopybit/Android.mk @@ -21,7 +21,7 @@ ifeq ($(TARGET_USES_C2D_COMPOSITION),true) include $(CLEAR_VARS) LOCAL_PRELINK_MODULE := false LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw - LOCAL_SHARED_LIBRARIES := liblog libdl libcutils + LOCAL_SHARED_LIBRARIES := liblog libdl libcutils libmemalloc libutils LOCAL_SRC_FILES := copybit_c2d.cpp software_converter.cpp LOCAL_MODULE := copybit.$(TARGET_BOARD_PLATFORM) LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp index f05711d..274ad7d 100644 --- a/libcopybit/copybit_c2d.cpp +++ b/libcopybit/copybit_c2d.cpp @@ -41,11 +41,19 @@ #include #include +#include +#include #include "c2d2.h" #include "software_converter.h" #include + +using gralloc::IMemAlloc; +using gralloc::IonController; +using gralloc::alloc_data; +using android::sp; + C2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id, uint32 surface_bits, C2D_SURFACE_TYPE surface_type, @@ -103,6 +111,8 @@ enum eC2DFlags { FLAGS_PREMULTIPLIED_ALPHA = 1<<0, FLAGS_YUV_DESTINATION = 1<<1 }; + +static android::sp sAlloc = 0; /******************************************************************************/ /** State information for each device instance */ @@ -113,6 +123,8 @@ struct copybit_context_t { unsigned int trg_transform; /* target transform */ C2D_OBJECT blitState; void *libc2d2; + alloc_data temp_src_buffer; + alloc_data temp_dst_buffer; int g12_device_fd; int fb_width; int fb_height; @@ -130,12 +142,6 @@ struct bufferInfo { int format; }; -struct memInfo { - int fd; - size_t size; - int base; -}; - struct yuvPlaneInfo { int yStride; //luma stride int plane1_stride; @@ -175,15 +181,19 @@ struct copybit_module_t HAL_MODULE_INFO_SYM = { static int get_format(int format) { switch (format) { case HAL_PIXEL_FORMAT_RGB_565: return C2D_COLOR_FORMAT_565_RGB; - case HAL_PIXEL_FORMAT_RGBX_8888: return C2D_COLOR_FORMAT_8888_ARGB | C2D_FORMAT_SWAP_RB | C2D_FORMAT_DISABLE_ALPHA; - case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB | C2D_FORMAT_SWAP_RB; + case HAL_PIXEL_FORMAT_RGBX_8888: return C2D_COLOR_FORMAT_8888_ARGB | + C2D_FORMAT_SWAP_RB | + C2D_FORMAT_DISABLE_ALPHA; + case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB | + C2D_FORMAT_SWAP_RB; case HAL_PIXEL_FORMAT_BGRA_8888: return C2D_COLOR_FORMAT_8888_ARGB; case HAL_PIXEL_FORMAT_RGBA_5551: return C2D_COLOR_FORMAT_5551_RGBA; case HAL_PIXEL_FORMAT_RGBA_4444: return C2D_COLOR_FORMAT_4444_RGBA; case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV12; case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12; case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV21; - case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 | C2D_FORMAT_MACROTILED; + case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 | + C2D_FORMAT_MACROTILED; default: LOGE("%s: invalid format (0x%x", __FUNCTION__, format); return -EINVAL; } return -EINVAL; @@ -193,7 +203,8 @@ static int get_format(int format) { static int get_c2d_format_for_yuv_destination(int halFormat) { switch (halFormat) { // We do not swap the RB when the target is YUV - case HAL_PIXEL_FORMAT_RGBX_8888: return C2D_COLOR_FORMAT_8888_ARGB | C2D_FORMAT_DISABLE_ALPHA; + case HAL_PIXEL_FORMAT_RGBX_8888: return C2D_COLOR_FORMAT_8888_ARGB | + C2D_FORMAT_DISABLE_ALPHA; case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB; // The U and V need to be interchanged when the target is YUV case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV21; @@ -271,7 +282,8 @@ static uint32 c2d_get_gpuaddr(int device_fd, struct private_handle_t *handle) return 0; } - if (!ioctl(device_fd, IOCTL_KGSL_MAP_USER_MEM, (void *)¶m, sizeof(param))) { + if (!ioctl(device_fd, IOCTL_KGSL_MAP_USER_MEM, (void *)¶m, + sizeof(param))) { return param.gpuaddr; } @@ -285,7 +297,8 @@ static uint32 c2d_unmap_gpuaddr(int device_fd, unsigned int gpuaddr) memset(¶m, 0, sizeof(param)); param.gpuaddr = gpuaddr; - ioctl(device_fd, IOCTL_KGSL_SHAREDMEM_FREE, (void *)¶m, sizeof(param)); + ioctl(device_fd, IOCTL_KGSL_SHAREDMEM_FREE, (void *)¶m, + sizeof(param)); return COPYBIT_SUCCESS; } @@ -345,7 +358,8 @@ static int is_valid_destination_format(int format) return COPYBIT_SUCCESS; } -static int calculate_yuv_offset_and_stride(const bufferInfo& info, yuvPlaneInfo& yuvInfo) +static int calculate_yuv_offset_and_stride(const bufferInfo& info, + yuvPlaneInfo& yuvInfo) { int width = info.width; int height = info.height; @@ -389,8 +403,8 @@ static int calculate_yuv_offset_and_stride(const bufferInfo& info, yuvPlaneInfo& } /** create C2D surface from copybit image */ -static int set_image(int device_fd, uint32 surfaceId, const struct copybit_image_t *rhs, int *cformat, uint32_t *mapped, - const eC2DFlags flags) +static int set_image(int device_fd, uint32 surfaceId, const struct copybit_image_t *rhs, + int *cformat, uint32_t *mapped, const eC2DFlags flags) { struct private_handle_t* handle = (struct private_handle_t*)rhs->handle; C2D_SURFACE_TYPE surfaceType; @@ -431,7 +445,8 @@ static int set_image(int device_fd, uint32 surfaceId, const struct copybit_image surfaceDef.phys = (void*) handle->gpuaddr; surfaceDef.buffer = (void*) (handle->base); - surfaceDef.format = *cformat | ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0); + surfaceDef.format = *cformat | + ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0); surfaceDef.width = rhs->w; surfaceDef.height = rhs->h; int aligned_width = ALIGN(surfaceDef.width,32); @@ -475,7 +490,8 @@ static int set_image(int device_fd, uint32 surfaceId, const struct copybit_image surfaceDef.stride2 = yuvInfo.plane2_stride; } - if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, &surfaceDef)) { + if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, + &surfaceDef)) { LOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__); goto error; status = COPYBIT_FAILURE; @@ -497,7 +513,8 @@ error: return status; } -static int set_src_image(int device_fd, uint32 *surfaceId, const struct copybit_image_t *rhs, int *cformat, uint32 *mapped) +static int set_src_image(int device_fd, uint32 *surfaceId, const struct copybit_image_t *rhs, + int *cformat, uint32 *mapped) { struct private_handle_t* handle = (struct private_handle_t*)rhs->handle; *cformat = get_format(rhs->format); @@ -566,7 +583,8 @@ static int set_src_image(int device_fd, uint32 *surfaceId, const struct copybit_ surfaceDef.phys1 = (void*) (handle->gpuaddr + yuvInfo.plane1_offset); surfaceDef.stride1 = yuvInfo.plane1_stride; - if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET | C2D_SOURCE, surfaceType, (void*)&surfaceDef)) { + if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET | C2D_SOURCE, surfaceType, + (void*)&surfaceDef)) { LOGE("%s: YUV surface LINK_c2dCreateSurface error", __func__); status = COPYBIT_FAILURE; goto error; @@ -587,7 +605,8 @@ error: return status; } -void unset_image(int device_fd, uint32 surfaceId, const struct copybit_image_t *rhs, uint32 mmapped) +void unset_image(int device_fd, uint32 surfaceId, const struct copybit_image_t *rhs, + uint32 mmapped) { struct private_handle_t* handle = (struct private_handle_t*)rhs->handle; @@ -912,62 +931,43 @@ static size_t get_size(const bufferInfo& info) * allocated from Ashmem. It is the caller's responsibility to free this * memory. */ -static int get_temp_buffer(const bufferInfo& info, memInfo& mem_info) +static int get_temp_buffer(const bufferInfo& info, alloc_data& data) { - // Alloc memory from ashmem - int err = COPYBIT_SUCCESS; - size_t size = get_size(info); - char name[ASHMEM_NAME_LEN]; - snprintf(name, ASHMEM_NAME_LEN, "c2d-buffer-%x",mem_info); - int prot = PROT_READ | PROT_WRITE; - int fd = ashmem_create_region(name, size); - void *base = 0; - if (fd < 0) { - LOGE("%s: couldn't create ashmem (%s)", __FUNCTION__, - strerror(errno)); - return COPYBIT_FAILURE; - } else { - if (ashmem_set_prot_region(fd, prot) < 0) { - LOGE("%s: ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)", - __FUNCTION__, fd, prot, strerror(errno)); - close(fd); - fd = -1; - return COPYBIT_FAILURE; - } else { - base = mmap(0, size, prot, MAP_SHARED|MAP_POPULATE|MAP_LOCKED, fd, 0); - if (base == MAP_FAILED) { - LOGE("%s: alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)", - __FUNCTION__, fd, size, prot, strerror(errno)); - close(fd); - fd = -1; - return COPYBIT_FAILURE; - } - } - } - if (ioctl(fd, ASHMEM_CACHE_INV_RANGE, NULL)) { - LOGE("ASHMEM_CACHE_INV_RANGE failed fd = %d", fd); + LOGD("%s E", __FUNCTION__); + // Alloc memory from system heap + data.base = 0; + data.fd = -1; + data.offset = 0; + data.size = get_size(info); + data.align = getpagesize(); + data.uncached = true; + int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP; + + if (sAlloc == 0) { + sAlloc = gralloc::IAllocController::getInstance(false); } - // Save the memory info. - mem_info.fd = fd; - mem_info.size = size; - mem_info.base = (int)base; + if (sAlloc == 0) { + LOGE("%s: sAlloc is still NULL", __FUNCTION__); + return COPYBIT_FAILURE; + } + + int err = sAlloc->allocate(data, allocFlags, 0); + if (0 != err) { + LOGE("%s: allocate failed", __FUNCTION__); + return COPYBIT_FAILURE; + } + + LOGD("%s X", __FUNCTION__); return err; } /* Function to free the temporary allocated memory.*/ -static void free_temp_image(private_handle_t *hnd) +static void free_temp_buffer(alloc_data &data) { - if (hnd) { - if (0 != hnd->base) { - munmap((void *)hnd->base, hnd->size); - hnd->base = 0; - } - - if (hnd->fd != -1) { - close(hnd->fd); - hnd->fd = -1; - } + if (-1 != data.fd) { + sp memalloc = sAlloc->getAllocator(data.allocType); + memalloc->free_buffer(data.base, data.size, 0, data.fd); } } @@ -1087,7 +1087,6 @@ static int stretch_copybit_internal( // width is not aligned to 32. This case occurs for YUV formats. RGB formats are // aligned to 32. bool needTempDestination = need_temp_buffer(dst); - memInfo mem_info; bufferInfo dst_info; populate_buffer_info(dst, dst_info); private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format, @@ -1097,29 +1096,32 @@ static int stretch_copybit_internal( return COPYBIT_FAILURE; } if (needTempDestination) { - // Create a temp buffer and set that as the destination. - if (COPYBIT_SUCCESS == get_temp_buffer(dst_info, mem_info)) { - dst_hnd->fd = mem_info.fd; - dst_hnd->size = mem_info.size; - dst_hnd->flags = private_handle_t::PRIV_FLAGS_USES_ASHMEM; - dst_hnd->base = mem_info.base; - dst_hnd->offset = 0; - dst_hnd->gpuaddr = 0; - dst_image.handle = dst_hnd; + if (get_size(dst_info) != ctx->temp_dst_buffer.size) { + free_temp_buffer(ctx->temp_dst_buffer); + // Create a temp buffer and set that as the destination. + if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) { + LOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__); + delete_handle(dst_hnd); + return COPYBIT_FAILURE; + } } + dst_hnd->fd = ctx->temp_dst_buffer.fd; + dst_hnd->size = ctx->temp_dst_buffer.size; + dst_hnd->flags = ctx->temp_dst_buffer.allocType; + dst_hnd->base = (int)(ctx->temp_dst_buffer.base); + dst_hnd->offset = ctx->temp_dst_buffer.offset; + dst_hnd->gpuaddr = 0; + dst_image.handle = dst_hnd; } int flags = 0; flags |= (ctx->isPremultipliedAlpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0; flags |= (isYUVDestination) ? FLAGS_YUV_DESTINATION : 0; - status = set_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], &dst_image, &cformat, - &trg_mapped, (eC2DFlags)flags); + status = set_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], &dst_image, + &cformat, &trg_mapped, (eC2DFlags)flags); if(status) { LOGE("%s: dst: set_image error", __FUNCTION__); - if (needTempDestination) { - free_temp_image(dst_hnd); - } delete_handle(dst_hnd); return COPYBIT_FAILURE; } @@ -1135,17 +1137,11 @@ static int stretch_copybit_internal( } else { LOGE("%s: src number of YUV planes is invalid src format = 0x%x", __FUNCTION__, src->format); - if (needTempDestination) { - free_temp_image(dst_hnd); - } delete_handle(dst_hnd); return -EINVAL; } } else { LOGE("%s: Invalid source surface format 0x%x", __FUNCTION__, src->format); - if (needTempDestination) { - free_temp_image(dst_hnd); - } delete_handle(dst_hnd); return -EINVAL; } @@ -1163,51 +1159,46 @@ static int stretch_copybit_internal( src_info.width, src_info.height); if (NULL == src_hnd) { LOGE("%s: src_hnd is null", __FUNCTION__); - if (needTempDestination) { - free_temp_image(dst_hnd); - } delete_handle(dst_hnd); return COPYBIT_FAILURE; } if (needTempSource) { - // Create a temp buffer and set that as the destination. - if (COPYBIT_SUCCESS == get_temp_buffer(src_info, mem_info)) { - src_hnd->fd = mem_info.fd; - src_hnd->size = mem_info.size; - src_hnd->flags = private_handle_t::PRIV_FLAGS_USES_ASHMEM; - src_hnd->base = mem_info.base; - src_hnd->offset = 0; - src_hnd->gpuaddr = 0; - src_image.handle = src_hnd; - - // Copy the source. - copy_image((private_handle_t *)src->handle, &src_image, CONVERT_TO_C2D_FORMAT); - - // Flush the cache - if (ioctl(src_hnd->fd, ASHMEM_CACHE_FLUSH_RANGE, NULL)) { - LOGE("%s: ASHMEM_CACHE_FLUSH_RANGE failed (error=%s)", - __FUNCTION__, strerror(errno)); - if (needTempDestination) { - free_temp_image(dst_hnd); - } - free_temp_image(src_hnd); + if (get_size(src_info) != ctx->temp_src_buffer.size) { + free_temp_buffer(ctx->temp_src_buffer); + // Create a temp buffer and set that as the destination. + if (COPYBIT_SUCCESS != get_temp_buffer(src_info, ctx->temp_src_buffer)) { + LOGE("%s: get_temp_buffer(src) failed", __FUNCTION__); delete_handle(dst_hnd); delete_handle(src_hnd); return COPYBIT_FAILURE; } } + src_hnd->fd = ctx->temp_src_buffer.fd; + src_hnd->size = ctx->temp_src_buffer.size; + src_hnd->flags = ctx->temp_src_buffer.allocType; + src_hnd->base = (int)(ctx->temp_src_buffer.base); + src_hnd->offset = ctx->temp_src_buffer.offset; + src_hnd->gpuaddr = 0; + src_image.handle = src_hnd; + + // Copy the source. + copy_image((private_handle_t *)src->handle, &src_image, CONVERT_TO_C2D_FORMAT); + + // Flush the cache + sp memalloc = sAlloc->getAllocator(src_hnd->flags); + if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size, + src_hnd->offset, src_hnd->fd)) { + LOGE("%s: clean_buffer failed", __FUNCTION__); + delete_handle(dst_hnd); + delete_handle(src_hnd); + return COPYBIT_FAILURE; + } } - status = set_image(ctx->g12_device_fd, ctx->src[src_surface_index], &src_image, &cformat, - &src_mapped, (eC2DFlags)flags); + status = set_image(ctx->g12_device_fd, ctx->src[src_surface_index], &src_image, + &cformat, &src_mapped, (eC2DFlags)flags); if(status) { LOGE("%s: set_src_image error", __FUNCTION__); - if (needTempDestination) { - free_temp_image(dst_hnd); - } - if (needTempSource) { - free_temp_image(src_hnd); - } delete_handle(dst_hnd); delete_handle(src_hnd); return COPYBIT_FAILURE; @@ -1218,14 +1209,10 @@ static int stretch_copybit_internal( ctx->blitState.config_mask &= ~C2D_ALPHA_BLEND_NONE; if(!(ctx->blitState.global_alpha)) { // src alpha is zero - unset_image(ctx->g12_device_fd, ctx->src[src_surface_index], &src_image, src_mapped); - unset_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], &dst_image, trg_mapped); - if (needTempDestination) { - free_temp_image(dst_hnd); - } - if (needTempSource) { - free_temp_image(src_hnd); - } + unset_image(ctx->g12_device_fd, ctx->src[src_surface_index], + &src_image, src_mapped); + unset_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], + &dst_image, trg_mapped); delete_handle(dst_hnd); delete_handle(src_hnd); return status; @@ -1261,17 +1248,17 @@ static int stretch_copybit_internal( LOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__); } - unset_image(ctx->g12_device_fd, ctx->src[src_surface_index], &src_image, src_mapped); - unset_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], &dst_image, trg_mapped); + unset_image(ctx->g12_device_fd, ctx->src[src_surface_index], &src_image, + src_mapped); + unset_image(ctx->g12_device_fd, ctx->dst[dst_surface_index], &dst_image, + trg_mapped); if (needTempDestination) { // copy the temp. destination without the alignment to the actual destination. copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT); - // Free the temp memory. - free_temp_image(dst_hnd); - } - if (needTempSource) { - // Free the temp memory. - free_temp_image(src_hnd); + // Invalidate the cache. + sp memalloc = sAlloc->getAllocator(dst_hnd->flags); + memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size, + dst_hnd->offset, dst_hnd->fd); } delete_handle(dst_hnd); delete_handle(src_hnd); @@ -1323,6 +1310,9 @@ static int close_copybit(struct hw_device_t *dev) if(ctx->g12_device_fd) close(ctx->g12_device_fd); + + free_temp_buffer(ctx->temp_src_buffer); + free_temp_buffer(ctx->temp_dst_buffer); free(ctx); } @@ -1432,17 +1422,19 @@ static int open_copybit(const struct hw_module_t* module, const char* name, yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa; yuvSurfaceDef.stride1 = 4; - if (LINK_c2dCreateSurface(&(ctx->src[YUV_SURFACE_2_PLANES]),C2D_TARGET | C2D_SOURCE, - (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), - &yuvSurfaceDef)) { + if (LINK_c2dCreateSurface(&(ctx->src[YUV_SURFACE_2_PLANES]), + C2D_TARGET | C2D_SOURCE, + (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST|C2D_SURFACE_WITH_PHYS), + &yuvSurfaceDef)) { LOGE("%s: create ctx->src[YUV_SURFACE_2_PLANES] failed", __FUNCTION__); ctx->src[YUV_SURFACE_2_PLANES] = -1; goto error; } - if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),C2D_TARGET | C2D_SOURCE, - (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), - &yuvSurfaceDef)) { + if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]), + C2D_TARGET | C2D_SOURCE, + (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), + &yuvSurfaceDef)) { LOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__); ctx->dst[YUV_SURFACE_2_PLANES] = -1; goto error; @@ -1453,25 +1445,36 @@ static int open_copybit(const struct hw_module_t* module, const char* name, yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa; yuvSurfaceDef.stride2 = 4; - if (LINK_c2dCreateSurface(&(ctx->src[YUV_SURFACE_3_PLANES]),C2D_TARGET | C2D_SOURCE, - (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), - &yuvSurfaceDef)) { + if (LINK_c2dCreateSurface(&(ctx->src[YUV_SURFACE_3_PLANES]), + C2D_TARGET | C2D_SOURCE, + (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), + &yuvSurfaceDef)) { LOGE("%s: create ctx->src[YUV_SURFACE_3_PLANES] failed", __FUNCTION__); ctx->src[YUV_SURFACE_3_PLANES] = -1; goto error; } - if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),C2D_TARGET | C2D_SOURCE, - (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), - &yuvSurfaceDef)) { + if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]), + C2D_TARGET | C2D_SOURCE, + (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS), + &yuvSurfaceDef)) { LOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__); ctx->dst[YUV_SURFACE_3_PLANES] = -1; goto error; } + ctx->temp_src_buffer.fd = -1; + ctx->temp_src_buffer.base = 0; + ctx->temp_src_buffer.size = 0; + + ctx->temp_dst_buffer.fd = -1; + ctx->temp_dst_buffer.base = 0; + ctx->temp_dst_buffer.size = 0; + ctx->fb_width = 0; ctx->fb_height = 0; ctx->isPremultipliedAlpha = false; + *device = &ctx->device.common; return status; From 5312f7f48eab0ef934d4e59e35d99a59f896fc6a Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Tue, 13 Dec 2011 19:41:03 -0800 Subject: [PATCH 2/8] Display: Add support in libqcomui to check FB update This change adds support in libqcomui to check if FB is updated by a composition type Change-Id: Ic23f24d95166cb9b1a03614f1c0fd562f321a1fd --- libhwcomposer/hwcomposer.cpp | 6 ------ libqcomui/qcom_ui.cpp | 20 ++++++++++++++++++++ libqcomui/qcom_ui.h | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp index 517ae82..5eec149 100755 --- a/libhwcomposer/hwcomposer.cpp +++ b/libhwcomposer/hwcomposer.cpp @@ -54,12 +54,6 @@ enum { COMPOSITION_TYPE_DYN = 0x8 }; -enum HWCCompositionType { - HWC_USE_GPU = HWC_FRAMEBUFFER, // This layer is to be handled by Surfaceflinger - HWC_USE_OVERLAY = HWC_OVERLAY, // This layer is to be handled by the overlay - HWC_USE_COPYBIT // This layer is to be handled by copybit -}; - enum HWCLayerType{ HWC_SINGLE_VIDEO = 0x1, HWC_ORIG_RESOLUTION = 0x2, diff --git a/libqcomui/qcom_ui.cpp b/libqcomui/qcom_ui.cpp index 9de00e7..24995e6 100644 --- a/libqcomui/qcom_ui.cpp +++ b/libqcomui/qcom_ui.cpp @@ -291,3 +291,23 @@ int getPerFrameFlags(int hwclFlags, int layerFlags) { return flags; } + +/* + * Checks if FB is updated by this composition type + * + * @param: composition type + * @return: true if FB is updated, false if not + */ + +bool isUpdatingFB(HWCCompositionType compositionType) +{ + switch(compositionType) + { + case HWC_USE_COPYBIT: + return true; + default: + LOGE("%s: invalid composition type(%d)", __FUNCTION__, compositionType); + return false; + }; +} + diff --git a/libqcomui/qcom_ui.h b/libqcomui/qcom_ui.h index 6744edf..0909365 100644 --- a/libqcomui/qcom_ui.h +++ b/libqcomui/qcom_ui.h @@ -32,6 +32,7 @@ #include #include +#include using android::sp; using android::GraphicBuffer; @@ -68,6 +69,12 @@ enum { HWC_COMP_BYPASS = 0x40000000, }; +enum HWCCompositionType { + HWC_USE_GPU = HWC_FRAMEBUFFER, // This layer is to be handled by Surfaceflinger + HWC_USE_OVERLAY = HWC_OVERLAY, // This layer is to be handled by the overlay + HWC_USE_COPYBIT // This layer is to be handled by copybit +}; + /* * Structure to hold the buffer geometry */ @@ -155,4 +162,13 @@ int updateLayerQcomFlags(eLayerAttrib attribute, bool enable, int& currentFlags) */ int getPerFrameFlags(int hwclFlags, int layerFlags); +/* + * Checks if FB is updated by this composition type + * + * @param: composition type + * @return: true if FB is updated, false if not + */ + +bool isUpdatingFB(HWCCompositionType compositionType); + #endif // INCLUDE_LIBQCOM_UI From 996254486f2fd503ca07f54b4191c6bde71fe9c0 Mon Sep 17 00:00:00 2001 From: Naomi Luis Date: Fri, 16 Dec 2011 10:44:48 -0800 Subject: [PATCH 3/8] libgralloc: Check for genlock success on all genlock calls Change-Id: I5bb9d209f80c6b9499197cda697d1a0293b409ba --- libgralloc/mapper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp index 2cecbd5..5eaa0fe 100755 --- a/libgralloc/mapper.cpp +++ b/libgralloc/mapper.cpp @@ -152,7 +152,7 @@ int gralloc_register_buffer(gralloc_module_t const* module, } // Attach the genlock handle - if (GENLOCK_FAILURE == genlock_attach_lock((native_handle_t *)handle)) { + if (GENLOCK_NO_ERROR != genlock_attach_lock((native_handle_t *)handle)) { LOGE("%s: genlock_attach_lock failed", __FUNCTION__); gralloc_unmap(module, handle); hnd->base = 0; @@ -252,7 +252,7 @@ int gralloc_lock(gralloc_module_t const* module, } int timeout = GENLOCK_MAX_TIMEOUT; - if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t *)handle, + if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)handle, (genlock_lock_type)lockType, timeout)) { LOGE("%s: genlock_lock_buffer (lockType=0x%x) failed", __FUNCTION__, @@ -292,7 +292,7 @@ int gralloc_unlock(gralloc_module_t const* module, if ((hnd->flags & private_handle_t::PRIV_FLAGS_SW_LOCK)) { // Unlock the buffer. - if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)handle)) { + if (GENLOCK_NO_ERROR != genlock_unlock_buffer((native_handle_t *)handle)) { LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); return -EINVAL; } else From eae32cda026d4550245b5bd38d77734ae14005be Mon Sep 17 00:00:00 2001 From: toastcfh Date: Thu, 22 Dec 2011 21:51:22 -0500 Subject: [PATCH 4/8] display: use some cm specific build flags and fix up cflags for qcom hardware Change-Id: I3e39bbb522313d4bafd97cd205411f32a992a697 --- Android.mk | 2 +- libgenlock/Android.mk | 2 +- libgralloc/Android.mk | 4 ++-- libhwcomposer/Android.mk | 5 +++-- libtilerenderer/Android.mk | 1 + 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Android.mk b/Android.mk index d7111c0..52d3bbd 100644 --- a/Android.mk +++ b/Android.mk @@ -1,7 +1,7 @@ #Enables the listed display HAL modules ifeq ($(BOARD_USES_QCOM_HARDWARE),true) - display-hals := libhwcomposer liboverlay libgralloc libcopybit + display-hals := libhwcomposer liboverlay libgralloc libcopybit libgenlock libtilerenderer display-hals += libqcomui include $(call all-named-subdir-makefiles,$(display-hals)) endif diff --git a/libgenlock/Android.mk b/libgenlock/Android.mk index 2ac565e..09b8a64 100644 --- a/libgenlock/Android.mk +++ b/libgenlock/Android.mk @@ -9,7 +9,7 @@ LOCAL_SRC_FILES := genlock.cpp LOCAL_CFLAGS:= -DLOG_TAG=\"libgenlock\" LOCAL_MODULE_TAGS := optional -ifeq ($(BOARD_USES_GENLOCK),true) +ifeq ($(TARGET_USES_GENLOCK),true) LOCAL_CFLAGS += -DUSE_GENLOCK endif diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk index 7820499..05dc53f 100755 --- a/libgralloc/Android.mk +++ b/libgralloc/Android.mk @@ -36,8 +36,8 @@ ifeq ($(call is-board-platform,msm7x27),true) LOCAL_CFLAGS += -DTARGET_MSM7x27 endif -ifeq ($(TARGET_HAVE_HDMI_OUT),true) - LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY +ifeq ($(TARGET_QCOM_HDMI_OUT),true) + LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY -DQCOM_HDMI_OUT LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay LOCAL_SHARED_LIBRARIES += liboverlay endif diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk index fd1a761..6b91df9 100755 --- a/libhwcomposer/Android.mk +++ b/libhwcomposer/Android.mk @@ -13,6 +13,7 @@ LOCAL_SRC_FILES := \ LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM) LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).hwcomposer\" +LOCAL_CFLAGS += -DQCOM_HARDWARE LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay @@ -20,8 +21,8 @@ LOCAL_C_INCLUDES += hardware/qcom/display/libcopybit LOCAL_C_INCLUDES += hardware/qcom/display/libgenlock LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui -ifeq ($(TARGET_HAVE_HDMI_OUT),true) -LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY +ifeq ($(TARGET_QCOM_HDMI_OUT),true) +LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY -DQCOM_HDMI_OUT endif ifeq ($(TARGET_USES_OVERLAY),true) LOCAL_CFLAGS += -DUSE_OVERLAY diff --git a/libtilerenderer/Android.mk b/libtilerenderer/Android.mk index e0bf342..588b684 100644 --- a/libtilerenderer/Android.mk +++ b/libtilerenderer/Android.mk @@ -20,6 +20,7 @@ LOCAL_C_INCLUDES += \ LOCAL_SRC_FILES := \ tilerenderer.cpp +LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DQCOM_HARDWARE LOCAL_MODULE := libtilerenderer LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) From 4438e2f942abff3f6fbf3ef170faa85b85c04495 Mon Sep 17 00:00:00 2001 From: Naomi Luis Date: Mon, 19 Dec 2011 11:40:05 -0800 Subject: [PATCH 5/8] libQcomUI: Implement clearRegion for C2D/MDP/CPU composition. Implement clearRegion for C2D/MDP/CPU composition. This prevents glClear and therefore the glFinish from being called, thus improving performance. Change-Id: I03d9230e03cce11d9fe7e2bd34e4df8328ad2e00 --- libhwcomposer/hwcomposer.cpp | 9 ---- libqcomui/Android.mk | 3 +- libqcomui/qcom_ui.cpp | 96 ++++++++++++++++++++++++++++++++++++ libqcomui/qcom_ui.h | 29 +++++++++++ 4 files changed, 127 insertions(+), 10 deletions(-) diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp index 5eec149..d41c5f2 100755 --- a/libhwcomposer/hwcomposer.cpp +++ b/libhwcomposer/hwcomposer.cpp @@ -45,15 +45,6 @@ #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) -// Enum containing the supported composition types -enum { - COMPOSITION_TYPE_GPU = 0, - COMPOSITION_TYPE_MDP = 0x1, - COMPOSITION_TYPE_C2D = 0x2, - COMPOSITION_TYPE_CPU = 0x4, - COMPOSITION_TYPE_DYN = 0x8 -}; - enum HWCLayerType{ HWC_SINGLE_VIDEO = 0x1, HWC_ORIG_RESOLUTION = 0x2, diff --git a/libqcomui/Android.mk b/libqcomui/Android.mk index 2b786d9..11b9909 100644 --- a/libqcomui/Android.mk +++ b/libqcomui/Android.mk @@ -8,7 +8,8 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libcutils \ libmemalloc \ - libui + libui \ + libEGL LOCAL_C_INCLUDES := $(TOP)/hardware/qcom/display/libgralloc \ LOCAL_CFLAGS := -DLOG_TAG=\"libQcomUI\" diff --git a/libqcomui/qcom_ui.cpp b/libqcomui/qcom_ui.cpp index 24995e6..f1cd7aa 100644 --- a/libqcomui/qcom_ui.cpp +++ b/libqcomui/qcom_ui.cpp @@ -28,17 +28,22 @@ */ #include +#include #include #include #include #include #include +#include +#include using gralloc::IMemAlloc; using gralloc::IonController; using gralloc::alloc_data; using android::sp; +static int sCompositionType = -1; + namespace { static android::sp sAlloc = 0; @@ -311,3 +316,94 @@ bool isUpdatingFB(HWCCompositionType compositionType) }; } +/* + * Get the current composition Type + * + * @return the compositon Type + */ +int getCompositionType() { + char property[PROPERTY_VALUE_MAX]; + int compositionType = 0; + if (property_get("debug.sf.hw", property, NULL) > 0) { + if(atoi(property) == 0) { + compositionType = COMPOSITION_TYPE_CPU; + } else { //debug.sf.hw = 1 + property_get("debug.composition.type", property, NULL); + if (property == NULL) { + compositionType = COMPOSITION_TYPE_GPU; + } else if ((strncmp(property, "mdp", 3)) == 0) { + compositionType = COMPOSITION_TYPE_MDP; + } else if ((strncmp(property, "c2d", 3)) == 0) { + compositionType = COMPOSITION_TYPE_C2D; + } else if ((strncmp(property, "dyn", 3)) == 0) { + compositionType = COMPOSITION_TYPE_DYN; + } else { + compositionType = COMPOSITION_TYPE_GPU; + } + } + } else { //debug.sf.hw is not set. Use cpu composition + compositionType = COMPOSITION_TYPE_CPU; + } + return compositionType; +} + +/* + * Clear Region implementation for C2D/MDP versions. + * + * @param: region to be cleared + * @param: EGL Display + * @param: EGL Surface + * + * @return 0 on success + */ +int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur) +{ + int ret = 0; + + if (-1 == sCompositionType) { + sCompositionType = getCompositionType(); + } + + if ((COMPOSITION_TYPE_MDP != sCompositionType) && + (COMPOSITION_TYPE_C2D != sCompositionType) && + (COMPOSITION_TYPE_CPU != sCompositionType)) { + // For non CPU/C2D/MDP composition, return an error, so that SF can use + // the GPU to draw the wormhole. + return -1; + } + + android_native_buffer_t *renderBuffer = (android_native_buffer_t *) + eglGetRenderBufferANDROID(dpy, sur); + if (!renderBuffer) { + LOGE("%s: eglGetRenderBufferANDROID returned NULL buffer", + __FUNCTION__); + return -1; + } + private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle; + if(!fbHandle) { + LOGE("%s: Framebuffer handle is NULL", __FUNCTION__); + return -1; + } + + int bytesPerPixel = 4; + if (HAL_PIXEL_FORMAT_RGB_565 == fbHandle->format) { + bytesPerPixel = 2; + } + + Region::const_iterator it = region.begin(); + Region::const_iterator const end = region.end(); + const int32_t stride = renderBuffer->stride*bytesPerPixel; + while (it != end) { + const Rect& r = *it++; + uint8_t* dst = (uint8_t*) fbHandle->base + + (r.left + r.top*renderBuffer->stride)*bytesPerPixel; + int w = r.width()*bytesPerPixel; + int h = r.height(); + do { + android_memset32((uint32_t*)dst, 0, w); + dst += stride; + } while(--h); + } + + return 0; +} diff --git a/libqcomui/qcom_ui.h b/libqcomui/qcom_ui.h index 0909365..d54280e 100644 --- a/libqcomui/qcom_ui.h +++ b/libqcomui/qcom_ui.h @@ -33,7 +33,10 @@ #include #include #include +#include +#include +using namespace android; using android::sp; using android::GraphicBuffer; @@ -45,6 +48,15 @@ enum { NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY = 0x20000000, }; +// Enum containing the supported composition types +enum { + COMPOSITION_TYPE_GPU = 0, + COMPOSITION_TYPE_MDP = 0x1, + COMPOSITION_TYPE_C2D = 0x2, + COMPOSITION_TYPE_CPU = 0x4, + COMPOSITION_TYPE_DYN = 0x8 +}; + /* * Layer Attributes */ @@ -171,4 +183,21 @@ int getPerFrameFlags(int hwclFlags, int layerFlags); bool isUpdatingFB(HWCCompositionType compositionType); +/* + * Get the current composition Type + * + * @return the compositon Type + */ +int getCompositionType(); + +/* + * Clear region implementation for C2D/MDP versions. + * + * @param: region to be cleared + * @param: EGL Display + * @param: EGL Surface + * + * @return 0 on success + */ +int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur); #endif // INCLUDE_LIBQCOM_UI From 7abeff1de334fe9aacaca30134776ee58c389173 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 14 Dec 2011 23:33:12 -0800 Subject: [PATCH 6/8] Display: Use bitwise operators on HWC flags Change-Id: I031a6510622a1e768651bcd91d3ab6f399fc81f1 --- libhwcomposer/hwcomposer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp index d41c5f2..f83901c 100755 --- a/libhwcomposer/hwcomposer.cpp +++ b/libhwcomposer/hwcomposer.cpp @@ -303,7 +303,7 @@ static int prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer, const bool wai return -1; } - if (layer->flags == HWC_USE_ORIGINAL_RESOLUTION) { + if (layer->flags & HWC_USE_ORIGINAL_RESOLUTION) { framebuffer_device_t* fbDev = hwcModule->fbDevice; ret = ovLibObject->setPosition(0, 0, fbDev->width, fbDev->height); @@ -619,7 +619,7 @@ bool setupBypass(hwc_context_t* ctx, hwc_layer_list_t* list) { void setBypassLayerFlags(hwc_context_t* ctx, hwc_layer_list_t* list) { for (int index = 0 ; index < list->numHwLayers; index++) { - list->hwLayers[index].flags = HWC_COMP_BYPASS; + list->hwLayers[index].flags |= HWC_COMP_BYPASS; list->hwLayers[index].compositionType = HWC_USE_OVERLAY; #ifdef DEBUG LOGE("%s: layer = %d", __FUNCTION__, index); @@ -629,7 +629,7 @@ void setBypassLayerFlags(hwc_context_t* ctx, hwc_layer_list_t* list) { void unsetBypassLayerFlags(hwc_layer_list_t* list) { for (int index = 0 ; index < list->numHwLayers; index++) { - if(list->hwLayers[index].flags == HWC_COMP_BYPASS) { + if(list->hwLayers[index].flags & HWC_COMP_BYPASS) { list->hwLayers[index].flags = 0; } } @@ -644,7 +644,7 @@ void unsetBypassBufferLockState(hwc_context_t* ctx) { void storeLockedBypassHandle(hwc_layer_list_t* list, hwc_context_t* ctx) { for (int index = 0 ; index < list->numHwLayers; index++) { // Store the current bypass handle. - if (list->hwLayers[index].flags == HWC_COMP_BYPASS) { + if (list->hwLayers[index].flags & HWC_COMP_BYPASS) { private_handle_t *hnd = (private_handle_t*)list->hwLayers[index].handle; if (ctx->bypassBufferLockState[index] == BYPASS_BUFFER_LOCKED) { ctx->previousBypassHandle[index] = (native_handle_t*)list->hwLayers[index].handle; @@ -901,7 +901,7 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) { } } else if (isS3DCompositionNeeded) { markUILayerForS3DComposition(list->hwLayers[i], s3dVideoFormat); - } else if (list->hwLayers[i].flags == HWC_USE_ORIGINAL_RESOLUTION) { + } else if (list->hwLayers[i].flags & HWC_USE_ORIGINAL_RESOLUTION) { list->hwLayers[i].compositionType = HWC_USE_OVERLAY; list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB; layerType |= HWC_ORIG_RESOLUTION; @@ -1154,10 +1154,10 @@ static int hwc_set(hwc_composer_device_t *dev, int ret = 0; for (size_t i=0; inumHwLayers; i++) { - if (list->hwLayers[i].flags == HWC_SKIP_LAYER) { + if (list->hwLayers[i].flags & HWC_SKIP_LAYER) { continue; #ifdef COMPOSITION_BYPASS - } else if (list->hwLayers[i].flags == HWC_COMP_BYPASS) { + } else if (list->hwLayers[i].flags & HWC_COMP_BYPASS) { drawLayerUsingBypass(ctx, &(list->hwLayers[i]), i); #endif } else if (list->hwLayers[i].compositionType == HWC_USE_OVERLAY) { From 6db0f4732610b33ffb503b20619585d235af31da Mon Sep 17 00:00:00 2001 From: Neti Ravi Kumar Date: Fri, 23 Dec 2011 19:43:05 +0530 Subject: [PATCH 7/8] Display/libqcomUI:Check for the clip width limit clip width should not exceed with the render buffer width(fb0) Change-Id: Ia927dc1e709a259910ae8f9e7d37979306eb3437 --- libqcomui/qcom_ui.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libqcomui/qcom_ui.cpp b/libqcomui/qcom_ui.cpp index f1cd7aa..107827f 100644 --- a/libqcomui/qcom_ui.cpp +++ b/libqcomui/qcom_ui.cpp @@ -399,6 +399,10 @@ int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur) (r.left + r.top*renderBuffer->stride)*bytesPerPixel; int w = r.width()*bytesPerPixel; int h = r.height(); + if(((int)dst + w ) > (fbHandle->base + renderBuffer->stride*bytesPerPixel)){ + LOGE("%s: Excedding the framebuffer limit",__FUNCTION__ ) ; + return -1; + } do { android_memset32((uint32_t*)dst, 0, w); dst += stride; From ada9e68943604cdad396afb62e660644189fcd1a Mon Sep 17 00:00:00 2001 From: Neti Ravi Kumar Date: Fri, 23 Dec 2011 21:27:14 +0530 Subject: [PATCH 8/8] Display/libqcomUI:Choosing memset according to pixel format For 2 bytes per pixel format the width might be not alligned to 4 So for such cases we need to use memset16 Change-Id: I22a6c673439c44447ce33faf2ed0615febd70a28 --- libqcomui/qcom_ui.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libqcomui/qcom_ui.cpp b/libqcomui/qcom_ui.cpp index 107827f..58f4ffb 100644 --- a/libqcomui/qcom_ui.cpp +++ b/libqcomui/qcom_ui.cpp @@ -399,12 +399,11 @@ int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur) (r.left + r.top*renderBuffer->stride)*bytesPerPixel; int w = r.width()*bytesPerPixel; int h = r.height(); - if(((int)dst + w ) > (fbHandle->base + renderBuffer->stride*bytesPerPixel)){ - LOGE("%s: Excedding the framebuffer limit",__FUNCTION__ ) ; - return -1; - } do { - android_memset32((uint32_t*)dst, 0, w); + if(4 == bytesPerPixel) + android_memset32((uint32_t*)dst, 0, w); + else + android_memset16((uint16_t*)dst, 0, w); dst += stride; } while(--h); }