exynos4: libhwcomposer: update for new api version

tirimbino
espenfjo 12 years ago committed by codeworkx
parent 1030fe0ae8
commit 34f9d5d692
  1. 14
      exynos4/hal/libhwcomposer/Android.mk
  2. 520
      exynos4/hal/libhwcomposer/SecHWC.cpp
  3. 897
      exynos4/hal/libhwcomposer/SecHWCUtils.cpp
  4. 128
      exynos4/hal/libhwcomposer/SecHWCUtils.h

@ -23,12 +23,8 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog libcutils libEGL \
libGLESv1_CM
ifeq ($(BOARD_USE_V4L2_ION),true)
LOCAL_SHARED_LIBRARIES += libion
endif
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../include
$(TARGET_HAL_PATH)/include
LOCAL_SRC_FILES := SecHWCLog.cpp SecHWCUtils.cpp SecHWC.cpp
@ -75,14 +71,6 @@ LOCAL_CFLAGS += -DSTD_1080P
endif
endif
ifeq ($(BOARD_USE_V4L2),true)
LOCAL_CFLAGS += -DBOARD_USE_V4L2
endif
ifeq ($(BOARD_USE_V4L2_ION),true)
LOCAL_CFLAGS += -DBOARD_USE_V4L2_ION
endif
LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)

