Merge "libgralloc: force 1M alignment for secure buffers"
diff --git a/libcopybit/c2d2.h b/libcopybit/c2d2.h
index 8c7d05b..886f38a 100644
--- a/libcopybit/c2d2.h
+++ b/libcopybit/c2d2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -9,7 +9,7 @@
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
- * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * * Neither the name of The Linux Foundation. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -232,6 +232,7 @@
C2D_DRAW_LINE_NOLAST = (1 << 17), /* disable last pixel draw for line */
} C2D_SOURCE_CONFIG;
+
/* Target configuration bits, defines rotation + mirroring.
* Mirror is applied prior to rotation if enabled. */
typedef enum {
@@ -273,6 +274,18 @@
C2D_ALPHA_BLEND_NONE = (1 << 25), /* disables alpha blending */
} C2D_ALPHA_BLEND_MODE;
+/* Configuration bits, used in the config_mask field of C2D_OBJECT struct */
+typedef enum {
+ C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG = (1 << 27), /* Overrides TARGET Config */
+ C2D_OVERRIDE_TARGET_ROTATE_0 = (0 << 28), /* no rotation */
+ C2D_OVERRIDE_TARGET_ROTATE_90 = (1 << 28), /* 90 degree rotation */
+ C2D_OVERRIDE_TARGET_ROTATE_180 = (2 << 28), /* 180 degree rotation */
+ C2D_OVERRIDE_TARGET_ROTATE_270 = (3 << 28), /* 270 degree rotation */
+} C2D_SOURCE_TARGET_CONFIG;
+
+#define C2D_OVERRIDE_SOURCE_CONFIG_TARGET_ROTATION_SHIFT_MASK 28
+#define C2D_OVERRIDE_TARGET_CONFIG_TARGET_ROTATION_SHIFT_MASK 2
+
/* Surface caps enumeration */
typedef enum {
@@ -375,6 +388,51 @@
struct C2D_OBJECT_STR *next; /* pointer to the next object or NULL */
} C2D_OBJECT;
+/* Configuration bits, driver capabilities used by 2Dapplications */
+typedef enum {
+ C2D_DRIVER_SUPPORTS_GLOBAL_ALPHA_OP = (1 << 0),
+ C2D_DRIVER_SUPPORTS_TILE_OP = (1 << 1),
+ C2D_DRIVER_SUPPORTS_COLOR_KEY_OP = (1 << 2),
+ C2D_DRIVER_SUPPORTS_NO_PIXEL_ALPHA_OP = (1 << 3),
+ C2D_DRIVER_SUPPORTS_TARGET_ROTATE_OP = (1 << 4),
+ C2D_DRIVER_SUPPORTS_ANTI_ALIASING_OP = (1 << 5), /* antialiasing */
+ C2D_DRIVER_SUPPORTS_BILINEAR_FILTER_OP = (1 << 6),
+ C2D_DRIVER_SUPPORTS_LENS_CORRECTION_OP = (1 << 7),
+ C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP = (1 << 8),
+ C2D_DRIVER_SUPPORTS_SHADER_BLOB_OP = (1 << 9),
+ C2D_DRIVER_SUPPORTS_MASK_SURFACE_OP = (1 << 10), /* mask surface */
+ C2D_DRIVER_SUPPORTS_MIRROR_H_OP = (1 << 11), /* horizontal flip */
+ C2D_DRIVER_SUPPORTS_MIRROR_V_OP = (1 << 12), /* vertical flip */
+ C2D_DRIVER_SUPPORTS_SCISSOR_RECT_OP = (1 << 13),
+ C2D_DRIVER_SUPPORTS_SOURCE_RECT_OP = (1 << 14),
+ C2D_DRIVER_SUPPORTS_TARGET_RECT_OP = (1 << 15),
+ C2D_DRIVER_SUPPORTS_ROTATE_OP = (1 << 16), /* all rotations */
+ C2D_DRIVER_SUPPORTS_FLUSH_WITH_FENCE_FD_OP = (1 << 17), /* all rotations */
+ C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP = ((0xFFFFFFFF) >> (31 - 17)) /* mask for all capabilities supported */
+} C2D_DRIVER_CAPABILITIES;
+
+/* 2D driver workaround bits used by the 2D applications */
+typedef enum {
+ C2D_DRIVER_WORKAROUND_NONE = 0, /* NO workaround */
+ C2D_DRIVER_WORKAROUND_SWAP_UV_FOR_YUV_TARGET = (1 << 0), /* Swap UV when this flag set */
+} C2D_DRIVER_WORKAROUND;
+
+/* Structure to query Driver information */
+typedef struct {
+ uint32 capabilities_mask;
+ uint32 workaround_mask;
+ uint32 reserved1;
+ uint32 reserved2;
+ uint32 reserved3;
+} C2D_DRIVER_INFO;
+
+/* Structure to query Driver information */
+typedef struct {
+ uint32 max_surface_template_needed;
+ uint32 reserved1;
+ uint32 reserved2;
+ uint32 reserved3;
+} C2D_DRIVER_SETUP_INFO;
/*****************************************************************************/
/**************************** C2D API 2.0 ********************************/
@@ -609,6 +667,13 @@
* gpaddr is the gpuaddr to unmap */
C2D_API C2D_STATUS c2dUnMapAddr (void * gpuaddr);
+/* allows user to query driver capabilities.
+ * driver_info is the information about driver */
+C2D_API C2D_STATUS c2dGetDriverCapabilities( C2D_DRIVER_INFO * driver_info);
+
+/* create a fence fd for the timestamp */
+C2D_API C2D_STATUS c2dCreateFenceFD( uint32 target_id, c2d_ts_handle timestamp, int32 *fd);
+
/*****************************************************************************/
#ifdef __cplusplus
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 773e9b8..ed302f1 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -1,6 +1,9 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010 - 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -129,6 +132,7 @@
case HAL_PIXEL_FORMAT_YCbCr_422_SP: return MDP_Y_CRCB_H2V1;
case HAL_PIXEL_FORMAT_YCbCr_420_SP: return MDP_Y_CRCB_H2V2;
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
}
return -1;
}
@@ -313,10 +317,10 @@
ctx->mFlags &= ~MDP_BLUR;
}
break;
- case COPYBIT_PREMULTIPLIED_ALPHA:
- if(value == COPYBIT_ENABLE) {
+ case COPYBIT_BLEND_MODE:
+ if(value == COPYBIT_BLENDING_PREMULT) {
ctx->mFlags |= MDP_BLEND_FG_PREMULT;
- } else if (value == COPYBIT_DISABLE) {
+ } else {
ctx->mFlags &= ~MDP_BLEND_FG_PREMULT;
}
break;
@@ -403,8 +407,8 @@
}
}
- if (src_rect->l < 0 || src_rect->r > (int)src->w ||
- src_rect->t < 0 || src_rect->b > (int)src->h) {
+ if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w ||
+ src_rect->t < 0 || (uint32_t)src_rect->b > src->h) {
// this is always invalid
ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\
__FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b);
@@ -423,7 +427,8 @@
}
if(src->format == HAL_PIXEL_FORMAT_YV12) {
- int usage = GRALLOC_USAGE_PRIVATE_MM_HEAP;
+ int usage =
+ GRALLOC_USAGE_PRIVATE_CAMERA_HEAP|GRALLOC_USAGE_PRIVATE_UNCACHED;
if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
src->format, usage)){
if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
@@ -501,6 +506,11 @@
return stretch_copybit(dev, dst, src, &dr, &sr, region);
}
+static int finish_copybit(struct copybit_device_t *dev)
+{
+ // NOP for MDP copybit
+}
+
/*****************************************************************************/
/** Close the copybit device */
@@ -531,6 +541,7 @@
ctx->device.get = get;
ctx->device.blit = blit_copybit;
ctx->device.stretch = stretch_copybit;
+ ctx->device.finish = finish_copybit;
ctx->mAlpha = MDP_ALPHA_NOP;
ctx->mFlags = 0;
ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index c14af74..d57b84d 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -1,5 +1,9 @@
/*
* Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -67,9 +71,8 @@
/* blurs the copied bitmap. The amount of blurring cannot be changed
* at this time. */
COPYBIT_BLUR = 5,
- /* Informs the copybit that the source and destination contains
- premultiplied alpha */
- COPYBIT_PREMULTIPLIED_ALPHA = 6,
+ /* Blend mode */
+ COPYBIT_BLEND_MODE = 6,
/* FB width */
COPYBIT_FRAMEBUFFER_WIDTH = 7,
/* FB height */
@@ -96,6 +99,20 @@
COPYBIT_ENABLE = 1
};
+/*
+ * copybit blending values. same as HWC blending values
+ */
+enum {
+ /* no blending */
+ COPYBIT_BLENDING_NONE = 0x0100,
+
+ /* ONE / ONE_MINUS_SRC_ALPHA */
+ COPYBIT_BLENDING_PREMULT = 0x0105,
+
+ /* SRC_ALPHA / ONE_MINUS_SRC_ALPHA */
+ COPYBIT_BLENDING_COVERAGE = 0x0405
+};
+
/* use get_static_info() to query static informations about the hardware */
enum {
/* Maximum amount of minification supported by the hardware*/
@@ -213,6 +230,26 @@
struct copybit_rect_t const *dst_rect,
struct copybit_rect_t const *src_rect,
struct copybit_region_t const *region);
+
+ /**
+ * Execute the completion of the copybit draw operation.
+ *
+ * @param dev from open
+ *
+ * @return 0 if successful
+ */
+ int (*finish)(struct copybit_device_t *dev);
+
+ /**
+ * Trigger the copybit draw operation(async).
+ *
+ * @param dev from open
+ *
+ * @param fd - gets the fencefd
+ *
+ * @return 0 if successful
+ */
+ int (*flush_get_fence)(struct copybit_device_t *dev, int* fd);
};
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index ea5dd2a..2fa55cd 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -1,6 +1,9 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +17,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#include <cutils/log.h>
+#include <sys/resource.h>
+#include <sys/prctl.h>
#include <stdint.h>
#include <string.h>
@@ -76,10 +80,16 @@
C2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
-C2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, uint32 len, uint32 offset, uint32 flags, void ** gpuaddr);
+C2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, uint32 len,
+ uint32 offset, uint32 flags, void ** gpuaddr);
C2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
+C2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
+
+/* create a fence fd for the timestamp */
+C2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
+ int32 *fd);
/******************************************************************************/
#if defined(COPYBIT_Z180)
@@ -89,7 +99,15 @@
#error "Unsupported HW version"
#endif
-#define NUM_SURFACES 3
+// The following defines can be changed as required i.e. as we encounter
+// complex use cases.
+#define MAX_RGB_SURFACES 8 // Max. RGB layers currently supported per draw
+#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
+#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
+// +1 for the destination surface. We cannot have multiple destination surfaces.
+#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
+#define NUM_SURFACE_TYPES 3 // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
+#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw
enum {
RGB_SURFACE,
@@ -103,8 +121,9 @@
};
enum eC2DFlags {
- FLAGS_PREMULTIPLIED_ALPHA = 1<<0,
- FLAGS_YUV_DESTINATION = 1<<1
+ FLAGS_PREMULTIPLIED_ALPHA = 1<<0,
+ FLAGS_YUV_DESTINATION = 1<<1,
+ FLAGS_TEMP_SRC_DST = 1<<2
};
static gralloc::IAllocController* sAlloc = 0;
@@ -113,22 +132,38 @@
/** State information for each device instance */
struct copybit_context_t {
struct copybit_device_t device;
- unsigned int src[NUM_SURFACES]; /* src surfaces */
- unsigned int dst[NUM_SURFACES]; /* dst surfaces */
- unsigned int trg_transform; /* target transform */
- C2D_OBJECT blitState;
+ // Templates for the various source surfaces. These templates are created
+ // to avoid the expensive create/destroy C2D Surfaces
+ C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
+ C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
+ C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
+ C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
+ C2D_DRIVER_INFO c2d_driver_info;
void *libc2d2;
alloc_data temp_src_buffer;
alloc_data temp_dst_buffer;
+ unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
+ unsigned int mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
+ int blit_rgb_count; // Total RGB surfaces being blit
+ int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
+ int blit_yuv_3_plane_count; // Total 3 plane YUV surfaces being blit
+ int blit_count; // Total blit objects.
+ unsigned int trg_transform; /* target transform */
int fb_width;
int fb_height;
- bool isPremultipliedAlpha;
- bool mBlitToFB;
-};
+ int src_global_alpha;
+ int config_mask;
+ int dst_surface_type;
+ bool is_premultiplied_alpha;
+ void* time_stamp;
-struct blitlist{
- uint32_t count;
- C2D_OBJECT blitObjects[12];
+ // used for signaling the wait thread
+ bool wait_timestamp;
+ pthread_t wait_thread_id;
+ bool stop_thread;
+ pthread_mutex_t wait_cleanup_lock;
+ pthread_cond_t wait_cleanup_cond;
+
};
struct bufferInfo {
@@ -172,6 +207,46 @@
};
+/* thread function which waits on the timeStamp and cleans up the surfaces */
+static void* c2d_wait_loop(void* ptr) {
+ copybit_context_t* ctx = (copybit_context_t*)(ptr);
+ char thread_name[64] = "copybitWaitThr";
+ prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+ while(ctx->stop_thread == false) {
+ pthread_mutex_lock(&ctx->wait_cleanup_lock);
+ while(ctx->wait_timestamp == false && !ctx->stop_thread) {
+ pthread_cond_wait(&(ctx->wait_cleanup_cond),
+ &(ctx->wait_cleanup_lock));
+ }
+ if(ctx->wait_timestamp) {
+ if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
+ ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
+ }
+ ctx->wait_timestamp = false;
+ // Unmap any mapped addresses.
+ for (int i = 0; i < MAX_SURFACES; i++) {
+ if (ctx->mapped_gpu_addr[i]) {
+ LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
+ ctx->mapped_gpu_addr[i] = 0;
+ }
+ }
+ // Reset the counts after the draw.
+ ctx->blit_rgb_count = 0;
+ ctx->blit_yuv_2_plane_count = 0;
+ ctx->blit_yuv_3_plane_count = 0;
+ ctx->blit_count = 0;
+ }
+ pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+ if(ctx->stop_thread)
+ break;
+ }
+ pthread_exit(NULL);
+ return NULL;
+}
+
+
/* convert COPYBIT_FORMAT to C2D format */
static int get_format(int format) {
switch (format) {
@@ -189,7 +264,9 @@
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;
- default: ALOGE("%s: invalid format (0x%x", __FUNCTION__, format); return -EINVAL;
+ default: ALOGE("%s: invalid format (0x%x",
+ __FUNCTION__, format);
+ return -EINVAL;
}
return -EINVAL;
}
@@ -201,7 +278,7 @@
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
+ // 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;
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV12;
@@ -251,7 +328,8 @@
return c2dBpp;
}
-static uint32 c2d_get_gpuaddr( struct private_handle_t *handle)
+static uint32 c2d_get_gpuaddr(copybit_context_t* ctx, struct private_handle_t *handle,
+ int &mapped_idx)
{
uint32 memtype, *gpuaddr;
C2D_STATUS rc;
@@ -271,13 +349,36 @@
return 0;
}
- rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size, handle->offset, memtype, (void**)&gpuaddr);
+ rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
+ handle->offset, memtype, (void**)&gpuaddr);
+
if (rc == C2D_STATUS_OK) {
+ // We have mapped the GPU address inside copybit. We need to unmap this
+ // address after the blit. Store this address
+ for (int i = 0; i < MAX_SURFACES; i++) {
+ if (ctx->mapped_gpu_addr[i] == 0) {
+ ctx->mapped_gpu_addr[i] = (uint32) gpuaddr;
+ mapped_idx = i;
+ break;
+ }
+ }
+
return (uint32) gpuaddr;
}
return 0;
}
+static void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
+{
+ if (!ctx || (mapped_idx == -1))
+ return;
+
+ if (ctx->mapped_gpu_addr[mapped_idx]) {
+ LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
+ ctx->mapped_gpu_addr[mapped_idx] = 0;
+ }
+}
+
static int is_supported_rgb_format(int format)
{
switch(format) {
@@ -379,20 +480,24 @@
}
/** create C2D surface from copybit image */
-static int set_image( uint32 surfaceId, const struct copybit_image_t *rhs,
- int *cformat, uint32_t *mapped, const eC2DFlags flags)
+static int set_image(copybit_context_t* ctx, uint32 surfaceId,
+ const struct copybit_image_t *rhs,
+ const eC2DFlags flags, int &mapped_idx)
{
struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
C2D_SURFACE_TYPE surfaceType;
int status = COPYBIT_SUCCESS;
+ uint32 gpuaddr = 0;
+ int c2d_format;
+ mapped_idx = -1;
if (flags & FLAGS_YUV_DESTINATION) {
- *cformat = get_c2d_format_for_yuv_destination(rhs->format);
+ c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
} else {
- *cformat = get_format(rhs->format);
+ c2d_format = get_format(rhs->format);
}
- if(*cformat == -EINVAL) {
+ if(c2d_format == -EINVAL) {
ALOGE("%s: invalid format", __FUNCTION__);
return -EINVAL;
}
@@ -403,12 +508,13 @@
}
if (handle->gpuaddr == 0) {
- handle->gpuaddr = c2d_get_gpuaddr(handle);
- if(!handle->gpuaddr) {
+ gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
+ if(!gpuaddr) {
ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
return COPYBIT_FAILURE;
}
- *mapped = 1;
+ } else {
+ gpuaddr = handle->gpuaddr;
}
/* create C2D surface */
@@ -418,26 +524,27 @@
surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
- surfaceDef.phys = (void*) handle->gpuaddr;
+ surfaceDef.phys = (void*) gpuaddr;
surfaceDef.buffer = (void*) (handle->base);
- surfaceDef.format = *cformat |
+ surfaceDef.format = c2d_format |
((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
surfaceDef.width = rhs->w;
surfaceDef.height = rhs->h;
int aligned_width = ALIGN(surfaceDef.width,32);
surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
- if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, &surfaceDef)) {
+ if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
+ &surfaceDef)) {
ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
- goto error;
+ unmap_gpuaddr(ctx, mapped_idx);
status = COPYBIT_FAILURE;
}
} else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
C2D_YUV_SURFACE_DEF surfaceDef;
memset(&surfaceDef, 0, sizeof(surfaceDef));
surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
- surfaceDef.format = *cformat;
+ surfaceDef.format = c2d_format;
bufferInfo info;
info.width = rhs->w;
@@ -448,199 +555,116 @@
status = calculate_yuv_offset_and_stride(info, yuvInfo);
if(status != COPYBIT_SUCCESS) {
ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
- goto error;
+ unmap_gpuaddr(ctx, mapped_idx);
}
surfaceDef.width = rhs->w;
surfaceDef.height = rhs->h;
surfaceDef.plane0 = (void*) (handle->base);
- surfaceDef.phys0 = (void*) (handle->gpuaddr);
+ surfaceDef.phys0 = (void*) (gpuaddr);
surfaceDef.stride0 = yuvInfo.yStride;
surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
- surfaceDef.phys1 = (void*) (handle->gpuaddr + yuvInfo.plane1_offset);
+ surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
surfaceDef.stride1 = yuvInfo.plane1_stride;
if (3 == get_num_planes(rhs->format)) {
surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
- surfaceDef.phys2 = (void*) (handle->gpuaddr + yuvInfo.plane2_offset);
+ surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
surfaceDef.stride2 = yuvInfo.plane2_stride;
}
if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
&surfaceDef)) {
ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
- goto error;
+ unmap_gpuaddr(ctx, mapped_idx);
status = COPYBIT_FAILURE;
}
} else {
ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
- goto error;
+ unmap_gpuaddr(ctx, mapped_idx);
status = COPYBIT_FAILURE;
}
return status;
-
-error:
- if(*mapped == 1) {
- LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
- handle->gpuaddr = 0;
- *mapped = 0;
- }
- return status;
}
-static int set_src_image( uint32 *surfaceId, const struct copybit_image_t *rhs,
- int *cformat, uint32 *mapped)
+/** copy the bits */
+static int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
{
- struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
- *cformat = get_format(rhs->format);
- C2D_SURFACE_TYPE surfaceType;
- uint32 gpuaddr = (uint32)handle->gpuaddr;
- int status = COPYBIT_SUCCESS;
+ if (ctx->blit_count == 0) {
+ return COPYBIT_SUCCESS;
+ }
- if (handle->gpuaddr == 0)
+ for (int i = 0; i < ctx->blit_count; i++)
{
- handle->gpuaddr = c2d_get_gpuaddr( handle);
- if(!handle->gpuaddr)
- return COPYBIT_FAILURE;
-
- *mapped = 1;
+ ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
}
+ ctx->blit_list[ctx->blit_count-1].next = NULL;
+ if(LINK_c2dDraw(target,ctx->trg_transform, 0x0, 0, 0, ctx->blit_list,
+ ctx->blit_count)) {
+ ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
+ return COPYBIT_FAILURE;
+ }
+ return COPYBIT_SUCCESS;
+}
- /* create C2D surface */
- if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
- /* RGB */
- C2D_RGB_SURFACE_DEF surfaceDef;
- surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY);
- surfaceDef.phys = (void*) handle->gpuaddr;
- surfaceDef.buffer = (void*) (handle->base);
- surfaceDef.buffer = (void*) (handle->base + handle->offset);
- surfaceDef.format = get_format(rhs->format);
- surfaceDef.width = rhs->w;
- surfaceDef.height = rhs->h;
- surfaceDef.stride = ALIGN(((surfaceDef.width * c2diGetBpp(surfaceDef.format))>>3), 32);
+static int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
+{
+ struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+ int status = COPYBIT_FAILURE;
+ if (!ctx)
+ return COPYBIT_FAILURE;
+ pthread_mutex_lock(&ctx->wait_cleanup_lock);
+ status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
- if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET, surfaceType,(void*)&surfaceDef)) {
- ALOGE("%s: LINK_c2dCreateSurface error", __FUNCTION__);
- status = COPYBIT_FAILURE;
- goto error;
- }
- } else if(is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
- /* YUV */
- C2D_YUV_SURFACE_DEF surfaceDef;
- int offset = 0;
- int yStride = 0;
- int uvStride = 0;
- memset(&surfaceDef, 0, sizeof(surfaceDef));
-
- surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY);
- surfaceDef.format = get_format(rhs->format);
- bufferInfo info;
- info.width = rhs->w;
- info.height = rhs->h;
- info.format = rhs->format;
-
- yuvPlaneInfo yuvInfo;
- status = calculate_yuv_offset_and_stride(info, yuvInfo);
- if(status != COPYBIT_SUCCESS) {
- ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
- goto error;
- }
-
- surfaceDef.width = rhs->w;
- surfaceDef.height = rhs->h;
- surfaceDef.plane0 = (void*) (handle->base);
- surfaceDef.phys0 = (void*) handle->gpuaddr;
- surfaceDef.stride0 = yuvInfo.yStride;
-
- surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
- surfaceDef.phys1 = (void*) (handle->gpuaddr + yuvInfo.plane1_offset);
- surfaceDef.stride1 = yuvInfo.plane1_stride;
-
- if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET | C2D_SOURCE, surfaceType,
- (void*)&surfaceDef)) {
- ALOGE("%s: YUV surface LINK_c2dCreateSurface error", __func__);
- status = COPYBIT_FAILURE;
- goto error;
- }
- } else {
- ALOGE("%s: Invalid format 0x%x", __FUNCTION__, rhs->format);
+ if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
+ ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
+ // unlock the mutex and return failure
+ pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+ return COPYBIT_FAILURE;
+ }
+ if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
+ fd)) {
+ ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
status = COPYBIT_FAILURE;
}
-
- return COPYBIT_SUCCESS;
-
-error:
- if(*mapped == 1) {
- LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
- handle->gpuaddr = 0;
- *mapped = 0;
+ if(status == COPYBIT_SUCCESS) {
+ //signal the wait_thread
+ ctx->wait_timestamp = true;
+ pthread_cond_signal(&ctx->wait_cleanup_cond);
}
+ pthread_mutex_unlock(&ctx->wait_cleanup_lock);
return status;
}
-void unset_image( uint32 surfaceId, const struct copybit_image_t *rhs,
- uint32 mmapped)
+static int finish_copybit(struct copybit_device_t *dev)
{
- struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
+ struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+ if (!ctx)
+ return COPYBIT_FAILURE;
- if (mmapped && handle->gpuaddr) {
- // Unmap this gpuaddr
- LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
- handle->gpuaddr = 0;
- }
-}
+ int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
-static int blit_to_target( uint32 surfaceId, const struct copybit_image_t *rhs)
-{
- struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
- uint32 cformat = get_format(rhs->format);
- C2D_SURFACE_TYPE surfaceType;
- uint32 memoryMapped = 0;
- int status = COPYBIT_SUCCESS;
-
- if (!handle->gpuaddr) {
- handle->gpuaddr = c2d_get_gpuaddr(handle);
- if(!handle->gpuaddr)
- return COPYBIT_FAILURE;
-
- memoryMapped = 1;
+ if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
+ ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
+ return COPYBIT_FAILURE;
}
- /* create C2D surface */
-
- if(cformat) {
- /* RGB */
- C2D_RGB_SURFACE_DEF surfaceDef;
- memset(&surfaceDef, 0, sizeof(surfaceDef));
-
- surfaceDef.buffer = (void*) handle->base;
- surfaceDef.phys = (void*) handle->gpuaddr;
-
- surfaceType = C2D_SURFACE_RGB_HOST;
- surfaceDef.format = get_format(rhs->format);
- surfaceDef.width = rhs->w;
- surfaceDef.height = rhs->h;
- surfaceDef.stride = ALIGN(((surfaceDef.width * c2diGetBpp(surfaceDef.format))>>3), 32);
-
- if(LINK_c2dReadSurface(surfaceId, surfaceType, (void*)&surfaceDef, 0, 0)) {
- ALOGE("%s: LINK_c2dReadSurface ERROR", __func__);
- status = COPYBIT_FAILURE;
- goto done;
+ // Unmap any mapped addresses.
+ for (int i = 0; i < MAX_SURFACES; i++) {
+ if (ctx->mapped_gpu_addr[i]) {
+ LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
+ ctx->mapped_gpu_addr[i] = 0;
}
}
- else {
- /* YUV */
- /* TODO */
- }
-done:
- if (memoryMapped) {
- LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
- handle->gpuaddr = 0;
- }
+ // Reset the counts after the draw.
+ ctx->blit_rgb_count = 0;
+ ctx->blit_yuv_2_plane_count = 0;
+ ctx->blit_yuv_3_plane_count = 0;
+ ctx->blit_count = 0;
return status;
}
@@ -696,24 +720,6 @@
c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
}
-/** copy the bits */
-static int msm_copybit(struct copybit_context_t *dev, blitlist *list, uint32 target)
-{
- unsigned int objects;
-
- for(objects = 0; objects < list->count; objects++) {
- list->blitObjects[objects].next = &(list->blitObjects[objects+1]);
- }
-
- if(LINK_c2dDraw(target,dev->trg_transform, 0x0, 0, 0, list->blitObjects,
- list->count)) {
- ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
- return COPYBIT_FAILURE;
- }
-
- return COPYBIT_SUCCESS;
-}
-
/*****************************************************************************/
/** Set a parameter to value */
@@ -723,81 +729,95 @@
int value)
{
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+ int status = COPYBIT_SUCCESS;
if (!ctx) {
ALOGE("%s: null context", __FUNCTION__);
return -EINVAL;
}
+ pthread_mutex_lock(&ctx->wait_cleanup_lock);
switch(name) {
- case COPYBIT_ROTATION_DEG:
- ctx->blitState.rotation = value<<16;
- /* SRC rotation */
- if(!value)
- ctx->blitState.config_mask &=~C2D_ROTATE_BIT;;
- break;
case COPYBIT_PLANE_ALPHA:
+ {
if (value < 0) value = 0;
if (value >= 256) value = 255;
- ctx->blitState.global_alpha = value;
-
- if(ctx->blitState.global_alpha<255)
- ctx->blitState.config_mask |= C2D_GLOBAL_ALPHA_BIT;
+ ctx->src_global_alpha = value;
+ if (value < 255)
+ ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
else
- ctx->blitState.config_mask &=~C2D_GLOBAL_ALPHA_BIT;
- break;
- case COPYBIT_DITHER:
- /* TODO */
- break;
- case COPYBIT_BLUR:
- /* TODO */
- break;
- case COPYBIT_TRANSFORM:
- ctx->blitState.config_mask &=~C2D_ROTATE_BIT;
- ctx->blitState.config_mask &=~C2D_MIRROR_H_BIT;
- ctx->blitState.config_mask &=~C2D_MIRROR_V_BIT;
- ctx->trg_transform = C2D_TARGET_ROTATE_0;
-
- if((value&0x7) == COPYBIT_TRANSFORM_ROT_180)
- ctx->trg_transform = C2D_TARGET_ROTATE_180;
- else if((value&0x7) == COPYBIT_TRANSFORM_ROT_270)
- ctx->trg_transform = C2D_TARGET_ROTATE_90;
- else {
- if(value©BIT_TRANSFORM_FLIP_H)
- ctx->blitState.config_mask |= C2D_MIRROR_H_BIT;
- if(value©BIT_TRANSFORM_FLIP_V)
- ctx->blitState.config_mask |= C2D_MIRROR_V_BIT;
- if(value©BIT_TRANSFORM_ROT_90)
- ctx->trg_transform = C2D_TARGET_ROTATE_270;
+ ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
+ }
+ break;
+ case COPYBIT_BLEND_MODE:
+ {
+ if (value == COPYBIT_BLENDING_NONE) {
+ ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
+ ctx->is_premultiplied_alpha = true;
+ } else if (value == COPYBIT_BLENDING_PREMULT) {
+ ctx->is_premultiplied_alpha = true;
+ } else {
+ ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
}
- break;
- case COPYBIT_PREMULTIPLIED_ALPHA:
- (value == COPYBIT_ENABLE) ? ctx->isPremultipliedAlpha = true :
- ctx->isPremultipliedAlpha = false;
- break;
+ }
+ break;
+ case COPYBIT_TRANSFORM:
+ {
+ unsigned int transform = 0;
+ uint32 config_mask = 0;
+ config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
+ if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
+ transform = C2D_TARGET_ROTATE_180;
+ config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
+ } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
+ transform = C2D_TARGET_ROTATE_90;
+ config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
+ } else if(value == COPYBIT_TRANSFORM_ROT_90) {
+ transform = C2D_TARGET_ROTATE_270;
+ config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
+ } else {
+ config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
+ if(value & COPYBIT_TRANSFORM_FLIP_H) {
+ config_mask |= C2D_MIRROR_H_BIT;
+ } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
+ config_mask |= C2D_MIRROR_V_BIT;
+ }
+ }
+
+ if (transform != ctx->trg_transform) {
+ if (ctx->c2d_driver_info.capabilities_mask &
+ C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
+ ctx->config_mask |= config_mask;
+ } else {
+ // The transform for this surface does not match the current
+ // target transform. Draw all previous surfaces. This will be
+ // changed once we have a new mechanism to send different
+ // target rotations to c2d.
+ finish_copybit(dev);
+ }
+ }
+ ctx->trg_transform = transform;
+ }
+ break;
case COPYBIT_FRAMEBUFFER_WIDTH:
ctx->fb_width = value;
break;
case COPYBIT_FRAMEBUFFER_HEIGHT:
ctx->fb_height = value;
break;
+ case COPYBIT_ROTATION_DEG:
+ case COPYBIT_DITHER:
+ case COPYBIT_BLUR:
case COPYBIT_BLIT_TO_FRAMEBUFFER:
- if (COPYBIT_ENABLE == value) {
- ctx->mBlitToFB = value;
- } else if (COPYBIT_DISABLE == value) {
- ctx->mBlitToFB = value;
- } else {
- ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d",
- __FUNCTION__, value);
- }
+ // Do nothing
break;
default:
ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
- return -EINVAL;
+ status = -EINVAL;
break;
}
-
- return COPYBIT_SUCCESS;
+ pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+ return status;
}
/** Get a static info value */
@@ -898,14 +918,14 @@
{
// Chroma for this format is aligned to 2K.
size = ALIGN((aligned_w*h), 2048) +
- ALIGN(w/2, 32) * h/2 *2;
+ ALIGN(aligned_w/2, 32) * (h/2) *2;
size = ALIGN(size, 4096);
} break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
{
- size = aligned_w*h +
- ALIGN(w/2, 32) * h/2 *2;
+ size = aligned_w * h +
+ ALIGN(aligned_w/2, 32) * (h/2) * 2;
size = ALIGN(size, 4096);
} break;
default: break;
@@ -998,6 +1018,19 @@
handle = 0;
}
}
+
+static bool need_to_execute_draw(struct copybit_context_t* ctx,
+ eC2DFlags flags)
+{
+ if (flags & FLAGS_TEMP_SRC_DST) {
+ return true;
+ }
+ if (flags & FLAGS_YUV_DESTINATION) {
+ return true;
+ }
+ return false;
+}
+
/** do a stretch blit type operation */
static int stretch_copybit_internal(
struct copybit_device_t *dev,
@@ -1010,14 +1043,10 @@
{
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
int status = COPYBIT_SUCCESS;
- uint32 maxCount;
- uint32 src_mapped = 0, trg_mapped = 0;
- blitlist list;
- C2D_OBJECT *req;
- memset(&list, 0, sizeof(list));
- int cformat;
- c2d_ts_handle timestamp;
- uint32 src_surface_index = 0, dst_surface_index = 0;
+ int flags = 0;
+ int src_surface_type;
+ int mapped_src_idx = -1, mapped_dst_idx = -1;
+ C2D_OBJECT_STR src_surface;
if (!ctx) {
ALOGE("%s: null context error", __FUNCTION__);
@@ -1030,40 +1059,54 @@
}
if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
- ALOGE("%s : dst dimension error dst w %d h %d", __FUNCTION__, dst->w, dst->h);
+ ALOGE("%s : dst dimension error dst w %d h %d", __FUNCTION__, dst->w,
+ dst->h);
return -EINVAL;
}
- maxCount = sizeof(list.blitObjects)/sizeof(C2D_OBJECT);
-
- struct copybit_rect_t clip;
- list.count = 0;
-
if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
- ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__, dst->format);
+ ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__,
+ dst->format);
return COPYBIT_FAILURE;
}
- bool isYUVDestination = false;
+ int dst_surface_type;
if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
- dst_surface_index = RGB_SURFACE;
+ dst_surface_type = RGB_SURFACE;
+ flags |= FLAGS_PREMULTIPLIED_ALPHA;
} else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
- isYUVDestination = true;
int num_planes = get_num_planes(dst->format);
+ flags |= FLAGS_YUV_DESTINATION;
if (num_planes == 2) {
- dst_surface_index = YUV_SURFACE_2_PLANES;
+ dst_surface_type = YUV_SURFACE_2_PLANES;
} else if (num_planes == 3) {
- dst_surface_index = YUV_SURFACE_3_PLANES;
+ dst_surface_type = YUV_SURFACE_3_PLANES;
} else {
ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
__FUNCTION__, dst->format);
return COPYBIT_FAILURE;
}
} else {
- ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__, dst->format);
+ ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__,
+ dst->format);
return COPYBIT_FAILURE;
}
+ if (ctx->blit_rgb_count == MAX_RGB_SURFACES ||
+ ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES ||
+ ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES ||
+ ctx->blit_count == MAX_BLIT_OBJECT_COUNT ||
+ ctx->dst_surface_type != dst_surface_type) {
+ // we have reached the max. limits of our internal structures or
+ // changed the target.
+ // Draw the remaining surfaces. We need to do the finish here since
+ // we need to free up the surface templates.
+ finish_copybit(dev);
+ }
+
+ ctx->dst_surface_type = dst_surface_type;
+
+ // Update the destination
copybit_image_t dst_image;
dst_image.w = dst->w;
dst_image.h = dst->h;
@@ -1072,7 +1115,7 @@
// Check if we need a temp. copy for the destination. We'd need this the destination
// width is not aligned to 32. This case occurs for YUV formats. RGB formats are
// aligned to 32.
- bool needTempDestination = need_temp_buffer(dst);
+ bool need_temp_dst = need_temp_buffer(dst);
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,
@@ -1081,7 +1124,7 @@
ALOGE("%s: dst_hnd is null", __FUNCTION__);
return COPYBIT_FAILURE;
}
- if (needTempDestination) {
+ if (need_temp_dst) {
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.
@@ -1100,35 +1143,40 @@
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->dst[dst_surface_index], &dst_image,
- &cformat, &trg_mapped, (eC2DFlags)flags);
+ status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image,
+ (eC2DFlags)flags, mapped_dst_idx);
if(status) {
ALOGE("%s: dst: set_image error", __FUNCTION__);
delete_handle(dst_hnd);
+ unmap_gpuaddr(ctx, mapped_dst_idx);
return COPYBIT_FAILURE;
}
+ // Update the source
+ flags = 0;
if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
- src_surface_index = RGB_SURFACE;
+ src_surface_type = RGB_SURFACE;
+ src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count];
} else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
int num_planes = get_num_planes(src->format);
if (num_planes == 2) {
- src_surface_index = YUV_SURFACE_2_PLANES;
+ src_surface_type = YUV_SURFACE_2_PLANES;
+ src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count];
} else if (num_planes == 3) {
- src_surface_index = YUV_SURFACE_3_PLANES;
+ src_surface_type = YUV_SURFACE_3_PLANES;
+ src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count];
} else {
ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
__FUNCTION__, src->format);
delete_handle(dst_hnd);
+ unmap_gpuaddr(ctx, mapped_dst_idx);
return -EINVAL;
}
} else {
- ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__, src->format);
+ ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__,
+ src->format);
delete_handle(dst_hnd);
+ unmap_gpuaddr(ctx, mapped_dst_idx);
return -EINVAL;
}
@@ -1138,24 +1186,27 @@
src_image.format = src->format;
src_image.handle = src->handle;
- bool needTempSource = need_temp_buffer(src);
+ bool need_temp_src = need_temp_buffer(src);
bufferInfo src_info;
populate_buffer_info(src, src_info);
private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
- src_info.width, src_info.height);
+ src_info.width, src_info.height);
if (NULL == src_hnd) {
ALOGE("%s: src_hnd is null", __FUNCTION__);
delete_handle(dst_hnd);
+ unmap_gpuaddr(ctx, mapped_dst_idx);
return COPYBIT_FAILURE;
}
- if (needTempSource) {
+ if (need_temp_src) {
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)) {
+ if (COPYBIT_SUCCESS != get_temp_buffer(src_info,
+ ctx->temp_src_buffer)) {
ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
delete_handle(dst_hnd);
delete_handle(src_hnd);
+ unmap_gpuaddr(ctx, mapped_dst_idx);
return COPYBIT_FAILURE;
}
}
@@ -1168,7 +1219,15 @@
src_image.handle = src_hnd;
// Copy the source.
- copy_image((private_handle_t *)src->handle, &src_image, CONVERT_TO_C2D_FORMAT);
+ status = copy_image((private_handle_t *)src->handle, &src_image,
+ CONVERT_TO_C2D_FORMAT);
+ if (status == COPYBIT_FAILURE) {
+ ALOGE("%s:copy_image failed in temp source",__FUNCTION__);
+ delete_handle(dst_hnd);
+ delete_handle(src_hnd);
+ unmap_gpuaddr(ctx, mapped_dst_idx);
+ return status;
+ }
// Flush the cache
IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
@@ -1177,70 +1236,90 @@
ALOGE("%s: clean_buffer failed", __FUNCTION__);
delete_handle(dst_hnd);
delete_handle(src_hnd);
+ unmap_gpuaddr(ctx, mapped_dst_idx);
return COPYBIT_FAILURE;
}
}
- status = set_image( ctx->src[src_surface_index], &src_image,
- &cformat, &src_mapped, (eC2DFlags)flags);
+ flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
+ flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
+ status = set_image(ctx, src_surface.surface_id, &src_image,
+ (eC2DFlags)flags, mapped_src_idx);
if(status) {
- ALOGE("%s: set_src_image error", __FUNCTION__);
+ ALOGE("%s: set_image (src) error", __FUNCTION__);
delete_handle(dst_hnd);
delete_handle(src_hnd);
+ unmap_gpuaddr(ctx, mapped_dst_idx);
+ unmap_gpuaddr(ctx, mapped_src_idx);
return COPYBIT_FAILURE;
}
+ src_surface.config_mask = C2D_NO_BILINEAR_BIT | C2D_NO_ANTIALIASING_BIT |
+ ctx->config_mask;
+ src_surface.global_alpha = ctx->src_global_alpha;
if (enableBlend) {
- if(ctx->blitState.config_mask & C2D_GLOBAL_ALPHA_BIT) {
- ctx->blitState.config_mask &= ~C2D_ALPHA_BLEND_NONE;
- if(!(ctx->blitState.global_alpha)) {
+ if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
+ src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
+ if(!(src_surface.global_alpha)) {
// src alpha is zero
- unset_image( ctx->src[src_surface_index],
- &src_image, src_mapped);
- unset_image( ctx->dst[dst_surface_index],
- &dst_image, trg_mapped);
delete_handle(dst_hnd);
delete_handle(src_hnd);
- return status;
+ unmap_gpuaddr(ctx, mapped_dst_idx);
+ unmap_gpuaddr(ctx, mapped_src_idx);
+ return COPYBIT_FAILURE;
}
} else {
- if(is_alpha(cformat))
- ctx->blitState.config_mask &= ~C2D_ALPHA_BLEND_NONE;
+ int c2d_format = get_format(src->format);
+ if(is_alpha(c2d_format))
+ src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
else
- ctx->blitState.config_mask |= C2D_ALPHA_BLEND_NONE;
+ src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
}
} else {
- ctx->blitState.config_mask |= C2D_ALPHA_BLEND_NONE;
+ src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
}
- ctx->blitState.surface_id = ctx->src[src_surface_index];
+ if (src_surface_type == RGB_SURFACE) {
+ ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface;
+ ctx->blit_rgb_count++;
+ } else if (src_surface_type == YUV_SURFACE_2_PLANES) {
+ ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface;
+ ctx->blit_yuv_2_plane_count++;
+ } else {
+ ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface;
+ ctx->blit_yuv_3_plane_count++;
+ }
+ struct copybit_rect_t clip;
while ((status == 0) && region->next(region, &clip)) {
- req = &(list.blitObjects[list.count]);
- memcpy(req,&ctx->blitState,sizeof(C2D_OBJECT));
-
- set_rects(ctx, req, dst_rect, src_rect, &clip);
-
- if (++list.count == maxCount) {
- status = msm_copybit(ctx, &list, ctx->dst[dst_surface_index]);
- list.count = 0;
+ set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
+ if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
+ ALOGW("Reached end of blit count");
+ finish_copybit(dev);
}
- }
- if ((status == 0) && list.count) {
- status = msm_copybit(ctx, &list, ctx->dst[dst_surface_index]);
+ ctx->blit_list[ctx->blit_count] = src_surface;
+ ctx->blit_count++;
}
- if(LINK_c2dFinish(ctx->dst[dst_surface_index])) {
- ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
+ // Check if we need to perform an early draw-finish.
+ flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
+ if (need_to_execute_draw(ctx, (eC2DFlags)flags))
+ {
+ finish_copybit(dev);
}
- unset_image( ctx->src[src_surface_index], &src_image,
- src_mapped);
- unset_image( 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);
+ if (need_temp_dst) {
+ // copy the temp. destination without the alignment to the actual
+ // destination.
+ status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
+ if (status == COPYBIT_FAILURE) {
+ ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__);
+ delete_handle(dst_hnd);
+ delete_handle(src_hnd);
+ unmap_gpuaddr(ctx, mapped_dst_idx);
+ unmap_gpuaddr(ctx, mapped_src_idx);
+ return status;
+ }
// Invalidate the cache.
IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
@@ -1248,12 +1327,15 @@
}
delete_handle(dst_hnd);
delete_handle(src_hnd);
- ctx->isPremultipliedAlpha = false;
+
+ ctx->is_premultiplied_alpha = false;
ctx->fb_width = 0;
ctx->fb_height = 0;
+ ctx->config_mask = 0;
return status;
}
+
static int stretch_copybit(
struct copybit_device_t *dev,
struct copybit_image_t const *dst,
@@ -1263,9 +1345,13 @@
struct copybit_region_t const *region)
{
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
- bool needsBlending = (ctx->blitState.global_alpha != 0);
- return stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
+ int status = COPYBIT_SUCCESS;
+ bool needsBlending = (ctx->src_global_alpha != 0);
+ pthread_mutex_lock(&ctx->wait_cleanup_lock);
+ status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
region, needsBlending);
+ pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+ return status;
}
/** Perform a blit type operation */
@@ -1282,26 +1368,60 @@
/*****************************************************************************/
+static void clean_up(copybit_context_t* ctx)
+{
+ void* ret;
+ if (!ctx)
+ return;
+
+ // stop the wait_cleanup_thread
+ pthread_mutex_lock(&ctx->wait_cleanup_lock);
+ ctx->stop_thread = true;
+ // Signal waiting thread
+ pthread_cond_signal(&ctx->wait_cleanup_cond);
+ pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+ // waits for the cleanup thread to exit
+ pthread_join(ctx->wait_thread_id, &ret);
+ pthread_mutex_destroy(&ctx->wait_cleanup_lock);
+ pthread_cond_destroy (&ctx->wait_cleanup_cond);
+
+ for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
+ if (ctx->dst[i])
+ LINK_c2dDestroySurface(ctx->dst[i]);
+ }
+
+ for (int i = 0; i < MAX_RGB_SURFACES; i++) {
+ if (ctx->blit_rgb_object[i].surface_id)
+ LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
+ }
+
+ for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
+ if (ctx->blit_yuv_2_plane_object[i].surface_id)
+ LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
+ }
+
+ for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
+ if (ctx->blit_yuv_3_plane_object[i].surface_id)
+ LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
+ }
+
+ if (ctx->libc2d2) {
+ ::dlclose(ctx->libc2d2);
+ ALOGV("dlclose(libc2d2)");
+ }
+
+ free(ctx);
+}
+
/** Close the copybit device */
static int close_copybit(struct hw_device_t *dev)
{
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
if (ctx) {
- for(int i = 0; i <NUM_SURFACES; i++) {
- LINK_c2dDestroySurface(ctx->dst[i]);
- LINK_c2dDestroySurface(ctx->src[i]);
- }
-
- if (ctx->libc2d2) {
- ::dlclose(ctx->libc2d2);
- ALOGV("dlclose(libc2d2)");
- }
-
free_temp_buffer(ctx->temp_src_buffer);
free_temp_buffer(ctx->temp_dst_buffer);
- free(ctx);
}
-
+ clean_up(ctx);
return 0;
}
@@ -1323,16 +1443,13 @@
/* initialize drawstate */
memset(ctx, 0, sizeof(*ctx));
-
- for (int i=0; i< NUM_SURFACES; i++) {
- ctx->dst[i] = -1;
- ctx->src[i] = -1;
- }
-
ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
if (!ctx->libc2d2) {
ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
- goto error;
+ clean_up(ctx);
+ status = COPYBIT_FAILURE;
+ *device = NULL;
+ return status;
}
*(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
"c2dCreateSurface");
@@ -1351,12 +1468,20 @@
"c2dMapAddr");
*(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
"c2dUnMapAddr");
+ *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
+ "c2dGetDriverCapabilities");
+ *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
+ "c2dCreateFenceFD");
if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
- || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp || !LINK_c2dFinish
- || !LINK_c2dDestroySurface) {
+ || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
+ !LINK_c2dFinish || !LINK_c2dDestroySurface ||
+ !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD) {
ALOGE("%s: dlsym ERROR", __FUNCTION__);
- goto error;
+ clean_up(ctx);
+ status = COPYBIT_FAILURE;
+ *device = NULL;
+ return status;
}
ctx->device.common.tag = HARDWARE_DEVICE_TAG;
@@ -1367,8 +1492,8 @@
ctx->device.get = get;
ctx->device.blit = blit_copybit;
ctx->device.stretch = stretch_copybit;
- ctx->blitState.config_mask = C2D_NO_BILINEAR_BIT | C2D_NO_ANTIALIASING_BIT;
- ctx->trg_transform = C2D_TARGET_ROTATE_0;
+ ctx->device.finish = finish_copybit;
+ ctx->device.flush_get_fence = flush_get_fence_copybit;
/* Create RGB Surface */
surfDefinition.buffer = (void*)0xdddddddd;
@@ -1379,24 +1504,45 @@
surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
(C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
- C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY ), &surfDefinition)) {
- ALOGE("%s: create ctx->dst[RGB_SURFACE] failed", __FUNCTION__);
- ctx->dst[RGB_SURFACE] = -1;
- goto error;
+ C2D_SURFACE_WITH_PHYS |
+ C2D_SURFACE_WITH_PHYS_DUMMY ),
+ &surfDefinition)) {
+ ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
+ ctx->dst[RGB_SURFACE] = 0;
+ clean_up(ctx);
+ status = COPYBIT_FAILURE;
+ *device = NULL;
+ return status;
}
-
- if (LINK_c2dCreateSurface(&(ctx->src[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
+ unsigned int surface_id = 0;
+ for (int i = 0; i < MAX_RGB_SURFACES; i++)
+ {
+ if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
(C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
- C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY), &surfDefinition)) {
- ALOGE("%s: create ctx->src[RGB_SURFACE] failed", __FUNCTION__);
- ctx->src[RGB_SURFACE] = -1;
- goto error;
+ C2D_SURFACE_WITH_PHYS |
+ C2D_SURFACE_WITH_PHYS_DUMMY ),
+ &surfDefinition)) {
+ ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
+ ctx->blit_rgb_object[i].surface_id = 0;
+ status = COPYBIT_FAILURE;
+ break;
+ } else {
+ ctx->blit_rgb_object[i].surface_id = surface_id;
+ ALOGW("%s i = %d surface_id=%d", __FUNCTION__, i,
+ ctx->blit_rgb_object[i].surface_id);
+ }
}
- /* Create YUV source surface */
- yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
+ if (status == COPYBIT_FAILURE) {
+ clean_up(ctx);
+ status = COPYBIT_FAILURE;
+ *device = NULL;
+ return status;
+ }
+ // Create 2 plane YUV surfaces
+ yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
yuvSurfaceDef.width = 4;
yuvSurfaceDef.height = 4;
yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
@@ -1406,48 +1552,101 @@
yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
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 | C2D_SURFACE_WITH_PHYS_DUMMY),
- &yuvSurfaceDef)) {
- ALOGE("%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 | C2D_SURFACE_WITH_PHYS_DUMMY),
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
+ C2D_SURFACE_WITH_PHYS |
+ C2D_SURFACE_WITH_PHYS_DUMMY),
&yuvSurfaceDef)) {
ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
- ctx->dst[YUV_SURFACE_2_PLANES] = -1;
- goto error;
+ ctx->dst[YUV_SURFACE_2_PLANES] = 0;
+ clean_up(ctx);
+ status = COPYBIT_FAILURE;
+ *device = NULL;
+ return status;
}
+ for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
+ {
+ if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
+ C2D_SURFACE_WITH_PHYS |
+ C2D_SURFACE_WITH_PHYS_DUMMY ),
+ &yuvSurfaceDef)) {
+ ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
+ ctx->blit_yuv_2_plane_object[i].surface_id = 0;
+ status = COPYBIT_FAILURE;
+ break;
+ } else {
+ ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
+ ALOGW("%s: 2 Plane YUV i=%d surface_id=%d", __FUNCTION__, i,
+ ctx->blit_yuv_2_plane_object[i].surface_id);
+ }
+ }
+
+ if (status == COPYBIT_FAILURE) {
+ clean_up(ctx);
+ status = COPYBIT_FAILURE;
+ *device = NULL;
+ return status;
+ }
+
+ // Create YUV 3 plane surfaces
yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
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 | C2D_SURFACE_WITH_PHYS_DUMMY),
- &yuvSurfaceDef)) {
- ALOGE("%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 | C2D_SURFACE_WITH_PHYS_DUMMY),
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
+ C2D_SURFACE_WITH_PHYS |
+ C2D_SURFACE_WITH_PHYS_DUMMY),
&yuvSurfaceDef)) {
ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
- ctx->dst[YUV_SURFACE_3_PLANES] = -1;
- goto error;
+ ctx->dst[YUV_SURFACE_3_PLANES] = 0;
+ clean_up(ctx);
+ status = COPYBIT_FAILURE;
+ *device = NULL;
+ return status;
}
+ for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
+ {
+ if (LINK_c2dCreateSurface(&(surface_id),
+ C2D_TARGET | C2D_SOURCE,
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
+ C2D_SURFACE_WITH_PHYS |
+ C2D_SURFACE_WITH_PHYS_DUMMY),
+ &yuvSurfaceDef)) {
+ ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
+ ctx->blit_yuv_3_plane_object[i].surface_id = 0;
+ status = COPYBIT_FAILURE;
+ break;
+ } else {
+ ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
+ ALOGW("%s: 3 Plane YUV i=%d surface_id=%d", __FUNCTION__, i,
+ ctx->blit_yuv_3_plane_object[i].surface_id);
+ }
+ }
+
+ if (status == COPYBIT_FAILURE) {
+ clean_up(ctx);
+ status = COPYBIT_FAILURE;
+ *device = NULL;
+ return status;
+ }
+
+ if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
+ ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
+ clean_up(ctx);
+ status = COPYBIT_FAILURE;
+ *device = NULL;
+ return status;
+ }
+ // Initialize context variables.
+ ctx->trg_transform = C2D_TARGET_ROTATE_0;
+
ctx->temp_src_buffer.fd = -1;
ctx->temp_src_buffer.base = 0;
ctx->temp_src_buffer.size = 0;
@@ -1458,28 +1657,25 @@
ctx->fb_width = 0;
ctx->fb_height = 0;
- ctx->isPremultipliedAlpha = false;
+
+ ctx->blit_rgb_count = 0;
+ ctx->blit_yuv_2_plane_count = 0;
+ ctx->blit_yuv_3_plane_count = 0;
+ ctx->blit_count = 0;
+
+ ctx->wait_timestamp = false;
+ ctx->stop_thread = false;
+ pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
+ pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
+ /* Start the wait thread */
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+ pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
+ (void *)ctx);
+ pthread_attr_destroy(&attr);
*device = &ctx->device.common;
return status;
-
-error:
- for (int i = 0; i<NUM_SURFACES; i++) {
- if (-1 != (ctx->src[i])) {
- LINK_c2dDestroySurface(ctx->src[i]);
- ctx->src[i] = -1;
- }
- if (-1 != (ctx->dst[i])) {
- LINK_c2dDestroySurface(ctx->dst[i]);
- ctx->dst[i] = -1;
- }
- }
- if (ctx->libc2d2)
- ::dlclose(ctx->libc2d2);
- if (ctx)
- free(ctx);
- status = COPYBIT_FAILURE;
- *device = NULL;
-
- return status;
}
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
index 159a252..f4e3834 100644
--- a/libgralloc/Android.mk
+++ b/libgralloc/Android.mk
@@ -35,7 +35,7 @@
LOCAL_MODULE := libmemalloc
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) libgenlock
+LOCAL_SHARED_LIBRARIES := $(common_libs) libgenlock libqdutils
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdmemalloc\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
LOCAL_SRC_FILES := ionalloc.cpp alloc_controller.cpp
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index 1193a27..5293ca9 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -267,9 +267,20 @@
float xdpi = (info.xres * 25.4f) / info.width;
float ydpi = (info.yres * 25.4f) / info.height;
+#ifdef MSMFB_METADATA_GET
+ struct msmfb_metadata metadata;
+ memset(&metadata, 0 , sizeof(metadata));
+ metadata.op = metadata_op_frame_rate;
+ if (ioctl(fd, MSMFB_METADATA_GET, &metadata) == -1) {
+ ALOGE("Error retrieving panel frame rate");
+ return -errno;
+ }
+ float fps = metadata.data.panel_frame_rate;
+#else
+ //XXX: Remove reserved field usage on all baselines
//The reserved[3] field is used to store FPS by the driver.
float fps = info.reserved[3] & 0xFF;
-
+#endif
ALOGI("using (fd=%d)\n"
"id = %s\n"
"xres = %d px\n"
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 656df38..0d070f0 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -47,6 +47,7 @@
common.module = const_cast<hw_module_t*>(&module->base.common);
common.close = gralloc_close;
alloc = gralloc_alloc;
+ allocSize = gralloc_alloc_size;
free = gralloc_free;
}
@@ -246,7 +247,7 @@
if ((ssize_t)size <= 0)
return -EINVAL;
- size = (bufferSize >= size)? bufferSize : size;
+ size = (bufferSize != 0)? bufferSize : size;
// All buffers marked as protected or for external
// display need to go to overlay
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 6ccc7e0..dc755cb 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -84,7 +84,8 @@
enum {
/* Gralloc perform enums
*/
- GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 0x080000001,
+ GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER =
+ GRALLOC_MODULE_PERFORM_PRIVATE_START,
};
#define GRALLOC_HEAP_MASK (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 176a84e..197c372 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -348,6 +348,21 @@
break;
}
+ case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY:
+ {
+ int width = va_arg(args, int);
+ int height = va_arg(args, int);
+ int format = va_arg(args, int);
+ private_handle_t* hnd = va_arg(args, private_handle_t*);
+ if (private_handle_t::validate(hnd)) {
+ return res;
+ }
+ hnd->width = width;
+ hnd->height = height;
+ hnd->format = format;
+ res = 0;
+ }
+ break;
default:
break;
}
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 543efd9..a9ada35 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -8,7 +8,7 @@
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL liboverlay libgenlock \
libexternal libqdutils libhardware_legacy \
- libdl libmemalloc libqservice
+ libdl libmemalloc libqservice libsync
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := hwc.cpp \
@@ -17,6 +17,7 @@
hwc_uevents.cpp \
hwc_vsync.cpp \
hwc_fbupdate.cpp \
- hwc_mdpcomp.cpp
+ hwc_mdpcomp.cpp \
+ hwc_copybit.cpp
include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index ac1be19..ba84580 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -2,6 +2,9 @@
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
*
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -30,6 +33,7 @@
#include "hwc_fbupdate.h"
#include "hwc_mdpcomp.h"
#include "external.h"
+#include "hwc_copybit.h"
using namespace qhwc;
#define VSYNC_DEBUG 0
@@ -96,6 +100,9 @@
if(ctx->mFBUpdate[i])
ctx->mFBUpdate[i]->reset();
+
+ if(ctx->mCopyBit[i])
+ ctx->mCopyBit[i]->reset();
}
VideoOverlay::reset();
}
@@ -127,11 +134,16 @@
if(fbLayer->handle) {
setListStats(ctx, list, dpy);
reset_layer_prop(ctx, dpy);
- if(!ctx->mMDPComp->prepare(ctx, list)) {
+ int ret = ctx->mMDPComp->prepare(ctx, list);
+ if(!ret) {
+ // IF MDPcomp fails use this route
VideoOverlay::prepare(ctx, list, dpy);
ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
}
ctx->mLayerCache[dpy]->updateLayerCache(list);
+ // Use Copybit, when MDP comp fails
+ if(!ret && ctx->mCopyBit[dpy])
+ ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
}
}
return 0;
@@ -154,6 +166,8 @@
VideoOverlay::prepare(ctx, list, dpy);
ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
ctx->mLayerCache[dpy]->updateLayerCache(list);
+ if(ctx->mCopyBit[dpy])
+ ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
ctx->mExtDispConfiguring = false;
}
}
@@ -296,8 +310,10 @@
ctx->dpyAttr[dpy].isActive) {
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
-
- hwc_sync(ctx, list, dpy);
+ int fd = -1; //FenceFD from the Copybit(valid in async mode)
+ if(ctx->mCopyBit[dpy])
+ ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
+ hwc_sync(ctx, list, dpy, fd);
if (!VideoOverlay::draw(ctx, list, dpy)) {
ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
ret = -1;
@@ -338,8 +354,11 @@
ctx->dpyAttr[dpy].connected) {
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
+ int fd = -1; //FenceFD from the Copybit(valid in async mode)
+ if(ctx->mCopyBit[dpy])
+ ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
- hwc_sync(ctx, list, dpy);
+ hwc_sync(ctx, list, dpy, fd);
if (!VideoOverlay::draw(ctx, list, dpy)) {
ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
@@ -369,7 +388,6 @@
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
Locker::Autolock _l(ctx->mBlankLock);
-
for (uint32_t i = 0; i < numDisplays; i++) {
hwc_display_contents_1_t* list = displays[i];
switch(i) {
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 1249e84..e764c69 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are retained
* for attribution purposes only.
@@ -20,14 +20,12 @@
#define DEBUG_COPYBIT 0
#include <copybit.h>
-#include <genlock.h>
-#include "hwc_copybit.h"
+#include <utils/Timers.h>
#include "hwc_copybit.h"
#include "comptype.h"
namespace qhwc {
-
struct range {
int current;
int end;
@@ -65,44 +63,9 @@
mutable range r;
};
-// Initialize CopyBit Class Static Mmembers.
-functype_eglGetRenderBufferANDROID CopyBit::LINK_eglGetRenderBufferANDROID
- = NULL;
-functype_eglGetCurrentSurface CopyBit::LINK_eglGetCurrentSurface = NULL;
-int CopyBit::sYuvCount = 0;
-int CopyBit::sYuvLayerIndex = -1;
-bool CopyBit::sIsModeOn = false;
-bool CopyBit::sIsLayerSkip = false;
-void* CopyBit::egl_lib = NULL;
-
-void CopyBit::openEglLibAndGethandle()
-{
- egl_lib = ::dlopen("libEGL_adreno200.so", RTLD_GLOBAL | RTLD_LAZY);
- if (!egl_lib) {
- return;
- }
- updateEglHandles(egl_lib);
-}
-void CopyBit::closeEglLib()
-{
- if(egl_lib)
- ::dlclose(egl_lib);
-
- egl_lib = NULL;
- updateEglHandles(NULL);
-}
-
-void CopyBit::updateEglHandles(void* egl_lib)
-{
- if(egl_lib != NULL) {
- *(void **)&CopyBit::LINK_eglGetRenderBufferANDROID =
- ::dlsym(egl_lib, "eglGetRenderBufferANDROID");
- *(void **)&CopyBit::LINK_eglGetCurrentSurface =
- ::dlsym(egl_lib, "eglGetCurrentSurface");
- }else {
- LINK_eglGetCurrentSurface = NULL;
- LINK_eglGetCurrentSurface = NULL;
- }
+void CopyBit::reset() {
+ mIsModeOn = false;
+ mCopyBitDraw = false;
}
bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) {
@@ -113,15 +76,16 @@
return true;
}
-bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
- int compositionType =
- qdutils::QCCompositionType::getInstance().getCompositionType();
+bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx,
+ hwc_display_contents_1_t *list,
+ int dpy) {
+ int compositionType = qdutils::QCCompositionType::
+ getInstance().getCompositionType();
if ((compositionType & qdutils::COMPOSITION_TYPE_C2D) ||
(compositionType & qdutils::COMPOSITION_TYPE_DYN)) {
- if (sYuvCount) {
+ if(ctx->listStats[dpy].yuvCount) {
//Overlay up & running. Dont use COPYBIT for RGB layers.
- // TODO need to implement blending with C2D
return false;
}
}
@@ -131,17 +95,13 @@
// use copybit, if (TotalRGBRenderArea < 2 * FB Area)
// this is done based on perf inputs in ICS
// TODO: Above condition needs to be re-evaluated in JB
-
- framebuffer_device_t *fbDev = ctx->mFbDev;
- if (!fbDev) {
- ALOGE("%s:Invalid FB device", __FUNCTION__);
- return false;
- }
- unsigned int fbArea = (fbDev->width * fbDev->height);
+ int fbWidth = ctx->dpyAttr[dpy].xres;
+ int fbHeight = ctx->dpyAttr[dpy].yres;
+ unsigned int fbArea = (fbWidth * fbHeight);
unsigned int renderArea = getRGBRenderingArea(list);
ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
__FUNCTION__, renderArea, fbArea);
- if (renderArea < (2 * fbArea)) {
+ if (renderArea <= (2 * fbArea)) {
return true;
}
} else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
@@ -154,7 +114,8 @@
return false;
}
-unsigned int CopyBit::getRGBRenderingArea(const hwc_display_contents_1_t *list) {
+unsigned int CopyBit::getRGBRenderingArea
+ (const hwc_display_contents_1_t *list) {
//Calculates total rendering area for RGB layers
unsigned int renderArea = 0;
unsigned int w=0, h=0;
@@ -170,71 +131,116 @@
return renderArea;
}
-bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
+bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+ int dpy) {
- int compositionType =
- qdutils::QCCompositionType::getInstance().getCompositionType();
+ if(mEngine == NULL) {
+ // No copybit device found - cannot use copybit
+ return false;
+ }
+ int compositionType = qdutils::QCCompositionType::
+ getInstance().getCompositionType();
- if ((compositionType & qdutils::COMPOSITION_TYPE_GPU) ||
- (compositionType & qdutils::COMPOSITION_TYPE_CPU)) {
+ if ((compositionType == qdutils::COMPOSITION_TYPE_GPU) ||
+ (compositionType == qdutils::COMPOSITION_TYPE_CPU)) {
//GPU/CPU composition, don't change layer composition type
return true;
}
- bool useCopybitForYUV = canUseCopybitForYUV(ctx);
- bool useCopybitForRGB = canUseCopybitForRGB(ctx, list);
-
if(!(validateParams(ctx, list))) {
- ALOGE("%s:Invalid Params", __FUNCTION__);
- return false;
+ ALOGE("%s:Invalid Params", __FUNCTION__);
+ return false;
}
- for (int i=list->numHwLayers-1; i >= 0 ; i--) {
+ if(ctx->listStats[dpy].skipCount) {
+ //GPU will be anyways used
+ return false;
+ }
+
+ bool useCopybitForYUV = canUseCopybitForYUV(ctx);
+ bool useCopybitForRGB = canUseCopybitForRGB(ctx, list, dpy);
+
+ // numAppLayers-1, as we iterate till 0th layer index
+ for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
- if (isSkipLayer(&list->hwLayers[i])) {
- return true;
- } else if (hnd->bufferType == BUFFER_TYPE_VIDEO) {
- //YUV layer, check, if copybit can be used
- if (useCopybitForYUV) {
- list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
- }
- } else if (hnd->bufferType == BUFFER_TYPE_UI) {
- //RGB layer, check, if copybit can be used
- if (useCopybitForRGB) {
- list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
- }
- }
- }
- return true;
-}
-
-bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, EGLDisplay dpy,
- EGLSurface sur){
- // draw layers marked for COPYBIT
- int retVal = true;
- for (size_t i=0; i<list->numHwLayers; i++) {
- if (list->hwLayers[i].compositionType == HWC_USE_COPYBIT) {
- retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
- (EGLDisplay)dpy,
- (EGLSurface)sur,
- LINK_eglGetRenderBufferANDROID,
- LINK_eglGetCurrentSurface);
- if(retVal<0) {
- ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
- }
+ if (hnd->bufferType == BUFFER_TYPE_VIDEO) {
+ //YUV layer, check, if copybit can be used
+ // mark the video layer to gpu when all layer is
+ // going to gpu in case of dynamic composition.
+ if (useCopybitForYUV) {
+ list->hwLayers[i].compositionType = HWC_BLIT;
+ mCopyBitDraw = true;
+ }
+ } else if (hnd->bufferType == BUFFER_TYPE_UI) {
+ //RGB layer, check, if copybit can be used
+ if (useCopybitForRGB) {
+ ALOGD_IF(DEBUG_COPYBIT, "%s: Marking layer[%d] for copybit for"
+ "dpy[%d] ", __FUNCTION__, i, dpy);
+ list->hwLayers[i].compositionType = HWC_BLIT;
+ mCopyBitDraw = true;
+ }
}
}
return true;
}
+bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+ int dpy, int32_t *fd) {
+ // draw layers marked for COPYBIT
+ int retVal = true;
+ int copybitLayerCount = 0;
+
+ if(mCopyBitDraw == false) // there is no layer marked for copybit
+ return true ;
+
+ size_t fbLayerIndex = ctx->listStats[dpy].fbLayerIndex;
+ hwc_layer_1_t *fbLayer = &list->hwLayers[fbLayerIndex];
+ //render buffer
+ private_handle_t *renderBuffer = (private_handle_t *)fbLayer->handle;
+ if (!renderBuffer) {
+ ALOGE("%s: HWC_FRAMEBUFFER_TARGET layer handle is NULL", __FUNCTION__);
+ return false;
+ }
+ // numAppLayers-1, as we iterate from 0th layer index with HWC_BLIT flag
+ for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
+ hwc_layer_1_t *layer = &list->hwLayers[i];
+ if(!list->hwLayers[i].compositionType == HWC_BLIT) {
+ ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for C2D", __FUNCTION__);
+ continue;
+ }
+ int ret = -1;
+ if (list->hwLayers[i].acquireFenceFd != -1 ) {
+ // Wait for acquire Fence on the App buffers.
+ ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
+ if(ret < 0) {
+ ALOGE("%s: sync_wait error!! error no = %d err str = %s",
+ __FUNCTION__, errno, strerror(errno));
+ }
+ close(list->hwLayers[i].acquireFenceFd);
+ list->hwLayers[i].acquireFenceFd = -1;
+ }
+ retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
+ renderBuffer, dpy);
+ copybitLayerCount++;
+ if(retVal < 0) {
+ ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
+ }
+ }
+
+ if (copybitLayerCount) {
+ copybit_device_t *copybit = getCopyBitDevice();
+ // Async mode
+ copybit->flush_get_fence(copybit, fd);
+ }
+ return true;
+}
+
int CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
- EGLDisplay dpy,
- EGLSurface surface,
- functype_eglGetRenderBufferANDROID& LINK_eglGetRenderBufferANDROID,
- functype_eglGetCurrentSurface LINK_eglGetCurrentSurface)
+ private_handle_t *renderBuffer, int dpy)
{
hwc_context_t* ctx = (hwc_context_t*)(dev);
+ int err = 0;
if(!ctx) {
ALOGE("%s: null context ", __FUNCTION__);
return -1;
@@ -246,26 +252,9 @@
return -1;
}
- // Lock this buffer for read.
- genlock_lock_type lockType = GENLOCK_READ_LOCK;
- int err = genlock_lock_buffer(hnd, lockType, GENLOCK_MAX_TIMEOUT);
- if (GENLOCK_FAILURE == err) {
- ALOGE("%s: genlock_lock_buffer(READ) failed", __FUNCTION__);
- return -1;
- }
- //render buffer
- EGLSurface eglSurface = LINK_eglGetCurrentSurface(EGL_DRAW);
- android_native_buffer_t *renderBuffer =
- (android_native_buffer_t *)LINK_eglGetRenderBufferANDROID(dpy, eglSurface);
- if (!renderBuffer) {
- ALOGE("%s: eglGetRenderBuffer returned NULL buffer", __FUNCTION__);
- genlock_unlock_buffer(hnd);
- return -1;
- }
- private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
+ private_handle_t *fbHandle = (private_handle_t *)renderBuffer;
if(!fbHandle) {
ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
- genlock_unlock_buffer(hnd);
return -1;
}
@@ -281,8 +270,6 @@
// this needs to change to accomodate vertical stride
// if needed in the future
src.vert_padding = 0;
- // Remove the srcBufferTransform if any
- layer->transform = (layer->transform & FINAL_TRANSFORM_MASK);
// Copybit source rect
hwc_rect_t sourceCrop = layer->sourceCrop;
@@ -302,9 +289,9 @@
dst.h = fbHandle->height;
dst.format = fbHandle->format;
dst.base = (void *)fbHandle->base;
- dst.handle = (native_handle_t *)renderBuffer->handle;
+ dst.handle = (native_handle_t *)fbHandle;
- copybit_device_t *copybit = ctx->mCopybitEngine->getEngine();
+ copybit_device_t *copybit = mEngine;
int32_t screen_w = displayFrame.right - displayFrame.left;
int32_t screen_h = displayFrame.bottom - displayFrame.top;
@@ -330,7 +317,6 @@
ALOGE("%s: wrong params for display screen_w=%d src_crop_width=%d \
screen_w=%d src_crop_width=%d", __FUNCTION__, screen_w,
src_crop_width,screen_w,src_crop_width);
- genlock_unlock_buffer(hnd);
return -1;
}
@@ -346,7 +332,6 @@
ALOGE("%s: greater than max supported size dsdx=%f dtdy=%f \
scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy,
scaleLimitMax,1/scaleLimitMin);
- genlock_unlock_buffer(hnd);
return -1;
}
if(dsdx > copybitsMaxScale ||
@@ -411,7 +396,6 @@
__LINE__);
if(tmpHnd)
free_buffer(tmpHnd);
- genlock_unlock_buffer(hnd);
return err;
}
// copy new src and src rect crop
@@ -431,9 +415,8 @@
layer->transform);
//TODO: once, we are able to read layer alpha, update this
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
- copybit->set_parameter(copybit, COPYBIT_PREMULTIPLIED_ALPHA,
- (layer->blending == HWC_BLENDING_PREMULT)?
- COPYBIT_ENABLE : COPYBIT_DISABLE);
+ copybit->set_parameter(copybit, COPYBIT_BLEND_MODE,
+ layer->blending);
copybit->set_parameter(copybit, COPYBIT_DITHER,
(dst.format == HAL_PIXEL_FORMAT_RGB_565)?
COPYBIT_ENABLE : COPYBIT_DISABLE);
@@ -449,13 +432,6 @@
if(err < 0)
ALOGE("%s: copybit stretch failed",__FUNCTION__);
-
- // Unlock this buffer since copybit is done with it.
- err = genlock_unlock_buffer(hnd);
- if (GENLOCK_FAILURE == err) {
- ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
- }
-
return err;
}
@@ -468,62 +444,41 @@
height = displayFrame.bottom - displayFrame.top;
}
-bool CopyBit::validateParams(hwc_context_t *ctx, const hwc_display_contents_1_t *list) {
- //Validate parameters
- if (!ctx) {
- ALOGE("%s:Invalid HWC context", __FUNCTION__);
- return false;
- } else if (!list) {
- ALOGE("%s:Invalid HWC layer list", __FUNCTION__);
- return false;
- }
-
- framebuffer_device_t *fbDev = ctx->mFbDev;
-
- if (!fbDev) {
- ALOGE("%s:Invalid FB device", __FUNCTION__);
- return false;
- }
-
- if (LINK_eglGetRenderBufferANDROID == NULL ||
- LINK_eglGetCurrentSurface == NULL) {
- ALOGE("%s:Not able to link to ADRENO", __FUNCTION__);
- return false;
- }
-
- return true;
+bool CopyBit::validateParams(hwc_context_t *ctx,
+ const hwc_display_contents_1_t *list) {
+ //Validate parameters
+ if (!ctx) {
+ ALOGE("%s:Invalid HWC context", __FUNCTION__);
+ return false;
+ } else if (!list) {
+ ALOGE("%s:Invalid HWC layer list", __FUNCTION__);
+ return false;
+ }
+ return true;
}
-//CopybitEngine Class functions
-CopybitEngine* CopybitEngine::sInstance = 0;
-struct copybit_device_t* CopybitEngine::getEngine() {
- return sEngine;
-}
-CopybitEngine* CopybitEngine::getInstance() {
- if(sInstance == NULL)
- sInstance = new CopybitEngine();
- return sInstance;
+struct copybit_device_t* CopyBit::getCopyBitDevice() {
+ return mEngine;
}
-CopybitEngine::CopybitEngine(){
+CopyBit::CopyBit():mIsModeOn(false), mCopyBitDraw(false){
hw_module_t const *module;
if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
- copybit_open(module, &sEngine);
- CopyBit::openEglLibAndGethandle();
+ if(copybit_open(module, &mEngine) < 0) {
+ ALOGE("FATAL ERROR: copybit open failed.");
+ }
} else {
- ALOGE("FATAL ERROR: copybit open failed.");
+ ALOGE("FATAL ERROR: copybit hw module not found");
}
}
-CopybitEngine::~CopybitEngine()
+CopyBit::~CopyBit()
{
- if(sEngine)
+ if(mEngine)
{
- CopyBit::closeEglLib();
- copybit_close(sEngine);
- sEngine = NULL;
+ copybit_close(mEngine);
+ mEngine = NULL;
}
}
-
}; //namespace qhwc
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index ae82b6c..015d85a 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are retained
* for attribution purposes only.
@@ -20,94 +20,49 @@
#ifndef HWC_COPYBIT_H
#define HWC_COPYBIT_H
#include "hwc_utils.h"
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <gralloc_priv.h>
-#include <gr.h>
-#include <dlfcn.h>
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
namespace qhwc {
-//Feature for using Copybit to display RGB layers.
-typedef EGLClientBuffer (*functype_eglGetRenderBufferANDROID) (
- EGLDisplay dpy,
- EGLSurface draw);
-typedef EGLSurface (*functype_eglGetCurrentSurface)(EGLint readdraw);
class CopyBit {
public:
+ CopyBit();
+ ~CopyBit();
+ // API to get copybit engine(non static)
+ struct copybit_device_t *getCopyBitDevice();
//Sets up members and prepares copybit if conditions are met
- static bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list);
+ bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+ int dpy);
//Draws layer if the layer is set for copybit in prepare
- static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, EGLDisplay dpy,
- EGLSurface sur);
- //Receives data from hwc
- static void setStats(int yuvCount, int yuvLayerIndex, bool isYuvLayerSkip);
-
- static void updateEglHandles(void*);
- static int drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
- EGLDisplay dpy, EGLSurface surface,
- functype_eglGetRenderBufferANDROID& LINK_eglGetRenderBufferANDROID,
- functype_eglGetCurrentSurface LINK_eglGetCurrentSurface);
- static bool canUseCopybitForYUV (hwc_context_t *ctx);
- static bool canUseCopybitForRGB (hwc_context_t *ctx,
- hwc_display_contents_1_t *list);
- static bool validateParams (hwc_context_t *ctx,
- const hwc_display_contents_1_t *list);
- static void closeEglLib();
- static void openEglLibAndGethandle();
+ bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+ int dpy, int* fd);
+ // resets the values
+ void reset();
private:
- //Marks layer flags if this feature is used
- static void markFlags(hwc_layer_1_t *layer);
- //returns yuv count
- static int getYuvCount();
-
- //Number of yuv layers in this drawing round
- static int sYuvCount;
- //Index of YUV layer, relevant only if count is 1
- static int sYuvLayerIndex;
- //Flags if a yuv layer is animating or below something that is animating
- static bool sIsLayerSkip;
+ // holds the copybit device
+ struct copybit_device_t *mEngine;
+ // Helper functions for copybit composition
+ int drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
+ private_handle_t *renderBuffer, int dpy);
+ bool canUseCopybitForYUV (hwc_context_t *ctx);
+ bool canUseCopybitForRGB (hwc_context_t *ctx,
+ hwc_display_contents_1_t *list, int dpy);
+ bool validateParams (hwc_context_t *ctx,
+ const hwc_display_contents_1_t *list);
//Flags if this feature is on.
- static bool sIsModeOn;
- //handle for adreno lib
- static void* egl_lib;
+ bool mIsModeOn;
+ // flag that indicates whether CopyBit composition is enabled for this cycle
+ bool mCopyBitDraw;
- static functype_eglGetRenderBufferANDROID LINK_eglGetRenderBufferANDROID;
- static functype_eglGetCurrentSurface LINK_eglGetCurrentSurface;
+ unsigned int getRGBRenderingArea
+ (const hwc_display_contents_1_t *list);
- static unsigned int getRGBRenderingArea (const hwc_display_contents_1_t *list);
-
- static void getLayerResolution(const hwc_layer_1_t* layer,
+ void getLayerResolution(const hwc_layer_1_t* layer,
unsigned int &width, unsigned int& height);
};
-class CopybitEngine {
-public:
- ~CopybitEngine();
- // API to get copybit engine(non static)
- struct copybit_device_t *getEngine();
- // API to get singleton
- static CopybitEngine* getInstance();
-private:
- CopybitEngine();
- struct copybit_device_t *sEngine;
- static CopybitEngine* sInstance; // singleton
-};
-
-
-inline void CopyBit::setStats(int yuvCount, int yuvLayerIndex,
- bool isYuvLayerSkip) {
- sYuvCount = yuvCount;
- sYuvLayerIndex = yuvLayerIndex;
- sIsLayerSkip = isYuvLayerSkip;
-}
-
-inline int CopyBit::getYuvCount() { return sYuvCount; }
-
-
}; //namespace qhwc
#endif //HWC_COPYBIT_H
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 2c0a77a..2e58b93 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -215,7 +215,8 @@
if(isSecureBuffer(hnd)) {
ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
}
- if((metadata->operation & PP_PARAM_INTERLACED) && metadata->interlaced) {
+ if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
+ metadata->interlaced) {
ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
}
}
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 334df26..6b8f4e3 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -27,6 +27,8 @@
#include <stdlib.h>
#include "hwc_utils.h"
#include "hwc_fbupdate.h"
+#include "hwc_copybit.h"
+#include "comptype.h"
#include "external.h"
namespace qhwc {
@@ -38,6 +40,16 @@
int vsync = 0;
int64_t timestamp = 0;
const char *str = udata;
+ bool usecopybit = false;
+ int compositionType =
+ qdutils::QCCompositionType::getInstance().getCompositionType();
+
+ if (compositionType & (qdutils::COMPOSITION_TYPE_DYN |
+ qdutils::COMPOSITION_TYPE_MDP |
+ qdutils::COMPOSITION_TYPE_C2D)) {
+ usecopybit = true;
+
+ }
if(!strcasestr("change@/devices/virtual/switch/hdmi", str) &&
!strcasestr("change@/devices/virtual/switch/wfd", str)) {
@@ -72,6 +84,8 @@
ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL] =
IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].xres,
HWC_DISPLAY_EXTERNAL);
+ if(usecopybit)
+ ctx->mCopyBit[HWC_DISPLAY_EXTERNAL] = new CopyBit();
} else {
ctx->mExtDisplay->processUEventOffline(udata);
if(ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL]) {
@@ -79,6 +93,11 @@
delete ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL];
ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL] = NULL;
}
+ if(ctx->mCopyBit[HWC_DISPLAY_EXTERNAL]){
+ Locker::Autolock _l(ctx->mExtSetLock);
+ delete ctx->mCopyBit[HWC_DISPLAY_EXTERNAL];
+ ctx->mCopyBit[HWC_DISPLAY_EXTERNAL] = NULL;
+ }
}
ALOGD("%s sending hotplug: connected = %d", __FUNCTION__, connected);
Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 76635d5..9cc5c24 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1,6 +1,9 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#define HWC_UTILS_DEBUG 0
#include <sys/ioctl.h>
#include <EGL/egl.h>
#include <cutils/properties.h>
@@ -25,9 +28,10 @@
#include "hwc_mdpcomp.h"
#include "hwc_fbupdate.h"
#include "mdp_version.h"
+#include "hwc_copybit.h"
#include "external.h"
#include "QService.h"
-
+#include "comptype.h"
namespace qhwc {
// Opens Framebuffer device
@@ -66,6 +70,19 @@
ctx->mFBUpdate[HWC_DISPLAY_PRIMARY] =
IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
HWC_DISPLAY_PRIMARY);
+
+ char value[PROPERTY_VALUE_MAX];
+ // Check if the target supports copybit compostion (dyn/mdp/c2d) to
+ // decide if we need to open the copybit module.
+ int compositionType =
+ qdutils::QCCompositionType::getInstance().getCompositionType();
+
+ if (compositionType & (qdutils::COMPOSITION_TYPE_DYN |
+ qdutils::COMPOSITION_TYPE_MDP |
+ qdutils::COMPOSITION_TYPE_C2D)) {
+ ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit();
+ }
+
ctx->mExtDisplay = new ExternalDisplay(ctx);
for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++)
ctx->mLayerCache[i] = new LayerCache();
@@ -87,6 +104,13 @@
ctx->mOverlay = NULL;
}
+ for(int i = 0; i< HWC_NUM_DISPLAY_TYPES; i++) {
+ if(ctx->mCopyBit[i]) {
+ delete ctx->mCopyBit[i];
+ ctx->mCopyBit[i] = NULL;
+ }
+ }
+
if(ctx->mFbDev) {
framebuffer_close(ctx->mFbDev);
ctx->mFbDev = NULL;
@@ -251,13 +275,15 @@
return ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive;
}
-int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy) {
+int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
+ int fd) {
int ret = 0;
struct mdp_buf_sync data;
int acquireFd[MAX_NUM_LAYERS];
int count = 0;
int releaseFd = -1;
int fbFd = -1;
+ memset(&data, 0, sizeof(data));
bool swapzero = false;
data.flags = MDP_BUF_SYNC_FLAG_WAIT;
data.acq_fen_fd = acquireFd;
@@ -270,35 +296,52 @@
//Accumulate acquireFenceFds
for(uint32_t i = 0; i < list->numHwLayers; i++) {
- if((list->hwLayers[i].compositionType == HWC_OVERLAY ||
- list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) &&
- list->hwLayers[i].acquireFenceFd != -1 ){
+ if(list->hwLayers[i].compositionType == HWC_OVERLAY &&
+ list->hwLayers[i].acquireFenceFd != -1) {
if(UNLIKELY(swapzero))
acquireFd[count++] = -1;
else
acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
}
+ if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
+ if(UNLIKELY(swapzero))
+ acquireFd[count++] = -1;
+ else if(fd != -1) {
+ //set the acquireFD from fd - which is coming from c2d
+ acquireFd[count++] = fd;
+ // Buffer sync IOCTL should be async when using c2d fence is
+ // used
+ data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
+ } else if(list->hwLayers[i].acquireFenceFd != -1)
+ acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+ }
}
data.acq_fen_fd_cnt = count;
fbFd = ctx->dpyAttr[dpy].fd;
-
//Waits for acquire fences, returns a release fence
- if(LIKELY(!swapzero))
+ if(LIKELY(!swapzero)) {
+ uint64_t start = systemTime();
ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
+ ALOGD_IF(HWC_UTILS_DEBUG, "%s: time taken for MSMFB_BUFFER_SYNC IOCTL = %d",
+ __FUNCTION__, (size_t) ns2ms(systemTime() - start));
+ }
if(ret < 0) {
ALOGE("ioctl MSMFB_BUFFER_SYNC failed, err=%s",
strerror(errno));
}
-
for(uint32_t i = 0; i < list->numHwLayers; i++) {
- if((list->hwLayers[i].compositionType == HWC_OVERLAY ||
- list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)) {
+ if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
+ list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
//Close the acquireFenceFds
if(list->hwLayers[i].acquireFenceFd > 0) {
close(list->hwLayers[i].acquireFenceFd);
list->hwLayers[i].acquireFenceFd = -1;
}
+ if(fd > 0) {
+ close(fd);
+ fd = -1;
+ }
//Populate releaseFenceFds.
if(UNLIKELY(swapzero))
list->hwLayers[i].releaseFenceFd = -1;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 9541404..0005582 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -1,6 +1,9 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,6 +54,7 @@
class ExternalDisplay;
class IFBUpdate;
class MDPComp;
+class CopyBit;
struct MDPInfo {
int version;
@@ -82,7 +86,6 @@
bool needsAlphaScale;
};
-
struct LayerProp {
uint32_t mFlags; //qcom specific layer flags
LayerProp():mFlags(0) {};
@@ -133,7 +136,8 @@
void dumpsys_log(android::String8& buf, const char* fmt, ...);
//Sync point impl.
-int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy);
+int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
+ int fd);
// Inline utility functions
static inline bool isSkipLayer(const hwc_layer_1_t* l) {
@@ -214,6 +218,10 @@
const hwc_procs_t* proc;
//Framebuffer device
framebuffer_device_t *mFbDev;
+
+ //CopyBit objects
+ qhwc::CopyBit *mCopyBit[HWC_NUM_DISPLAY_TYPES];
+
//Overlay object - NULL for non overlay devices
overlay::Overlay *mOverlay;
//QService object
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index 1784593..16d0c89 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -108,7 +108,8 @@
}
MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
- if ((metadata->operation & PP_PARAM_INTERLACED) && metadata->interlaced) {
+ if (metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
+ metadata->interlaced) {
ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
}
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index dedc396..071e9f2 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
* Not a Contribution, Apache license notifications and license are retained
* for attribution purposes only.
*
@@ -95,10 +95,7 @@
}
void MdssRot::setFlags(const utils::eMdpFlags& flags) {
- mRotInfo.flags &= ~utils::OV_MDP_SECURE_OVERLAY_SESSION;
- if (flags & utils::OV_MDP_SECURE_OVERLAY_SESSION) {
- mRotInfo.flags |= utils::OV_MDP_SECURE_OVERLAY_SESSION;
- }
+ mRotInfo.flags |= flags;
}
void MdssRot::setTransform(const utils::eTransform& rot, const bool& rotUsed)
@@ -132,6 +129,8 @@
return false;
}
mRotData.id = mRotInfo.id;
+ //reset flags to avoid stale orientation values
+ mRotInfo.flags = 0;
return true;
}
diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk
index ecae273..eb04afb 100644
--- a/libqdutils/Android.mk
+++ b/libqdutils/Android.mk
@@ -9,8 +9,8 @@
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdutils\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := profiler.cpp mdp_version.cpp \
- idle_invalidator.cpp
-
+ idle_invalidator.cpp \
+ comptype.cpp
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
diff --git a/libqdutils/comptype.cpp b/libqdutils/comptype.cpp
new file mode 100644
index 0000000..a29158a
--- /dev/null
+++ b/libqdutils/comptype.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation or the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include<comptype.h>
+
+//Instanticate the QCCompositionType Singleton
+ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::QCCompositionType);
diff --git a/libqdutils/comptype.h b/libqdutils/comptype.h
index a90f957..63c99d3 100644
--- a/libqdutils/comptype.h
+++ b/libqdutils/comptype.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
-
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
@@ -10,7 +10,7 @@
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
- * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * * Neither the name of The Linux Foundation or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -89,5 +89,4 @@
}
}; //namespace qdutils
-ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::QCCompositionType);
#endif //INCLUDE_LIBQCOM_COMPTYPES