@ -27,6 +27,8 @@
#include <cutils/atomic.h>
#include <EGL/egl.h>
#include <sys/prctl.h>
#include <fcntl.h>
#include "SecHWCUtils.h"
@ -63,7 +65,7 @@ static struct hw_module_methods_t hwc_module_methods = {
hwc_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_major: 2,
version_minor: 0,
id: HWC_HARDWARE_MODULE_ID,
name: "Samsung S5PC21X hwcomposer module",
@ -74,8 +76,8 @@ hwc_module_t HAL_MODULE_INFO_SYM = {
/*****************************************************************************/
static void dump_layer(hwc_layer_t const* l) {
ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, "
static void dump_layer(hwc_layer_1_t const* l) {
SEC_HWC_Log(HWC_LOG_DEBUG,"\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, "
"{%d,%d,%d,%d}, {%d,%d,%d,%d}",
l->compositionType, l->flags, l->handle, l->transform, l->blending,
l->sourceCrop.left,
@ -88,7 +90,7 @@ static void dump_layer(hwc_layer_t const* l) {
l->displayFrame.bottom);
}
void calculate_rect(struct hwc_win_info_t *win, hwc_layer_t *cur,
void calculate_rect(struct hwc_win_info_t *win, hwc_layer_1_t *cur,
sec_rect *rect)
{
rect->x = cur->displayFrame.left;
@ -118,7 +120,7 @@ void calculate_rect(struct hwc_win_info_t *win, hwc_layer_t *cur,
}
}
static int set_src_dst_img_rect(hwc_layer_t *cur,
static int set_src_dst_img_rect(hwc_layer_1_t *cur,
struct hwc_win_info_t *win,
struct sec_img *src_img,
struct sec_img *dst_img,
@ -194,62 +196,62 @@ static int set_src_dst_img_rect(hwc_layer_t *cur,
src_rect->x =
(0 - cur->displayFrame.left)
*(src_img->w)
/(cur->displayFrame.right - cur->displayFrame.left + 1);
if (cur->displayFrame.right + 1 > win->lcd_info.xres) {
/(cur->displayFrame.right - cur->displayFrame.left);
if (cur->displayFrame.right > win->lcd_info.xres) {
src_rect->w =
(cur->sourceCrop.right - cur->sourceCrop.left + 1) -
(cur->sourceCrop.right - cur->sourceCrop.left) -
src_rect->x -
(cur->displayFrame.right - win->lcd_info.xres)
*(src_img->w)
/(cur->displayFrame.right - cur->displayFrame.left + 1);
/(cur->displayFrame.right - cur->displayFrame.left);
} else {
src_rect->w =
(cur->sourceCrop.right - cur->sourceCrop.left + 1) -
(cur->sourceCrop.right - cur->sourceCrop.left) -
src_rect->x;
}
} else {
src_rect->x = cur->sourceCrop.left;
if (cur->displayFrame.right + 1 > win->lcd_info.xres) {
if (cur->displayFrame.right > win->lcd_info.xres) {
src_rect->w =
(cur->sourceCrop.right - cur->sourceCrop.left + 1) -
(cur->sourceCrop.right - cur->sourceCrop.left) -
src_rect->x -
(cur->displayFrame.right - win->lcd_info.xres)
*(src_img->w)
/(cur->displayFrame.right - cur->displayFrame.left + 1);
/(cur->displayFrame.right - cur->displayFrame.left);
} else {
src_rect->w =
(cur->sourceCrop.right - cur->sourceCrop.left + 1);
(cur->sourceCrop.right - cur->sourceCrop.left);
}
}
if (cur->displayFrame.top < 0) {
src_rect->y =
(0 - cur->displayFrame.top)
*(src_img->h)
/(cur->displayFrame.bottom - cur->displayFrame.top + 1);
if (cur->displayFrame.bottom + 1 > win->lcd_info.yres) {
/(cur->displayFrame.bottom - cur->displayFrame.top);
if (cur->displayFrame.bottom > win->lcd_info.yres) {
src_rect->h =
(cur->sourceCrop.bottom - cur->sourceCrop.top + 1) -
(cur->sourceCrop.bottom - cur->sourceCrop.top) -
src_rect->y -
(cur->displayFrame.bottom - win->lcd_info.yres)
*(src_img->h)
/(cur->displayFrame.bottom - cur->displayFrame.top + 1);
/(cur->displayFrame.bottom - cur->displayFrame.top);
} else {
src_rect->h =
(cur->sourceCrop.bottom - cur->sourceCrop.top + 1) -
(cur->sourceCrop.bottom - cur->sourceCrop.top) -
src_rect->y;
}
} else {
src_rect->y = cur->sourceCrop.top;
if (cur->displayFrame.bottom + 1 > win->lcd_info.yres) {
if (cur->displayFrame.bottom > win->lcd_info.yres) {
src_rect->h =
(cur->sourceCrop.bottom - cur->sourceCrop.top + 1) -
(cur->sourceCrop.bottom - cur->sourceCrop.top) -
src_rect->y -
(cur->displayFrame.bottom - win->lcd_info.yres)
*(src_img->h)
/(cur->displayFrame.bottom - cur->displayFrame.top + 1);
/(cur->displayFrame.bottom - cur->displayFrame.top);
} else {
src_rect->h =
(cur->sourceCrop.bottom - cur->sourceCrop.top + 1);
(cur->sourceCrop.bottom - cur->sourceCrop.top);
}
}
@ -301,7 +303,7 @@ static int set_src_dst_img_rect(hwc_layer_t *cur,
return 0;
}
static int get_hwc_compos_decision(hwc_layer_t* cur, int iter, int win_cnt)
static int get_hwc_compos_decision(hwc_layer_1_t* cur, int iter, int win_cnt)
{
if(cur->flags & HWC_SKIP_LAYER || !cur->handle) {
SEC_HWC_Log(HWC_LOG_DEBUG, "%s::is_skip_layer %d cur->handle %x ",
@ -351,36 +353,6 @@ static int get_hwc_compos_decision(hwc_layer_t* cur, int iter, int win_cnt)
}
}
#ifdef SUB_TITLES_HWC
else if ((win_cnt > 0) &&
(prev_handle->usage & GRALLOC_USAGE_EXTERNAL_DISP)) {
switch (prev_handle->format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_RGBA_5551:
case HAL_PIXEL_FORMAT_RGBA_4444:
compositionType = HWC_OVERLAY;
break;
default:
compositionType = HWC_FRAMEBUFFER;
break;
}
SEC_HWC_Log(HWC_LOG_DEBUG, "2nd iter###%s:: compositionType %d bpp %d"
" format %x src[%d %d %d %d] dst[%d %d %d %d] srcImg[%d %d]",
__func__, compositionType, prev_handle->bpp,
prev_handle->format,
cur->sourceCrop.left, cur->sourceCrop.right,
cur->sourceCrop.top, cur->sourceCrop.bottom,
cur->displayFrame.left, cur->displayFrame.right,
cur->displayFrame.top, cur->displayFrame.bottom,
prev_handle->width, prev_handle->height);
}
#endif
SEC_HWC_Log(HWC_LOG_DEBUG,
"%s::compositionType(%d)=>0:FB,1:OVERLAY \r\n"
" format(0x%x),magic(0x%x),flags(%d),size(%d),offset(%d)"
@ -404,7 +376,7 @@ static void reset_win_rect_info(hwc_win_info_t *win)
}
static int assign_overlay_window(struct hwc_context_t *ctx, hwc_layer_t *cur,
static int assign_overlay_window(struct hwc_context_t *ctx, hwc_layer_1_t *cur,
int win_idx, int layer_idx)
{
struct hwc_win_info_t *win;
@ -453,12 +425,136 @@ static int assign_overlay_window(struct hwc_context_t *ctx, hwc_layer_t *cur,
return 0;
}
static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
#ifdef SKIP_DUMMY_UI_LAY_DRAWING
static void get_hwc_ui_lay_skipdraw_decision(struct hwc_context_t* ctx,
hwc_display_contents_1_t* list)
{
private_handle_t *prev_handle;
hwc_layer_1_t* cur;
int num_of_fb_lay_skip = 0;
int fb_lay_tot = ctx->num_of_fb_layer + ctx->num_of_fb_lay_skip;
if (fb_lay_tot > NUM_OF_DUMMY_WIN)
return;
if (fb_lay_tot < 1) {
#ifdef GL_WA_OVLY_ALL
ctx->ui_skip_frame_cnt++;
if (ctx->ui_skip_frame_cnt >= THRES_FOR_SWAP) {
ctx->ui_skip_frame_cnt = 0;
ctx->num_of_fb_layer_prev = 1;
}
#endif
return;
}
if (ctx->fb_lay_skip_initialized) {
for (int cnt = 0; cnt < fb_lay_tot; cnt++) {
cur = &list->hwLayers[ctx->win_virt[cnt].layer_index];
if (ctx->win_virt[cnt].layer_prev_buf == (uint32_t)cur->handle)
num_of_fb_lay_skip++;
}
#ifdef GL_WA_OVLY_ALL
if (ctx->ui_skip_frame_cnt >= THRES_FOR_SWAP)
num_of_fb_lay_skip = 0;
#endif
if (num_of_fb_lay_skip != fb_lay_tot) {
ctx->num_of_fb_layer = fb_lay_tot;
ctx->num_of_fb_lay_skip = 0;
#ifdef GL_WA_OVLY_ALL
ctx->ui_skip_frame_cnt = 0;
#endif
for (int cnt = 0; cnt < fb_lay_tot; cnt++) {
cur = &list->hwLayers[ctx->win_virt[cnt].layer_index];
ctx->win_virt[cnt].layer_prev_buf = (uint32_t)cur->handle;
cur->compositionType = HWC_FRAMEBUFFER;
ctx->win_virt[cnt].status = HWC_WIN_FREE;
}
} else {
ctx->num_of_fb_layer = 0;
ctx->num_of_fb_lay_skip = fb_lay_tot;
#ifdef GL_WA_OVLY_ALL
ctx->ui_skip_frame_cnt++;
#endif
for (int cnt = 0; cnt < fb_lay_tot; cnt++) {
cur = &list->hwLayers[ctx->win_virt[cnt].layer_index];
cur->compositionType = HWC_OVERLAY;
ctx->win_virt[cnt].status = HWC_WIN_RESERVED;
}
}
} else {
ctx->num_of_fb_lay_skip = 0;
for (int i = 0; i < list->numHwLayers ; i++) {
if(num_of_fb_lay_skip >= NUM_OF_DUMMY_WIN)
break;
cur = &list->hwLayers[i];
if (cur->handle) {
prev_handle = (private_handle_t *)(cur->handle);
switch (prev_handle->format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGB_565:
cur->compositionType = HWC_FRAMEBUFFER;
ctx->win_virt[num_of_fb_lay_skip].layer_prev_buf =
(uint32_t)cur->handle;
ctx->win_virt[num_of_fb_lay_skip].layer_index = i;
ctx->win_virt[num_of_fb_lay_skip].status = HWC_WIN_FREE;
num_of_fb_lay_skip++;
break;
default:
break;
}
} else {
cur->compositionType = HWC_FRAMEBUFFER;
}
}
if (num_of_fb_lay_skip == fb_lay_tot)
ctx->fb_lay_skip_initialized = 1;
}
return;
}
#endif
static int hwc_prepare(hwc_composer_device_1_t *dev, size_t numDisplays, hwc_display_contents_1_t** displays)
{
for (uint32_t i = 0; i < numDisplays; i++) {
hwc_display_contents_1_t *list = displays[i];
struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
int overlay_win_cnt = 0;
int compositionType = 0;
int ret;
#if defined(BOARD_USES_HDMI)
android::SecHdmiClient *mHdmiClient = android::SecHdmiClient::getInstance();
int hdmi_cable_status = (int)mHdmiClient->getHdmiCableStatus();
ctx->hdmi_cable_status = hdmi_cable_status;
#endif
#ifdef SKIP_DUMMY_UI_LAY_DRAWING
if ((list && (!(list->flags & HWC_GEOMETRY_CHANGED))) &&
(ctx->num_of_hwc_layer > 0)) {
get_hwc_ui_lay_skipdraw_decision(ctx, list);
return 0;
}
ctx->fb_lay_skip_initialized = 0;
ctx->num_of_fb_lay_skip = 0;
#ifdef GL_WA_OVLY_ALL
ctx->ui_skip_frame_cnt = 0;
#endif
for (int i = 0; i < NUM_OF_DUMMY_WIN; i++) {
ctx->win_virt[i].layer_prev_buf = 0;
ctx->win_virt[i].layer_index = -1;
ctx->win_virt[i].status = HWC_WIN_FREE;
}
#endif
//if geometry is not changed, there is no need to do any work here
if (!list || (!(list->flags & HWC_GEOMETRY_CHANGED)))
@ -473,9 +569,27 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
ctx->num_of_hwc_layer = 0;
ctx->num_of_fb_layer = 0;
ctx->num_2d_blit_layer = 0;
ctx->num_of_ext_disp_video_layer = 0;
for (int i = 0; i < list->numHwLayers; i++) {
hwc_layer_1_t *cur = &list->hwLayers[i];
private_handle_t *prev_handle = NULL;
if (cur->handle) {
prev_handle = (private_handle_t *)(cur->handle);
SEC_HWC_Log(HWC_LOG_DEBUG, "prev_handle->usage = %d", prev_handle->usage);
if (prev_handle->usage & GRALLOC_USAGE_EXTERNAL_DISP) {
ctx->num_of_ext_disp_layer++;
if ((prev_handle->usage & GRALLOC_USAGE_EXTERNAL_DISP) ||
check_yuv_format((unsigned int)prev_handle->format) == 1) {
ctx->num_of_ext_disp_video_layer++;
}
}
}
}
for (int i = 0; i < list->numHwLayers ; i++) {
hwc_layer_t* cur = &list->hwLayers[i];
hwc_layer_1_t* cur = &list->hwLayers[i];
private_handle_t *prev_handle = (private_handle_t *)(cur->handle);
if (overlay_win_cnt < NUM_OF_WIN) {
compositionType = get_hwc_compos_decision(cur, 0, overlay_win_cnt);
@ -486,7 +600,7 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
} else {
ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i);
if (ret != 0) {
ALOGE("assign_overlay_window fail, change to frambuffer");
SEC_HWC_Log(HWC_LOG_ERROR, "assign_overlay_window fail, change to frambuffer");
cur->compositionType = HWC_FRAMEBUFFER;
ctx->num_of_fb_layer++;
continue;
@ -501,32 +615,29 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
cur->compositionType = HWC_FRAMEBUFFER;
ctx->num_of_fb_layer++;
}
}
#ifdef SUB_TITLES_HWC
for (int i = 0; i < list->numHwLayers ; i++) {
if (overlay_win_cnt < NUM_OF_WIN) {
hwc_layer_t* cur = &list->hwLayers[i];
if (get_hwc_compos_decision(cur, 1, overlay_win_cnt) == HWC_OVERLAY) {
ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i);
if (ret == 0) {
cur->compositionType = HWC_OVERLAY;
cur->hints = HWC_HINT_CLEAR_FB;
overlay_win_cnt++;
ctx->num_of_hwc_layer++;
ctx->num_of_fb_layer--;
ctx->num_2d_blit_layer = 1;
}
#if defined(BOARD_USES_HDMI)
SEC_HWC_Log(HWC_LOG_DEBUG, "ext disp vid = %d, cable status = %d, composition type = %d",
ctx->num_of_ext_disp_video_layer, ctx->hdmi_cable_status, compositionType);
if (ctx->num_of_ext_disp_video_layer >= 2) {
if ((ctx->hdmi_cable_status) &&
(compositionType == HWC_OVERLAY) &&
(prev_handle->usage & GRALLOC_USAGE_EXTERNAL_DISP)) {
cur->compositionType = HWC_FRAMEBUFFER;
ctx->num_of_hwc_layer--;
overlay_win_cnt--;
ctx->num_of_fb_layer++;
cur->hints = 0;
}
}
else
break;
}
#endif
}
#if defined(BOARD_USES_HDMI)
android::SecHdmiClient *mHdmiClient = android::SecHdmiClient::getInstance();
mHdmiClient = android::SecHdmiClient::getInstance();
mHdmiClient->setHdmiHwcLayer(ctx->num_of_hwc_layer);
if (ctx->num_of_ext_disp_video_layer > 1) {
mHdmiClient->setExtDispLayerNum(0);
}
#endif
if (list->numHwLayers != (ctx->num_of_fb_layer + ctx->num_of_hwc_layer))
@ -542,27 +653,27 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
reset_win_rect_info(&ctx->win[i]);
}
}
}
return 0;
}
static int hwc_set(hwc_composer_device_t *dev,
hwc_display_t dpy,
hwc_surface_t sur,
hwc_layer_list_t* list)
static int hwc_set(hwc_composer_device_1_t *dev,
size_t numDisplays,
hwc_display_contents_1_t** displays)
{
struct hwc_context_t *ctx = (struct hwc_context_t *)dev;
int skipped_window_mask = 0;
hwc_layer_t* cur;
hwc_layer_1_t* cur;
struct hwc_win_info_t *win;
int ret;
int pmem_phyaddr;
static int egl_check;
int egl_run = 0;
struct sec_img src_img;
struct sec_img dst_img;
struct sec_rect src_work_rect;
struct sec_rect dst_work_rect;
bool need_swap_buffers = ctx->num_of_fb_layer > 0;
for (uint32_t i = 0; i < numDisplays; i++) {
hwc_display_contents_1_t* list = displays[i];
memset(&src_img, 0, sizeof(src_img));
memset(&dst_img, 0, sizeof(dst_img));
@ -582,14 +693,45 @@ static int hwc_set(hwc_composer_device_t *dev,
ctx->win[i].status = HWC_WIN_FREE;
}
ctx->num_of_hwc_layer = 0;
need_swap_buffers = true;
if (sur == NULL && dpy == NULL)
if (list->sur == NULL && list->dpy == NULL) {
#ifdef SKIP_DUMMY_UI_LAY_DRAWING
ctx->fb_lay_skip_initialized = 0;
#endif
return HWC_EGL_ERROR;
}
}
if(ctx->num_of_hwc_layer > NUM_OF_WIN)
ctx->num_of_hwc_layer = NUM_OF_WIN;
/*
* H/W composer documentation states:
* There is an implicit layer containing opaque black
* pixels behind all the layers in the list.
* It is the responsibility of the hwcomposer module to make
* sure black pixels are output (or blended from).
*
* Since we're using a blitter, we need to erase the frame-buffer when
* switching to all-overlay mode.
*
*/
if (ctx->num_of_hwc_layer &&
ctx->num_of_fb_layer==0 && ctx->num_of_fb_layer_prev) {
#ifdef SKIP_DUMMY_UI_LAY_DRAWING
if (ctx->num_of_fb_lay_skip == 0)
#endif
{
glDisable(GL_SCISSOR_TEST);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST);
need_swap_buffers = true;
}
}
ctx->num_of_fb_layer_prev = ctx->num_of_fb_layer;
//compose hardware layers here
for (int i = 0; i < ctx->num_of_hwc_layer - ctx->num_2d_blit_layer; i++) {
win = &ctx->win[i];
@ -603,7 +745,7 @@ static int hwc_set(hwc_composer_device_t *dev,
* double buffered (2 or more) this buffer is already rendered.
* It is the redundant src buffer for FIMC rendering.
*/
ALOGD("SKIP FIMC rendering for Layer%d", win->layer_index);
#if defined(BOARD_USES_HDMI)
skip_hdmi_rendering = 1;
#endif
@ -646,33 +788,6 @@ static int hwc_set(hwc_composer_device_t *dev,
}
}
#ifdef SUB_TITLES_HWC
if (ctx->num_2d_blit_layer) {
g2d_rect srcRect;
g2d_rect dstRect;
win = &ctx->win[ctx->num_of_hwc_layer - 1];
cur = &list->hwLayers[win->layer_index];
set_src_dst_g2d_rect(cur, win, &srcRect, &dstRect);
ret = runG2d(ctx, &srcRect, &dstRect,
cur->transform);
if (ret < 0) {
SEC_HWC_Log(HWC_LOG_ERROR, "%s::runG2d fail : ret=%d\n",
__func__, ret);
skipped_window_mask |= (1 << (ctx->num_of_hwc_layer - 1));
goto g2d_error;
}
window_pan_display(win);
win->buf_index = (win->buf_index + 1) % NUM_OF_WIN_BUF;
if (win->power_state == 0)
window_show(win);
}
g2d_error:
#endif
if (skipped_window_mask) {
//turn off the free windows
for (int i = 0; i < NUM_OF_WIN; i++) {
@ -683,7 +798,7 @@ g2d_error:
}
}
if (0 < ctx->num_of_fb_layer) {
if (need_swap_buffers) {
#ifdef CHECK_EGL_FPS
check_fps();
#endif
@ -691,17 +806,7 @@ g2d_error:
unsigned char pixels[4];
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
#endif
egl_check = 1;
egl_run = 1;
} else {
if (egl_check == 1) {
egl_check = 0;
egl_run = 1;
}
}
if (egl_run == 1) {
EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
EGLBoolean sucess = eglSwapBuffers((EGLDisplay)list->dpy, (EGLSurface)list->sur);
if (!sucess)
return HWC_EGL_ERROR;
}
@ -732,14 +837,14 @@ g2d_error:
// To support S3D video playback (automatic TV mode change to 3D mode)
if (ctx->num_of_hwc_layer == 1) {
if (src_img.usage != prev_usage)
mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE); // V4L2_STD_1080P_60
mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE, android::SecHdmiClient::HDMI_2D); // V4L2_STD_1080P_60
if ((src_img.usage & GRALLOC_USAGE_PRIVATE_SBS_LR) ||
(src_img.usage & GRALLOC_USAGE_PRIVATE_SBS_RL))
mHdmiClient->setHdmiResolution(7209601); // V4L2_STD_TVOUT_720P_60_SBS_HALF
mHdmiClient->setHdmiResolution(DEFAULT_HDMI_S3D_SBS_RESOLUTION_VALUE, android::SecHdmiClient::HDMI_S3D_SBS); // V4L2_STD_TVOUT_720P_60_SBS_HALF
else if ((src_img.usage & GRALLOC_USAGE_PRIVATE_TB_LR) ||
(src_img.usage & GRALLOC_USAGE_PRIVATE_TB_RL))
mHdmiClient->setHdmiResolution(1080924); // V4L2_STD_TVOUT_1080P_24_TB
mHdmiClient->setHdmiResolution(DEFAULT_HDMI_S3D_TB_RESOLUTION_VALUE, android::SecHdmiClient::HDMI_S3D_TB); // V4L2_STD_TVOUT_1080P_24_TB
prev_usage = src_img.usage;
} else {
@ -747,7 +852,7 @@ g2d_error:
(prev_usage & GRALLOC_USAGE_PRIVATE_SBS_RL) ||
(prev_usage & GRALLOC_USAGE_PRIVATE_TB_LR) ||
(prev_usage & GRALLOC_USAGE_PRIVATE_TB_RL))
mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE); // V4L2_STD_1080P_60
mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE, android::SecHdmiClient::HDMI_2D); // V4L2_STD_1080P_60
prev_usage = 0;
}
@ -756,8 +861,7 @@ g2d_error:
if ((src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED)||
(src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP)) {
ADDRS * addr = (ADDRS *)(src_img.base);
mHdmiClient->blit2Hdmi(src_img.w, src_img.h,
mHdmiClient->blit2Hdmi(src_work_rect.w, src_work_rect.h,
src_img.format,
(unsigned int)addr->addr_y, (unsigned int)addr->addr_cbcr, (unsigned int)addr->addr_cbcr,
0, 0,
@ -767,7 +871,7 @@ g2d_error:
(src_img.format == HAL_PIXEL_FORMAT_YCrCb_420_SP) ||
(src_img.format == HAL_PIXEL_FORMAT_YCbCr_420_P) ||
(src_img.format == HAL_PIXEL_FORMAT_YV12)) {
mHdmiClient->blit2Hdmi(src_img.w, src_img.h,
mHdmiClient->blit2Hdmi(src_work_rect.w, src_work_rect.h,
src_img.format,
(unsigned int)ctx->fimc.params.src.buf_addr_phy_rgb_y,
(unsigned int)ctx->fimc.params.src.buf_addr_phy_cb,
@ -776,13 +880,90 @@ g2d_error:
android::SecHdmiClient::HDMI_MODE_VIDEO,
ctx->num_of_hwc_layer);
} else {
ALOGE("%s: Unsupported format = %d", __func__, src_img.format);
SEC_HWC_Log(HWC_LOG_ERROR, "%s: Unsupported format = %d", __func__, src_img.format);
}
}
#endif
}
return 0;
}
static void hwc_registerProcs(struct hwc_composer_device_1* dev,
hwc_procs_t const* procs)
{
struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
ctx->procs = const_cast<hwc_procs_t *>(procs);
}
static int hwc_query(struct hwc_composer_device_1* dev,
int what, int* value)
{
struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
switch (what) {
case HWC_BACKGROUND_LAYER_SUPPORTED:
// we don't support the background layer yet
value[0] = 0;
break;
case HWC_VSYNC_PERIOD:
// vsync period in nanosecond
value[0] = 1000000000.0 / 57;
break;
default:
// unsupported query
return -EINVAL;
}
return 0;
}
static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
int event, int enabled)
{
struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
switch (event) {
case HWC_EVENT_VSYNC:
int val = !!enabled;
int err = ioctl(ctx->win[0].fd, S3CFB_SET_VSYNC_INT, &val);
if (err < 0)
return -errno;
return 0;
}
return -EINVAL;
}
static void *hwc_vsync_sysfs_loop(void *data)
{
static char buf[4096];
int vsync_timestamp_fd;
fd_set exceptfds;
int res;
int64_t timestamp = 0;
hwc_context_t * ctx = (hwc_context_t *)(data);
vsync_timestamp_fd = open("/sys/devices/platform/samsung-pd.2/s3cfb.0/vsync_time", O_RDONLY);
char thread_name[64] = "hwcVsyncThread";
prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
setpriority(PRIO_PROCESS, 0, -20);
memset(buf, 0, sizeof(buf));
SEC_HWC_Log(HWC_LOG_DEBUG,"Using sysfs mechanism for VSYNC notification");
FD_ZERO(&exceptfds);
FD_SET(vsync_timestamp_fd, &exceptfds);
do {
ssize_t len = read(vsync_timestamp_fd, buf, sizeof(buf));
timestamp = strtoull(buf, NULL, 0);
ctx->procs->vsync(ctx->procs, 0, timestamp);
select(vsync_timestamp_fd + 1, NULL, NULL, &exceptfds, NULL);
lseek(vsync_timestamp_fd, 0, SEEK_SET);
} while (1);
return NULL;
}
static int hwc_device_close(struct hw_device_t *dev)
{
struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
@ -793,23 +974,7 @@ static int hwc_device_close(struct hw_device_t *dev)
SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyFimc fail", __func__);
ret = -1;
}
#ifdef SUB_TITLES_HWC
if (destroyG2d(&ctx->g2d) < 0) {
SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyG2d() fail", __func__);
ret = -1;
}
#endif
if (destroyMem(&ctx->s3c_mem) < 0) {
SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyMem fail", __func__);
ret = -1;
}
#ifdef USE_HW_PMEM
if (destroyPmem(&ctx->sec_pmem) < 0) {
SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyPmem fail", __func__);
ret = -1;
}
#endif
for (i = 0; i < NUM_OF_WIN; i++) {
if (window_close(&ctx->win[i]) < 0)
SEC_HWC_Log(HWC_LOG_DEBUG, "%s::window_close() fail", __func__);
@ -819,11 +984,17 @@ static int hwc_device_close(struct hw_device_t *dev)
}
return ret;
}
static int hwc_blank(struct hwc_composer_device_1 *dev, int dpy, int blank)
{
// We're using an older method of screen blanking based on
// early_suspend in the kernel. No need to do anything here.
return 0;
}
static int hwc_device_open(const struct hw_module_t* module, const char* name,
struct hw_device_t** device)
{
int status = 0;
int err = 0;
struct hwc_win_info_t *win;
if (strcmp(name, HWC_HARDWARE_COMPOSER))
@ -837,21 +1008,20 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
/* initialize the procs */
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = 0;
dev->device.common.version = HWC_DEVICE_API_VERSION_1_0;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = hwc_device_close;
dev->device.prepare = hwc_prepare;
dev->device.set = hwc_set;
dev->device.eventControl = hwc_eventControl;
dev->device.blank = hwc_blank;
dev->device.query = hwc_query;
dev->device.registerProcs = hwc_registerProcs;
*device = &dev->device.common;
//initializing
memset(&(dev->fimc), 0, sizeof(s5p_fimc_t));
memset(&(dev->s3c_mem), 0, sizeof(struct s3c_mem_t));
#ifdef USE_HW_PMEM
memset(&(dev->sec_pmem), 0, sizeof(sec_pmem_t));
#endif
/* open WIN0 & WIN1 here */
for (int i = 0; i < NUM_OF_WIN; i++) {
if (window_open(&(dev->win[i]), i) < 0) {
@ -902,18 +1072,6 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
}
#ifdef USE_HW_PMEM
if (createPmem(&dev->sec_pmem, PMEM_SIZE) < 0) {
SEC_HWC_Log(HWC_LOG_ERROR, "%s::initPmem(%d) fail", __func__, PMEM_SIZE);
}
#endif
if (createMem(&dev->s3c_mem, 0, 0) < 0) {
SEC_HWC_Log(HWC_LOG_ERROR, "%s::createMem() fail (size=0)", __func__);
status = -EINVAL;
goto err;
}
//create PP
if (createFimc(&dev->fimc) < 0) {
SEC_HWC_Log(HWC_LOG_ERROR, "%s::creatFimc() fail", __func__);
@ -921,13 +1079,12 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
goto err;
}
#ifdef SUB_TITLES_HWC
if (createG2d(&dev->g2d) < 0) {
SEC_HWC_Log(HWC_LOG_ERROR, "%s::createG2d() fail", __func__);
status = -EINVAL;
err = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_sysfs_loop, dev);
if (err) {
SEC_HWC_Log(HWC_LOG_ERROR, "%s::pthread_create() failed : %s", __func__, strerror(err));
status = -err;
goto err;
}
#endif
SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: hwc_device_open: SUCCESS", __func__);
@ -936,17 +1093,6 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
err:
if (destroyFimc(&dev->fimc) < 0)
SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyFimc() fail", __func__);
#ifdef SUB_TITLES_HWC
if (destroyG2d(&dev->g2d) < 0)
SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyG2d() fail", __func__);
#endif
if (destroyMem(&dev->s3c_mem) < 0)
SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyMem() fail", __func__);
#ifdef USE_HW_PMEM
if (destroyPmem(&dev->sec_pmem) < 0)
SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyPmem() fail", __func__);
#endif
for (int i = 0; i < NUM_OF_WIN; i++) {
if (window_close(&dev->win[i]) < 0)

File diff suppressed because it is too large Load Diff

@ -34,33 +34,33 @@
#include <errno.h>
#include <cutils/log.h>
#ifdef BOARD_USE_V4L2_ION
#include <ion.h>
#include "s5p_fimc_v4l2.h"
#include "sec_utils_v4l2.h"
#else
#include <linux/videodev.h>
#include "videodev2.h"
#include "s5p_fimc.h"
#include "sec_utils.h"
#endif
#include <linux/android_pmem.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <hardware/gralloc.h>
#include "linux/fb.h"
#include "s3c_lcd.h"
#include "s3c_mem.h"
#include "sec_format.h"
#define HWC_DEBUG
#define HWC_DEBUG 1
#if defined(BOARD_USES_FIMGAPI)
#include "sec_g2d.h"
//#define SUB_TITLES_HWC
#endif
#define SKIP_DUMMY_UI_LAY_DRAWING
#ifdef SKIP_DUMMY_UI_LAY_DRAWING
#define GL_WA_OVLY_ALL
#define THRES_FOR_SWAP (3427) /* 60sec in Frames. 57fps * 60 = 3427 */
#endif
#define NUM_OF_DUMMY_WIN (4)
#define NUM_OF_WIN (2)
#define NUM_OF_WIN_BUF (2)
#define NUM_OF_MEM_OBJ (1)
@ -72,27 +72,14 @@
#define MAX_RESIZING_RATIO_LIMIT (63)
#ifdef SAMSUNG_EXYNOS4x12
#ifdef BOARD_USE_V4L2_ION
#define PP_DEVICE_DEV_NAME "/dev/video4"
#else
#define PP_DEVICE_DEV_NAME "/dev/video3"
#endif
#endif
#ifdef SAMSUNG_EXYNOS4210
#define PP_DEVICE_DEV_NAME "/dev/video1"
#endif
#define S3C_MEM_DEV_NAME "/dev/s3c-mem"
#define PMEM_DEVICE_DEV_NAME "/dev/pmem_gpu1"
#ifdef BOARD_USE_V4L2_ION
#undef USE_HW_PMEM
#else
#define USE_HW_PMEM
#endif
#define PMEM_SIZE (1920 * 1280 * 2)
/* cacheable configuration */
#define V4L2_CID_CACHEABLE (V4L2_CID_BASE+40)
struct sec_rect {
int32_t x;
@ -127,34 +114,6 @@ inline int SEC_MAX(int x, int y)
return ((x > y) ? x : y);
}
struct s3c_mem_t {
int fd;
struct s3c_mem_alloc mem_alloc[NUM_OF_MEM_OBJ];
};
#ifdef USE_HW_PMEM
typedef struct __sec_pmem_alloc {
int fd;
int total_size;
int offset;
int size;
unsigned int virt_addr;
unsigned int phys_addr;
} sec_pmem_alloc_t;
typedef struct __sec_pmem {
int pmem_master_fd;
void *pmem_master_base;
int pmem_total_size;
sec_pmem_alloc_t sec_pmem_alloc[NUM_OF_MEM_OBJ];
} sec_pmem_t;
inline size_t roundUpToPageSize(size_t x)
{
return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
}
#endif
struct hwc_win_info_t {
int fd;
int size;
@ -167,9 +126,6 @@ struct hwc_win_info_t {
int layer_index;
int status;
int vsync;
#ifdef BOARD_USE_V4L2_ION
int ion_fd;
#endif
struct fb_fix_screeninfo fix_info;
struct fb_var_screeninfo var_info;
@ -187,24 +143,46 @@ enum {
HWC_VIRT_MEM_TYPE,
};
#ifdef SKIP_DUMMY_UI_LAY_DRAWING
struct hwc_ui_lay_info{
uint32_t layer_prev_buf;
int layer_index;
int status;
};
#endif
struct hwc_context_t {
hwc_composer_device_t device;
hwc_composer_device_1_t device;
/* our private state goes below here */
struct hwc_win_info_t win[NUM_OF_WIN];
struct fb_var_screeninfo lcd_info;
s5p_fimc_t fimc;
#ifdef SUB_TITLES_HWC
sec_g2d_t g2d;
#ifdef SKIP_DUMMY_UI_LAY_DRAWING
struct hwc_ui_lay_info win_virt[NUM_OF_DUMMY_WIN];
int fb_lay_skip_initialized;
int num_of_fb_lay_skip;
#ifdef GL_WA_OVLY_ALL
int ui_skip_frame_cnt;
#endif
struct s3c_mem_t s3c_mem;
#ifdef USE_HW_PMEM
sec_pmem_t sec_pmem;
#endif
struct fb_var_screeninfo lcd_info;
s5p_fimc_t fimc;
hwc_procs_t *procs;
pthread_t uevent_thread;
pthread_t vsync_thread;
int num_of_fb_layer;
int num_of_hwc_layer;
int num_of_fb_layer_prev;
int num_2d_blit_layer;
uint32_t layer_prev_buf[NUM_OF_WIN];
int num_of_ext_disp_layer;
int num_of_ext_disp_video_layer;
#ifdef BOARD_USES_HDMI
int hdmi_cable_status;
#endif
};
typedef enum _LOG_LEVEL {
@ -308,24 +286,6 @@ int runFimc(struct hwc_context_t *ctx,
struct sec_img *src_img, struct sec_rect *src_rect,
struct sec_img *dst_img, struct sec_rect *dst_rect,
uint32_t transform);
#ifdef SUB_TITLES_HWC
int runG2d(struct hwc_context_t *ctx,
g2d_rect *src_rect, g2d_rect *dst_rect,
uint32_t transform);
int destroyG2d(sec_g2d_t *g2d);
int createG2d(sec_g2d_t *g2d);
#endif
int createMem (struct s3c_mem_t *mem, unsigned int index, unsigned int size);
int destroyMem(struct s3c_mem_t *mem);
int checkMem (struct s3c_mem_t *mem, unsigned int index, unsigned int size);
#ifdef USE_HW_PMEM
int createPmem (sec_pmem_t *pm, unsigned int size);
int destroyPmem(sec_pmem_t *pm);
int checkPmem (sec_pmem_t *pm, unsigned int index, unsigned int size);
#endif
int check_yuv_format(unsigned int color_format);
#endif /* ANDROID_SEC_HWC_UTILS_H_*/

Loading…
Cancel
Save