summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--device_base.mk4
-rw-r--r--include/hal_public.h163
-rwxr-xr-xinclude/sec_format.h43
-rwxr-xr-xinclude/sec_lcd.h49
-rw-r--r--include/sec_utils.h331
-rw-r--r--libhwcomposer/Android.mk35
-rw-r--r--libhwcomposer/SecHWC.cpp530
-rw-r--r--libhwcomposer/SecHWCUtils.cpp871
-rw-r--r--libhwcomposer/SecHWCUtils.h139
9 files changed, 2163 insertions, 2 deletions
diff --git a/device_base.mk b/device_base.mk
index d9404e6..a443a89 100644
--- a/device_base.mk
+++ b/device_base.mk
@@ -106,8 +106,8 @@ PRODUCT_PACKAGES += \
# Misc other modules
PRODUCT_PACKAGES += \
lights.s5pc110 \
- overlay.s5pc110 \
- sensors.herring
+ hwcomposer.s5pc110 \
+ sensors.herring
# Camera
PRODUCT_PACKAGES += \
diff --git a/include/hal_public.h b/include/hal_public.h
new file mode 100644
index 0000000..9764ee8
--- /dev/null
+++ b/include/hal_public.h
@@ -0,0 +1,163 @@
+/* Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HAL_PUBLIC_H
+#define HAL_PUBLIC_H
+
+/* Authors of third party hardware composer (HWC) modules will need to include
+ * this header to access functionality in the gralloc and framebuffer HALs.
+ */
+
+#include <hardware/gralloc.h>
+
+#define ALIGN(x,a) (((x) + (a) - 1L) & ~((a) - 1L))
+#define HW_ALIGN 32
+
+/* This can be tuned down as appropriate for the SOC.
+ *
+ * IMG formats are usually a single sub-alloc.
+ * Some OEM video formats are two sub-allocs (Y, UV planes).
+ * Future OEM video formats might be three sub-allocs (Y, U, V planes).
+ */
+#define MAX_SUB_ALLOCS 3
+
+typedef struct
+{
+ native_handle_t base;
+
+ /* These fields can be sent cross process. They are also valid
+ * to duplicate within the same process.
+ *
+ * A table is stored within psPrivateData on gralloc_module_t (this
+ * is obviously per-process) which maps stamps to a mapped
+ * PVRSRV_CLIENT_MEM_INFO in that process. Each map entry has a lock
+ * count associated with it, satisfying the requirements of the
+ * Android API. This also prevents us from leaking maps/allocations.
+ *
+ * This table has entries inserted either by alloc()
+ * (alloc_device_t) or map() (gralloc_module_t). Entries are removed
+ * by free() (alloc_device_t) and unmap() (gralloc_module_t).
+ *
+ * As a special case for framebuffer_device_t, framebuffer_open()
+ * will add and framebuffer_close() will remove from this table.
+ */
+
+#define IMG_NATIVE_HANDLE_NUMFDS MAX_SUB_ALLOCS
+ /* The `fd' field is used to "export" a meminfo to another process.
+ * Therefore, it is allocated by alloc_device_t, and consumed by
+ * gralloc_module_t. The framebuffer_device_t does not need a handle,
+ * and the special value IMG_FRAMEBUFFER_FD is used instead.
+ */
+ int fd[MAX_SUB_ALLOCS];
+
+#define IMG_NATIVE_HANDLE_NUMINTS ((sizeof(unsigned long long) / sizeof(int)) + 5)
+ /* A KERNEL unique identifier for any exported kernel meminfo. Each
+ * exported kernel meminfo will have a unique stamp, but note that in
+ * userspace, several meminfos across multiple processes could have
+ * the same stamp. As the native_handle can be dup(2)'d, there could be
+ * multiple handles with the same stamp but different file descriptors.
+ */
+ unsigned long long ui64Stamp;
+
+ /* This is used for buffer usage validation when locking a buffer,
+ * and also in WSEGL (for the composition bypass feature).
+ */
+ int usage;
+
+ //int dummy;
+ /* In order to do efficient cache flushes we need the buffer dimensions
+ * and format. These are available on the ANativeWindowBuffer,
+ * but the platform doesn't pass them down to the graphics HAL.
+ *
+ * These fields are also used in the composition bypass. In this
+ * capacity, these are the "real" values for the backing allocation.
+ */
+ int iWidth;
+ int iHeight;
+ int iFormat;
+ unsigned int uiBpp;
+}
+__attribute__((aligned(sizeof(int)),packed)) IMG_native_handle_t;
+
+typedef struct
+{
+ framebuffer_device_t base;
+
+ /* The HWC was loaded. post() is no longer responsible for presents */
+ int bBypassPost;
+
+ /* Custom-blit components in lieu of overlay hardware */
+ int (*Blit)(framebuffer_device_t *device, buffer_handle_t src,
+ buffer_handle_t dest, int w, int h, int x, int y);
+
+ /* HWC path for present posts */
+ int (*Post2)(framebuffer_device_t *fb, buffer_handle_t *buffers,
+ int num_buffers, void *data, int data_length);
+}
+IMG_framebuffer_device_public_t;
+
+typedef struct IMG_gralloc_module_public_t
+{
+ gralloc_module_t base;
+
+ /* If the framebuffer has been opened, this will point to the
+ * framebuffer device data required by the allocator, WSEGL
+ * modules and composerhal.
+ */
+ IMG_framebuffer_device_public_t *psFrameBufferDevice;
+
+ int (*GetPhyAddrs)(struct IMG_gralloc_module_public_t const* module,
+ buffer_handle_t handle,
+ unsigned int auiPhyAddr[MAX_SUB_ALLOCS]);
+}
+IMG_gralloc_module_public_t;
+
+typedef struct
+{
+ int l, t, w, h;
+}
+IMG_write_lock_rect_t;
+
+typedef struct IMG_buffer_format_public_t
+{
+ /* Buffer formats are returned as a linked list */
+ struct IMG_buffer_format_public_t *psNext;
+
+ /* HAL_PIXEL_FORMAT_... enumerant */
+ int iHalPixelFormat;
+
+ /* WSEGL_PIXELFORMAT_... enumerant */
+ int iWSEGLPixelFormat;
+
+ /* Friendly name for format */
+ const char *const szName;
+
+ /* Bits (not bytes) per pixel */
+ unsigned int uiBpp;
+
+ /* GPU output format (creates EGLConfig for format) */
+ int bGPURenderable;
+}
+IMG_buffer_format_public_t;
+
+#endif /* HAL_PUBLIC_H */
diff --git a/include/sec_format.h b/include/sec_format.h
new file mode 100755
index 0000000..99a47bf
--- /dev/null
+++ b/include/sec_format.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright@ Samsung Electronics Co. LTD
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+#ifndef _SEC_FORMAT_H_
+#define _SEC_FORMAT_H_
+
+/* enum related to pixel format */
+
+enum {
+ HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x100,
+ HAL_PIXEL_FORMAT_YCbCr_420_P = 0x101,
+ HAL_PIXEL_FORMAT_YCbCr_420_I = 0x102,
+ HAL_PIXEL_FORMAT_CbYCrY_422_I = 0x103,
+ HAL_PIXEL_FORMAT_CbYCrY_420_I = 0x104,
+ HAL_PIXEL_FORMAT_YCbCr_422_P = 0x105,
+ HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x106,
+ // support custom format for zero copy
+ HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP = 0x110,
+ HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP = 0x111,
+ HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED = 0x112,
+ HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP = 0x113,
+ HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP = 0x114,
+ HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I = 0x115,
+ HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I = 0x116,
+ HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I = 0x117,
+ HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I = 0x118,
+ HAL_PIXEL_FORMAT_CUSTOM_MAX
+};
+
+#endif
diff --git a/include/sec_lcd.h b/include/sec_lcd.h
new file mode 100755
index 0000000..b5451b7
--- /dev/null
+++ b/include/sec_lcd.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright@ Samsung Electronics Co. LTD
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _SEC_FB_LCD_
+#define _SEC_FB_LCD_
+
+/*
+ * S T R U C T U R E S F O R C U S T O M I O C T L S
+ *
+*/
+struct secfb_user_window {
+ int x;
+ int y;
+};
+
+/*
+ * C U S T O M I O C T L S
+ *
+*/
+
+#define FBIO_WAITFORVSYNC _IO ('F', 32)
+#define SECFB_WIN_POSITION _IOW ('F', 203, struct secfb_user_window)
+
+
+#define DEFAULT_LCD_WIDTH (480)
+#define DEFAULT_LCD_HEIGHT (800)
+#define DEFAULT_LCD_BPP (32)
+
+/***************** LCD frame buffer *****************/
+#define FB0_NAME "/dev/fb0"
+#define FB1_NAME "/dev/fb1"
+#define FB2_NAME "/dev/fb2"
+#define FB3_NAME "/dev/fb3"
+#define FB4_NAME "/dev/fb4"
+
+#endif
diff --git a/include/sec_utils.h b/include/sec_utils.h
new file mode 100644
index 0000000..80b4493
--- /dev/null
+++ b/include/sec_utils.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright@ Samsung Electronics Co. LTD
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+#ifndef __SAMSUNG_SYSLSI_SEC_COMMON_H__
+#define __SAMSUNG_SYSLSI_SEC_COMMON_H__
+
+//---------------------------------------------------------//
+// Include
+//---------------------------------------------------------//
+
+#include <hardware/hardware.h>
+#include "sec_format.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <linux/videodev2.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+//---------------------------------------------------------//
+// Common structure //
+//---------------------------------------------------------//
+struct ADDRS {
+ unsigned int addr_y;
+ unsigned int addr_cbcr;
+ unsigned int buf_idx;
+ unsigned int reserved;
+};
+
+//---------------------------------------------------------//
+// Common function //
+//---------------------------------------------------------//
+inline int HAL_PIXEL_FORMAT_2_V4L2_PIX(int HAL_PIXEL_FORMAT)
+{
+ int V4L2_PIX = -1;
+
+ switch (HAL_PIXEL_FORMAT) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ V4L2_PIX = V4L2_PIX_FMT_RGB32;
+ break;
+
+ case HAL_PIXEL_FORMAT_RGB_888:
+ V4L2_PIX = V4L2_PIX_FMT_RGB24;
+ break;
+
+ case HAL_PIXEL_FORMAT_RGB_565:
+ V4L2_PIX = V4L2_PIX_FMT_RGB565;
+ break;
+
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ //V4L2_PIX = V4L2_PIX_FMT_BGR32; // this is not proper on fimc.
+ V4L2_PIX = V4L2_PIX_FMT_RGB32;
+ break;
+
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ V4L2_PIX = V4L2_PIX_FMT_RGB555X;
+ break;
+
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ V4L2_PIX = V4L2_PIX_FMT_RGB444;
+ break;
+
+ case HAL_PIXEL_FORMAT_YV12:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P:
+ V4L2_PIX = V4L2_PIX_FMT_YUV420;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP:
+ V4L2_PIX = V4L2_PIX_FMT_NV61;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP:
+ V4L2_PIX = V4L2_PIX_FMT_NV12;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I:
+ V4L2_PIX = V4L2_PIX_FMT_YUYV;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_422_P:
+ V4L2_PIX = V4L2_PIX_FMT_YUV422P;
+ break;
+
+ case HAL_PIXEL_FORMAT_CbYCrY_422_I:
+ case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I:
+ V4L2_PIX = V4L2_PIX_FMT_UYVY;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP:
+ V4L2_PIX = V4L2_PIX_FMT_NV16;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP:
+ V4L2_PIX = V4L2_PIX_FMT_NV21;
+ break;
+
+ case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED:
+ V4L2_PIX = V4L2_PIX_FMT_NV12T;
+ break;
+
+ case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I:
+ V4L2_PIX = V4L2_PIX_FMT_YVYU;
+ break;
+
+ case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I:
+ V4L2_PIX = V4L2_PIX_FMT_VYUY;
+ break;
+
+ default:
+ LOGE("%s::unmatched HAL_PIXEL_FORMAT color_space(0x%x)\n",
+ __func__, HAL_PIXEL_FORMAT);
+ break;
+ }
+
+ return V4L2_PIX;
+}
+
+inline int V4L2_PIX_2_HAL_PIXEL_FORMAT(int V4L2_PIX)
+{
+ int HAL_PIXEL_FORMAT = -1;
+
+ switch (V4L2_PIX) {
+ case V4L2_PIX_FMT_RGB32:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888;
+ //HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBX_8888;
+ break;
+
+ case V4L2_PIX_FMT_RGB24:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGB_888;
+ break;
+
+ case V4L2_PIX_FMT_RGB565:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
+ break;
+
+ case V4L2_PIX_FMT_BGR32:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_BGRA_8888;
+ break;
+
+ case V4L2_PIX_FMT_RGB555X:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBA_5551;
+ break;
+
+ case V4L2_PIX_FMT_RGB444:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBA_4444;
+ break;
+
+ case V4L2_PIX_FMT_YUV420:
+ //HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YV12;
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCbCr_420_P;
+ break;
+
+ case V4L2_PIX_FMT_NV16:
+ //HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCrCb_422_SP;
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP;
+ break;
+
+ case V4L2_PIX_FMT_NV12:
+ //HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP;
+ break;
+
+ case V4L2_PIX_FMT_YUYV:
+ //HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCbCr_422_I;
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I;
+ break;
+
+ case V4L2_PIX_FMT_YUV422P:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCbCr_422_P;
+ break;
+
+ case V4L2_PIX_FMT_UYVY:
+ //HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CbYCrY_422_I;
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I;
+ break;
+
+ case V4L2_PIX_FMT_NV21:
+ //HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCbCr_420_SP;
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP;
+ break;
+
+ case V4L2_PIX_FMT_NV12T:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED;
+ break;
+
+ case V4L2_PIX_FMT_NV61:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP;
+ break;
+
+ case V4L2_PIX_FMT_YVYU:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I;
+ break;
+
+ case V4L2_PIX_FMT_VYUY:
+ HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I;
+ break;
+
+ default:
+ LOGE("%s::unmatched V4L2_PIX color_space(%d)\n",
+ __func__, V4L2_PIX);
+ break;
+ }
+
+ return HAL_PIXEL_FORMAT;
+}
+
+#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5)
+#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7)
+#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13)
+
+#define GET_32BPP_FRAME_SIZE(w, h) (((w) * (h)) << 2)
+#define GET_24BPP_FRAME_SIZE(w, h) (((w) * (h)) * 3)
+#define GET_16BPP_FRAME_SIZE(w, h) (((w) * (h)) << 1)
+
+inline unsigned int FRAME_SIZE(int HAL_PIXEL_FORMAT, int w, int h)
+{
+ unsigned int frame_size = 0;
+ unsigned int size = 0;
+
+ switch (HAL_PIXEL_FORMAT) {
+ // 16bpp
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ //case HAL_PIXEL_FORMAT_ARGB_1555:
+ //case HAL_PIXEL_FORMAT_BGRA_5551:
+ //case HAL_PIXEL_FORMAT_ABGR_1555:
+
+ //case HAL_PIXEL_FORMAT_RGBX_5551:
+ //case HAL_PIXEL_FORMAT_XRGB_1555:
+ //case HAL_PIXEL_FORMAT_BGRX_5551:
+ //case HAL_PIXEL_FORMAT_XBGR_1555:
+
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ //case HAL_PIXEL_FORMAT_ARGB_4444:
+ //case HAL_PIXEL_FORMAT_BGRA_4444:
+ //case HAL_PIXEL_FORMAT_ABGR_4444:
+
+ //case HAL_PIXEL_FORMAT_RGBX_4444:
+ //case HAL_PIXEL_FORMAT_XRGB_4444:
+ //case HAL_PIXEL_FORMAT_BGRX_4444:
+ //case HAL_PIXEL_FORMAT_XBGR_4444:
+ frame_size = GET_16BPP_FRAME_SIZE(w, h);
+ break;
+
+ // 24bpp
+ case HAL_PIXEL_FORMAT_RGB_888:
+ frame_size = GET_24BPP_FRAME_SIZE(w, h);
+ break;
+
+ // 32bpp
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ //case HAL_PIXEL_FORMAT_ARGB_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ //case HAL_PIXEL_FORMAT_ABGR_8888:
+
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ //case HAL_PIXEL_FORMAT_XRGB_8888:
+ //case HAL_PIXEL_FORMAT_BGRX_8888:
+ //case HAL_PIXEL_FORMAT_XBGR_8888:
+ frame_size = GET_32BPP_FRAME_SIZE(w, h);
+ break;
+
+ // 12bpp
+ case HAL_PIXEL_FORMAT_YV12:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P:
+ case HAL_PIXEL_FORMAT_YCbCr_420_I:
+ case HAL_PIXEL_FORMAT_CbYCrY_420_I:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP:
+ size = w * h;
+ // frame_size = width * height * 3 / 2;
+ // sw5771.park : very curious...
+ // frame_size = size + ((size / 4) * 2);
+ frame_size = size + ((size >> 2) << 1);
+ break;
+
+ case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED:
+ frame_size = ALIGN_TO_8KB(ALIGN_TO_128B(w) * ALIGN_TO_32B(h))
+ + ALIGN_TO_8KB(ALIGN_TO_128B(w) * ALIGN_TO_32B(h >> 1));
+ break;
+
+ // 16bpp
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ case HAL_PIXEL_FORMAT_YCbCr_422_P:
+ case HAL_PIXEL_FORMAT_CbYCrY_422_I:
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I:
+ case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I:
+ case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I:
+ case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I:
+ frame_size = GET_16BPP_FRAME_SIZE(w, h);
+ break;
+
+ default:
+ LOGD("%s::no matching source colorformat(0x%x), w(%d), h(%d) fail\n",
+ __func__, HAL_PIXEL_FORMAT, w, h);
+ break;
+ }
+
+ return frame_size;
+}
+
+#endif //__SAMSUNG_SYSLSI_SEC_COMMON_H__
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
new file mode 100644
index 0000000..cfdd5f8
--- /dev/null
+++ b/libhwcomposer/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# 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
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ifneq ($(filter crespo crespo4g,$(TARGET_DEVICE)),)
+
+LOCAL_PATH:= $(call my-dir)
+# HAL module implemenation, not prelinked and stored in
+# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.product.board>.so
+
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SHARED_LIBRARIES := liblog libcutils libEGL libhardware
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../include
+
+LOCAL_SRC_FILES := SecHWCUtils.cpp SecHWC.cpp
+
+LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_SHARED_LIBRARY)
+
+endif
diff --git a/libhwcomposer/SecHWC.cpp b/libhwcomposer/SecHWC.cpp
new file mode 100644
index 0000000..cbed30d
--- /dev/null
+++ b/libhwcomposer/SecHWC.cpp
@@ -0,0 +1,530 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ *
+ * @author Rama, Meka(v.meka@samsung.com)
+ Sangwoo, Park(sw5771.park@samsung.com)
+ Jamie Oh (jung-min.oh@samsung.com)
+ * @date 2011-07-28
+ *
+ */
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <EGL/egl.h>
+#include "SecHWCUtils.h"
+
+static IMG_gralloc_module_public_t *gpsGrallocModule;
+
+static int hwc_device_open(const struct hw_module_t* module, const char* name,
+ struct hw_device_t** device);
+
+static struct hw_module_methods_t hwc_module_methods = {
+ open: hwc_device_open
+};
+
+hwc_module_t HAL_MODULE_INFO_SYM = {
+ common: {
+ tag: HARDWARE_MODULE_TAG,
+ version_major: 1,
+ version_minor: 0,
+ id: HWC_HARDWARE_MODULE_ID,
+ name: "Samsung S5PC11X hwcomposer module",
+ author: "SAMSUNG",
+ methods: &hwc_module_methods,
+ }
+};
+
+static void dump_layer(hwc_layer_t const* l) {
+ LOGD("\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,
+ l->sourceCrop.top,
+ l->sourceCrop.right,
+ l->sourceCrop.bottom,
+ l->displayFrame.left,
+ l->displayFrame.top,
+ l->displayFrame.right,
+ l->displayFrame.bottom);
+}
+
+static int set_src_dst_info(hwc_layer_t *cur,
+ struct hwc_win_info_t *win,
+ struct sec_img *src_img,
+ struct sec_img *dst_img,
+ struct sec_rect *src_rect,
+ struct sec_rect *dst_rect,
+ int win_idx)
+{
+ IMG_native_handle_t *prev_handle = (IMG_native_handle_t *)(cur->handle);
+
+ // set src image
+ src_img->w = prev_handle->iWidth;
+ src_img->h = prev_handle->iHeight;
+ src_img->format = prev_handle->iFormat;
+ src_img->base = NULL;
+ src_img->offset = 0;
+ src_img->mem_id =0;
+
+ src_img->mem_type = HWC_PHYS_MEM_TYPE;
+ src_img->w = (src_img->w + 15) & (~15);
+ src_img->h = (src_img->h + 1) & (~1) ;
+
+ //set src rect
+ src_rect->x = SEC_MAX(cur->sourceCrop.left, 0);
+ src_rect->y = SEC_MAX(cur->sourceCrop.top, 0);
+ src_rect->w = SEC_MAX(cur->sourceCrop.right - cur->sourceCrop.left, 0);
+ src_rect->w = SEC_MIN(src_rect->w, src_img->w - src_rect->x);
+ src_rect->h = SEC_MAX(cur->sourceCrop.bottom - cur->sourceCrop.top, 0);
+ src_rect->h = SEC_MIN(src_rect->h, src_img->h - src_rect->y);
+
+ //set dst image
+ dst_img->w = win->lcd_info.xres;
+ dst_img->h = win->lcd_info.yres;
+
+ switch (win->lcd_info.bits_per_pixel) {
+ case 32:
+ dst_img->format = HAL_PIXEL_FORMAT_RGBX_8888;
+ break;
+ default:
+ dst_img->format = HAL_PIXEL_FORMAT_RGB_565;
+ break;
+ }
+
+ dst_img->base = win->addr[win->buf_index];
+ dst_img->offset = 0;
+ dst_img->mem_id = 0;
+ dst_img->mem_type = HWC_PHYS_MEM_TYPE;
+
+ //set dst rect
+ //fimc dst image will be stored from left top corner
+ dst_rect->x = 0;
+ dst_rect->y = 0;
+ dst_rect->w = win->rect_info.w;
+ dst_rect->h = win->rect_info.h;
+
+ LOGV("%s::sr_x %d sr_y %d sr_w %d sr_h %d dr_x %d dr_y %d dr_w %d dr_h %d ",
+ __func__, src_rect->x, src_rect->y, src_rect->w, src_rect->h,
+ dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h);
+
+ return 0;
+}
+
+static int get_hwc_compos_decision(hwc_layer_t* cur)
+{
+ if(cur->flags & HWC_SKIP_LAYER || !cur->handle) {
+ LOGV("%s::is_skip_layer %d cur->handle %x",
+ __func__, cur->flags & HWC_SKIP_LAYER, (uint32_t)cur->handle);
+ return HWC_FRAMEBUFFER;
+ }
+
+ IMG_native_handle_t *prev_handle = (IMG_native_handle_t *)(cur->handle);
+ int compositionType = HWC_FRAMEBUFFER;
+
+ /* check here....if we have any resolution constraints */
+ if (((cur->sourceCrop.right - cur->sourceCrop.left) < 16) ||
+ ((cur->sourceCrop.bottom - cur->sourceCrop.top) < 8))
+ return compositionType;
+
+ if ((cur->transform == HAL_TRANSFORM_ROT_90) ||
+ (cur->transform == HAL_TRANSFORM_ROT_270)) {
+ if(((cur->displayFrame.right - cur->displayFrame.left) < 4)||
+ ((cur->displayFrame.bottom - cur->displayFrame.top) < 8))
+ return compositionType;
+ } else if (((cur->displayFrame.right - cur->displayFrame.left) < 8) ||
+ ((cur->displayFrame.bottom - cur->displayFrame.top) < 4))
+ return compositionType;
+
+ if((prev_handle->usage & GRALLOC_USAGE_PHYS_CONTIG) &&
+ (cur->blending = HWC_BLENDING_NONE))
+ compositionType = HWC_OVERLAY;
+ else
+ compositionType = HWC_FRAMEBUFFER;
+
+ LOGV("%s::compositionType %d bpp %d format %x usage %x",
+ __func__,compositionType, prev_handle->uiBpp, prev_handle->iFormat,
+ prev_handle->usage & GRALLOC_USAGE_PHYS_CONTIG);
+
+ return compositionType;
+}
+
+static int assign_overlay_window(struct hwc_context_t *ctx,
+ hwc_layer_t *cur,
+ int win_idx,
+ int layer_idx)
+{
+ struct hwc_win_info_t *win;
+ sec_rect rect;
+ int ret = 0;
+
+ if(NUM_OF_WIN <= win_idx)
+ return -1;
+
+ win = &ctx->win[win_idx];
+
+ rect.x = SEC_MAX(cur->displayFrame.left, 0);
+ rect.y = SEC_MAX(cur->displayFrame.top, 0);
+ rect.w = SEC_MIN(cur->displayFrame.right - rect.x, win->lcd_info.xres - rect.x);
+ rect.h = SEC_MIN(cur->displayFrame.bottom - rect.y, win->lcd_info.yres - rect.y);
+ win->set_win_flag = 0;
+
+ if((rect.x != win->rect_info.x) || (rect.y != win->rect_info.y) ||
+ (rect.w != win->rect_info.w) || (rect.h != win->rect_info.h)){
+ win->rect_info.x = rect.x;
+ win->rect_info.y = rect.y;
+ win->rect_info.w = rect.w;
+ win->rect_info.h = rect.h;
+ win->set_win_flag = 1;
+ win->layer_prev_buf = 0;
+ }
+
+ win->layer_index = layer_idx;
+ win->status = HWC_WIN_RESERVED;
+
+ LOGV("%s:: win_x %d win_y %d win_w %d win_h %d lay_idx %d win_idx %d",
+ __func__, win->rect_info.x, win->rect_info.y, win->rect_info.w,
+ win->rect_info.h, win->layer_index, win_idx );
+
+ return 0;
+}
+
+static void reset_win_rect_info(hwc_win_info_t *win)
+{
+ win->rect_info.x = 0;
+ win->rect_info.y = 0;
+ win->rect_info.w = 0;
+ win->rect_info.h = 0;
+ return;
+}
+
+static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
+{
+
+ struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
+ int overlay_win_cnt = 0;
+ int compositionType = 0;
+ int ret;
+
+ //if geometry is not changed, there is no need to do any work here
+ if( !list || (!(list->flags & HWC_GEOMETRY_CHANGED)))
+ return 0;
+
+ //all the windows are free here....
+ for (int i = 0; i < NUM_OF_WIN; i++) {
+ ctx->win[i].status = HWC_WIN_FREE;
+ ctx->win[i].buf_index = 0;
+ }
+ ctx->num_of_hwc_layer = 0;
+ ctx->num_of_fb_layer = 0;
+ LOGV("%s:: hwc_prepare list->numHwLayers %d", __func__, list->numHwLayers);
+
+ for (int i = 0; i < list->numHwLayers ; i++) {
+ hwc_layer_t* cur = &list->hwLayers[i];
+
+ if (overlay_win_cnt < NUM_OF_WIN) {
+ compositionType = get_hwc_compos_decision(cur);
+
+ if (compositionType == HWC_FRAMEBUFFER) {
+ cur->compositionType = HWC_FRAMEBUFFER;
+ ctx->num_of_fb_layer++;
+ } else {
+ ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i);
+ if (ret != 0) {
+ cur->compositionType = HWC_FRAMEBUFFER;
+ ctx->num_of_fb_layer++;
+ continue;
+ }
+
+ cur->compositionType = HWC_OVERLAY;
+ cur->hints = HWC_HINT_CLEAR_FB;
+ overlay_win_cnt++;
+ ctx->num_of_hwc_layer++;
+ }
+ } else {
+ cur->compositionType = HWC_FRAMEBUFFER;
+ ctx->num_of_fb_layer++;
+ }
+ }
+
+ if(list->numHwLayers != (ctx->num_of_fb_layer + ctx->num_of_hwc_layer))
+ LOGV("%s:: numHwLayers %d num_of_fb_layer %d num_of_hwc_layer %d ",
+ __func__, list->numHwLayers, ctx->num_of_fb_layer,
+ ctx->num_of_hwc_layer);
+
+ if (overlay_win_cnt < NUM_OF_WIN) {
+ //turn off the free windows
+ for (int i = overlay_win_cnt; i < NUM_OF_WIN; i++) {
+ window_hide(&ctx->win[i]);
+ 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)
+{
+ struct hwc_context_t *ctx = (struct hwc_context_t *)dev;
+ unsigned int phyAddr[MAX_NUM_PLANES];
+ int skipped_window_mask = 0;
+ hwc_layer_t* cur;
+ struct hwc_win_info_t *win;
+ int ret;
+ struct sec_img src_img;
+ struct sec_img dst_img;
+ struct sec_rect src_rect;
+ struct sec_rect dst_rect;
+
+ if (!list) {
+ /* turn off the all windows */
+ for (int i = 0; i < NUM_OF_WIN; i++) {
+ window_hide(&ctx->win[i]);
+ reset_win_rect_info(&ctx->win[i]);
+ ctx->win[i].status = HWC_WIN_FREE;
+ }
+ ctx->num_of_hwc_layer = 0;
+ return 0;
+ }
+
+ if(ctx->num_of_hwc_layer > NUM_OF_WIN)
+ ctx->num_of_hwc_layer = NUM_OF_WIN;
+
+ if (0 < ctx->num_of_fb_layer) {
+ EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
+ if (!sucess) {
+ return HWC_EGL_ERROR;
+ }
+ }
+
+ /* compose hardware layers here */
+ for (uint32_t i = 0; i < ctx->num_of_hwc_layer; i++) {
+ win = &ctx->win[i];
+ if (win->status == HWC_WIN_RESERVED) {
+ cur = &list->hwLayers[win->layer_index];
+
+ if (cur->compositionType == HWC_OVERLAY) {
+ /* Skip duplicate frame rendering */
+ if (win->layer_prev_buf == (uint32_t)cur->handle)
+ continue;
+
+ win->layer_prev_buf = (uint32_t)cur->handle;
+
+ ret = gpsGrallocModule->GetPhyAddrs(gpsGrallocModule,
+ cur->handle, phyAddr);
+ if (ret) {
+ LOGE("%s::GetPhyAddrs fail : ret=%d\n", __func__, ret);
+ skipped_window_mask |= (1 << i);
+ continue;
+ }
+
+ /* initialize the src & dist context for fimc */
+ set_src_dst_info (cur, win, &src_img, &dst_img, &src_rect,
+ &dst_rect, i);
+
+ ret = runFimc(ctx, &src_img, &src_rect, &dst_img, &dst_rect,
+ phyAddr, cur->transform);
+ if (ret < 0){
+ LOGE("%s::runFimc fail : ret=%d\n", __func__, ret);
+ skipped_window_mask |= (1 << i);
+ continue;
+ }
+
+ if (win->set_win_flag == 1) {
+ /* turnoff the window and set the window position with new conf... */
+ if (window_set_pos(win) < 0) {
+ LOGE("%s::window_set_pos is failed : %s", __func__,
+ strerror(errno));
+ skipped_window_mask |= (1 << i);
+ continue;
+ }
+ win->set_win_flag = 0;
+ }
+
+ window_pan_display(win);
+
+ win->buf_index = (win->buf_index + 1) % NUM_OF_WIN_BUF;
+
+ if(win->power_state == 0)
+ window_show(win);
+
+ } else {
+ LOGE("%s:: error : layer %d compositionType should have been \
+ HWC_OVERLAY", __func__, win->layer_index);
+ skipped_window_mask |= (1 << i);
+ continue;
+ }
+ } else {
+ LOGE("%s:: error : window status should have been HWC_WIN_RESERVED \
+ by now... ", __func__);
+ skipped_window_mask |= (1 << i);
+ continue;
+ }
+ }
+
+ if (skipped_window_mask) {
+ //turn off the free windows
+ for (int i = 0; i < NUM_OF_WIN; i++) {
+ if (skipped_window_mask & (1 << i))
+ window_hide(&ctx->win[i]);
+ }
+ }
+
+ return 0;
+}
+
+static int hwc_device_close(struct hw_device_t *dev)
+{
+ struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
+ int ret = 0;
+ int i;
+
+ if (ctx) {
+ if (destroyFimc(&ctx->fimc) < 0) {
+ LOGE("%s::destroyFimc fail", __func__);
+ ret = -1;
+ }
+
+ for (i = 0; i < NUM_OF_WIN; i++) {
+ if (window_close(&ctx->win[i]) < 0) {
+ LOGE("%s::window_close() fail", __func__);
+ ret = -1;
+ }
+ }
+
+ free(ctx);
+ }
+ return ret;
+}
+
+static int hwc_device_open(const struct hw_module_t* module, const char* name,
+ struct hw_device_t** device)
+{
+ int status = 0;
+ struct hwc_win_info_t *win;
+
+ if(hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
+ (const hw_module_t**)&gpsGrallocModule))
+ return -EINVAL;
+
+ if(strcmp(gpsGrallocModule->base.common.author, "Imagination Technologies"))
+ return -EINVAL;
+
+ if (strcmp(name, HWC_HARDWARE_COMPOSER))
+ return -EINVAL;
+
+ struct hwc_context_t *dev;
+ dev = (hwc_context_t*)malloc(sizeof(*dev));
+
+ /* initialize our state here */
+ memset(dev, 0, sizeof(*dev));
+
+ /* initialize the procs */
+ dev->device.common.tag = HARDWARE_DEVICE_TAG;
+ dev->device.common.version = 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;
+
+ *device = &dev->device.common;
+
+ /* initializing */
+ memset(&(dev->fimc), 0, sizeof(s5p_fimc_t));
+ dev->fimc.dev_fd = -1;
+
+ /* open WIN0 & WIN1 here */
+ for (int i = 0; i < NUM_OF_WIN; i++) {
+ if (window_open(&(dev->win[i]), i) < 0) {
+ LOGE("%s:: Failed to open window %d device ", __func__, i);
+ status = -EINVAL;
+ goto err;
+ }
+ }
+
+ if (window_get_global_lcd_info(dev->win[0].fd, &dev->lcd_info) < 0) {
+ LOGE("%s::window_get_global_lcd_info is failed : %s",
+ __func__, strerror(errno));
+ status = -EINVAL;
+ goto err;
+ }
+
+ dev->lcd_info.yres_virtual = dev->lcd_info.yres * NUM_OF_WIN_BUF;
+
+ /* initialize the window context */
+ for (int i = 0; i < NUM_OF_WIN; i++) {
+ win = &dev->win[i];
+ memcpy(&win->lcd_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo));
+ memcpy(&win->var_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo));
+
+ win->rect_info.x = 0;
+ win->rect_info.y = 0;
+ win->rect_info.w = win->var_info.xres;
+ win->rect_info.h = win->var_info.yres;
+
+ if (window_set_pos(win) < 0) {
+ LOGE("%s::window_set_pos is failed : %s",
+ __func__, strerror(errno));
+ status = -EINVAL;
+ goto err;
+ }
+
+ if (window_get_info(win) < 0) {
+ LOGE("%s::window_get_info is failed : %s",
+ __func__, strerror(errno));
+ status = -EINVAL;
+ goto err;
+ }
+
+ win->size = win->fix_info.line_length * win->var_info.yres;
+
+ if (!win->fix_info.smem_start){
+ LOGE("%s:: win-%d failed to get the reserved memory", __func__, i);
+ status = -EINVAL;
+ goto err;
+ }
+
+ for (int j = 0; j < NUM_OF_WIN_BUF; j++) {
+ win->addr[j] = win->fix_info.smem_start + (win->size * j);
+ LOGI("%s::win-%d add[%d] %x ", __func__, i, j, win->addr[j]);
+ }
+ }
+
+ /* open pp */
+ if (createFimc(&dev->fimc) < 0) {
+ LOGE("%s::creatFimc() fail", __func__);
+ status = -EINVAL;
+ goto err;
+ }
+
+ LOGD("%s:: success\n", __func__);
+
+ return 0;
+
+err:
+ if (destroyFimc(&dev->fimc) < 0)
+ LOGE("%s::destroyFimc() fail", __func__);
+
+ for (int i = 0; i < NUM_OF_WIN; i++) {
+ if (window_close(&dev->win[i]) < 0)
+ LOGE("%s::window_close() fail", __func__);
+ }
+
+ return status;
+}
diff --git a/libhwcomposer/SecHWCUtils.cpp b/libhwcomposer/SecHWCUtils.cpp
new file mode 100644
index 0000000..7c89f47
--- /dev/null
+++ b/libhwcomposer/SecHWCUtils.cpp
@@ -0,0 +1,871 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ *
+ * @author Rama, Meka(v.meka@samsung.com)
+ Sangwoo, Park(sw5771.park@samsung.com)
+ Jamie Oh (jung-min.oh@samsung.com)
+ * @date 2011-07-28
+ *
+ */
+
+#include "SecHWCUtils.h"
+
+int window_open(struct hwc_win_info_t *win, int id)
+{
+ char name[64];
+
+ char const * const device_template = "/dev/graphics/fb%u";
+ /* window & FB maping
+ fb0 -> win-id : 2
+ fb1 -> win-id : 3
+ fb2 -> win-id : 4
+ fb3 -> win-id : 0
+ fb4 -> win_id : 1
+ it is pre assumed that ...win0 or win1 is used here..
+ */
+ switch (id) {
+ case 0:
+ case 1:
+ break;
+ default:
+ LOGE("%s::id(%d) is weird", __func__, id);
+ goto error;
+ }
+
+ snprintf(name, 64, device_template, (id + 3)%5);
+
+ win->fd = open(name, O_RDWR);
+ if (win->fd < 0) {
+ LOGE("%s::Failed to open window device (%s) : %s",
+ __func__, strerror(errno), device_template);
+ goto error;
+ }
+
+ return 0;
+
+error:
+ if (0 <= win->fd)
+ close(win->fd);
+ win->fd = -1;
+
+ return -1;
+}
+
+int window_close(struct hwc_win_info_t *win)
+{
+ int ret = 0;
+
+ if (0 <= win->fd)
+ ret = close(win->fd);
+ win->fd = -1;
+
+ return ret;
+}
+
+int window_set_pos(struct hwc_win_info_t *win)
+{
+ struct secfb_user_window window;
+
+ /* before changing the screen configuration...powerdown the window */
+ if(window_hide(win) != 0)
+ return -1;
+
+ win->var_info.xres = win->rect_info.w;
+ win->var_info.yres = win->rect_info.h;
+
+ win->var_info.activate &= ~FB_ACTIVATE_MASK;
+ win->var_info.activate |= FB_ACTIVATE_FORCE;
+
+ if (ioctl(win->fd, FBIOPUT_VSCREENINFO, &(win->var_info)) < 0) {
+ LOGE("%s::FBIOPUT_VSCREENINFO(%d, %d) fail",
+ __func__, win->rect_info.w, win->rect_info.h);
+ return -1;
+ }
+
+ window.x = win->rect_info.x;
+ window.y = win->rect_info.y;
+
+ if (ioctl(win->fd, SECFB_WIN_POSITION, &window) < 0) {
+ LOGE("%s::S3CFB_WIN_POSITION(%d, %d) fail",
+ __func__, window.x, window.y);
+ return -1;
+ }
+
+ return 0;
+}
+
+int window_get_info(struct hwc_win_info_t *win)
+{
+ if (ioctl(win->fd, FBIOGET_FSCREENINFO, &win->fix_info) < 0) {
+ LOGE("FBIOGET_FSCREENINFO failed : %s", strerror(errno));
+ goto error;
+ }
+
+ return 0;
+
+error:
+ win->fix_info.smem_start = 0;
+
+ return -1;
+}
+
+int window_pan_display(struct hwc_win_info_t *win)
+{
+ struct fb_var_screeninfo *lcd_info = &(win->lcd_info);
+
+ lcd_info->yoffset = lcd_info->yres * win->buf_index;
+
+ if (ioctl(win->fd, FBIOPAN_DISPLAY, lcd_info) < 0) {
+ LOGE("%s::FBIOPAN_DISPLAY(%d / %d / %d) fail(%s)",
+ __func__, lcd_info->yres, win->buf_index, lcd_info->yres_virtual,
+ strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int window_show(struct hwc_win_info_t *win)
+{
+ if(win->power_state == 0) {
+ if (ioctl(win->fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
+ LOGE("%s: FBIOBLANK failed : (%d:%s)", __func__, win->fd,
+ strerror(errno));
+ return -1;
+ }
+ win->power_state = 1;
+ }
+ return 0;
+}
+
+int window_hide(struct hwc_win_info_t *win)
+{
+ if (win->power_state == 1) {
+ if (ioctl(win->fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
+ LOGE("%s::FBIOBLANK failed : (%d:%s)",
+ __func__, win->fd, strerror(errno));
+ return -1;
+ }
+ win->power_state = 0;
+ }
+ return 0;
+}
+
+int window_get_global_lcd_info(int fd, struct fb_var_screeninfo *lcd_info)
+{
+ if (ioctl(fd, FBIOGET_VSCREENINFO, lcd_info) < 0) {
+ LOGE("FBIOGET_VSCREENINFO failed : %s", strerror(errno));
+ return -1;
+ }
+
+ if (lcd_info->xres == 0) {
+ lcd_info->xres = DEFAULT_LCD_WIDTH;
+ lcd_info->xres_virtual = DEFAULT_LCD_WIDTH;
+ }
+
+ if (lcd_info->yres == 0) {
+ lcd_info->yres = DEFAULT_LCD_HEIGHT;
+ lcd_info->yres_virtual = DEFAULT_LCD_HEIGHT * NUM_OF_WIN_BUF;
+ }
+
+ if (lcd_info->bits_per_pixel == 0)
+ lcd_info->bits_per_pixel = DEFAULT_LCD_BPP;
+
+ return 0;
+}
+
+int fimc_v4l2_set_src(int fd, unsigned int hw_ver, s5p_fimc_img_info *src)
+{
+ struct v4l2_format fmt;
+ struct v4l2_cropcap cropcap;
+ struct v4l2_crop crop;
+ struct v4l2_requestbuffers req;
+
+ /*
+ * To set size & format for source image (DMA-INPUT)
+ */
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ fmt.fmt.pix.width = src->full_width;
+ fmt.fmt.pix.height = src->full_height;
+ fmt.fmt.pix.pixelformat = src->color_space;
+ fmt.fmt.pix.field = V4L2_FIELD_NONE;
+
+ if (ioctl (fd, VIDIOC_S_FMT, &fmt) < 0) {
+ LOGE("VIDIOC_S_FMT failed : errno=%d (%s) : fd=%d", errno,
+ strerror(errno), fd);
+ return -1;
+ }
+
+ /*
+ * crop input size
+ */
+ crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ if (0x50 == hw_ver) {
+ crop.c.left = src->start_x;
+ crop.c.top = src->start_y;
+ } else {
+ crop.c.left = 0;
+ crop.c.top = 0;
+ }
+ crop.c.width = src->width;
+ crop.c.height = src->height;
+ if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) {
+ LOGE("Error in video VIDIOC_S_CROP (%d, %d, %d, %d)",
+ crop.c.left, crop.c.top, crop.c.width, crop.c.height);
+ return -1;
+ }
+
+ /*
+ * input buffer type
+ */
+ req.count = 1;
+ req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ req.memory = V4L2_MEMORY_USERPTR;
+
+ if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
+ LOGE("Error in VIDIOC_REQBUFS");
+ return -1;
+ }
+
+ return 0;
+}
+
+int fimc_v4l2_set_dst(int fd,
+ s5p_fimc_img_info *dst,
+ int rotation,
+ int flag_h_flip,
+ int flag_v_flip,
+ unsigned int addr)
+{
+ struct v4l2_format sFormat;
+ struct v4l2_control vc;
+ struct v4l2_framebuffer fbuf;
+
+ /*
+ * set rotation configuration
+ */
+ vc.id = V4L2_CID_HFLIP;
+ vc.value = flag_h_flip;
+ if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
+ LOGE("Error in video VIDIOC_S_CTRL - flag_h_flip (%d)", flag_h_flip);
+ return -1;
+ }
+
+ vc.id = V4L2_CID_VFLIP;
+ vc.value = flag_v_flip;
+ if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
+ LOGE("Error in video VIDIOC_S_CTRL - flag_v_flip (%d)", flag_v_flip);
+ return -1;
+ }
+
+ vc.id = V4L2_CID_ROTATION;
+ vc.value = rotation;
+ if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
+ LOGE("Error in video VIDIOC_S_CTRL - rotation (%d)", rotation);
+ return -1;
+ }
+
+ /*
+ * set size, format & address for destination image (DMA-OUTPUT)
+ */
+ if (ioctl (fd, VIDIOC_G_FBUF, &fbuf) < 0) {
+ LOGE("Error in video VIDIOC_G_FBUF");
+ return -1;
+ }
+
+ fbuf.base = (void *)addr;
+ fbuf.fmt.width = dst->full_width;
+ fbuf.fmt.height = dst->full_height;
+ fbuf.fmt.pixelformat = dst->color_space;
+ if (ioctl (fd, VIDIOC_S_FBUF, &fbuf) < 0) {
+ LOGE("Error in video VIDIOC_S_FBUF 0x%x %d %d %d",
+ (void *)addr, dst->full_width, dst->full_height,
+ dst->color_space);
+ return -1;
+ }
+
+ /*
+ * set destination window
+ */
+ sFormat.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+ sFormat.fmt.win.w.left = dst->start_x;
+ sFormat.fmt.win.w.top = dst->start_y;
+ sFormat.fmt.win.w.width = dst->width;
+ sFormat.fmt.win.w.height = dst->height;
+ if (ioctl(fd, VIDIOC_S_FMT, &sFormat) < 0) {
+ LOGE("Error in video VIDIOC_S_FMT %d %d %d %d",
+ dst->start_x, dst->start_y, dst->width, dst->height);
+ return -1;
+ }
+
+ return 0;
+}
+
+int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type)
+{
+ if (ioctl (fd, VIDIOC_STREAMON, &type) < 0) {
+ LOGE("Error in VIDIOC_STREAMON");
+ return -1;
+ }
+
+ return 0;
+}
+
+int fimc_v4l2_queue(int fd, struct fimc_buf *fimc_buf)
+{
+ struct v4l2_buffer buf;
+
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ buf.m.userptr = (unsigned long)fimc_buf;
+ buf.length = 0;
+ buf.index = 0;
+
+ if (ioctl (fd, VIDIOC_QBUF, &buf) < 0) {
+ LOGE("Error in VIDIOC_QBUF");
+ return -1;
+ }
+
+ return 0;
+}
+
+int fimc_v4l2_dequeue(int fd)
+{
+ struct v4l2_buffer buf;
+
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ buf.memory = V4L2_MEMORY_USERPTR;
+
+ if (ioctl (fd, VIDIOC_DQBUF, &buf) < 0) {
+ LOGE("Error in VIDIOC_DQBUF");
+ return -1;
+ }
+
+ return buf.index;
+}
+
+int fimc_v4l2_stream_off(int fd)
+{
+ enum v4l2_buf_type type;
+ type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+ if (ioctl (fd, VIDIOC_STREAMOFF, &type) < 0) {
+ LOGE("Error in VIDIOC_STREAMOFF");
+ return -1;
+ }
+
+ return 0;
+}
+
+int fimc_v4l2_clr_buf(int fd)
+{
+ struct v4l2_requestbuffers req;
+
+ req.count = 0;
+ req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ req.memory = V4L2_MEMORY_USERPTR;
+
+ if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
+ LOGE("Error in VIDIOC_REQBUFS");
+ }
+
+ return 0;
+}
+
+int fimc_handle_oneshot(int fd, struct fimc_buf *fimc_buf)
+{
+ if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT) < 0) {
+ LOGE("Fail : v4l2_stream_on()");
+ return -1;
+ }
+
+ if (fimc_v4l2_queue(fd, fimc_buf) < 0) {
+ LOGE("Fail : v4l2_queue()");
+ return -1;
+ }
+
+ if (fimc_v4l2_dequeue(fd) < 0) {
+ LOGE("Fail : v4l2_dequeue()");
+ return -1;
+ }
+
+ if (fimc_v4l2_stream_off(fd) < 0) {
+ LOGE("Fail : v4l2_stream_off()");
+ return -1;
+ }
+
+ if (fimc_v4l2_clr_buf(fd) < 0) {
+ LOGE("Fail : v4l2_clr_buf()");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int get_src_phys_addr(struct hwc_context_t *ctx,
+ sec_img *src_img,
+ unsigned int *phyAddr)
+{
+ s5p_fimc_t *fimc = &ctx->fimc;
+
+ if(src_img->mem_type == HWC_PHYS_MEM_TYPE) {
+ switch(src_img->format) {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ fimc->params.src.buf_addr_phy_rgb_y = phyAddr[0];
+ fimc->params.src.buf_addr_phy_cb = phyAddr[1];
+ break;
+ default:
+ LOGE("%s format error (format=0x%x)", __func__,
+ src_img->format);
+ return -1;
+ }
+ } else {
+ LOGE("%s mem_type error (mem_type=%d)", __func__, src_img->mem_type);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int get_dst_phys_addr(struct hwc_context_t *ctx,
+ sec_img *dst_img)
+{
+ unsigned int dst_phys_addr = 0;
+
+ if (HWC_PHYS_MEM_TYPE == dst_img->mem_type && 0 != dst_img->base)
+ dst_phys_addr = dst_img->base;
+ else {
+ LOGE("%s::get_dst_phys_addr fail ", __func__);
+ dst_phys_addr = 0;
+ }
+ return dst_phys_addr;
+}
+
+static inline int rotateValueHAL2PP(unsigned char transform,
+ int *flag_h_flip,
+ int *flag_v_flip)
+{
+ int rotate_result = 0;
+ int rotate_flag = transform & 0x7;
+
+ switch (rotate_flag) {
+ case HAL_TRANSFORM_ROT_90:
+ rotate_result = 90;
+ break;
+ case HAL_TRANSFORM_ROT_180:
+ rotate_result = 180;
+ break;
+ case HAL_TRANSFORM_ROT_270:
+ rotate_result = 270;
+ break;
+ }
+
+ switch (rotate_flag) {
+ case HAL_TRANSFORM_FLIP_H:
+ *flag_h_flip = 1;
+ *flag_v_flip = 0;
+ break;
+ case HAL_TRANSFORM_FLIP_V:
+ *flag_h_flip = 0;
+ *flag_v_flip = 1;
+ break;
+ default:
+ *flag_h_flip = 0;
+ *flag_v_flip = 0;
+ break;
+ }
+
+ return rotate_result;
+}
+
+static inline int multipleOfN(int number, int N)
+{
+ int result = number;
+ switch (N) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ result = (number - (number & (N-1)));
+ break;
+ default:
+ result = number - (number % N);
+ break;
+ }
+ return result;
+}
+
+static inline int widthOfPP(unsigned int ver,
+ int pp_color_format,
+ int number)
+{
+ if (0x50 == ver) {
+ switch(pp_color_format) {
+ /* 422 1/2/3 plane */
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_NV61:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_YUV422P:
+
+ /* 420 2/3 plane */
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV12T:
+ case V4L2_PIX_FMT_YUV420:
+ return multipleOfN(number, 2);
+
+ default :
+ return number;
+ }
+ } else {
+ switch(pp_color_format) {
+ case V4L2_PIX_FMT_RGB565:
+ return multipleOfN(number, 8);
+
+ case V4L2_PIX_FMT_RGB32:
+ return multipleOfN(number, 4);
+
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ return multipleOfN(number, 4);
+
+ case V4L2_PIX_FMT_NV61:
+ case V4L2_PIX_FMT_NV16:
+ return multipleOfN(number, 8);
+
+ case V4L2_PIX_FMT_YUV422P:
+ return multipleOfN(number, 16);
+
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV12T:
+ return multipleOfN(number, 8);
+
+ case V4L2_PIX_FMT_YUV420:
+ return multipleOfN(number, 16);
+
+ default :
+ return number;
+ }
+ }
+ return number;
+}
+
+static inline int heightOfPP(int pp_color_format,
+ int number)
+{
+ switch(pp_color_format) {
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV12T:
+ case V4L2_PIX_FMT_YUV420:
+ return multipleOfN(number, 2);
+
+ default :
+ return number;
+ }
+ return number;
+}
+
+static int runcFimcCore(struct hwc_context_t *ctx,
+ sec_img *src_img,
+ sec_rect *src_rect,
+ uint32_t src_color_space,
+ unsigned int dst_phys_addr,
+ sec_img *dst_img,
+ sec_rect *dst_rect,
+ uint32_t dst_color_space,
+ int transform)
+{
+ s5p_fimc_t * fimc = &ctx->fimc;
+ s5p_fimc_params_t * params = &(fimc->params);
+
+ unsigned int frame_size = 0;
+ struct fimc_buf fimc_src_buf;
+
+ int src_bpp, src_planes;
+ int flag_h_flip = 0;
+ int flag_v_flip = 0;
+ int rotate_value = rotateValueHAL2PP(transform, &flag_h_flip, &flag_v_flip);
+
+ /* set post processor configuration */
+ params->src.full_width = src_img->w;
+ params->src.full_height = src_img->h;
+ params->src.start_x = src_rect->x;
+ params->src.start_y = src_rect->y;
+ params->src.width = widthOfPP(fimc->hw_ver, src_color_space, src_rect->w);
+ params->src.height = heightOfPP(src_color_space, src_rect->h);
+ params->src.color_space = src_color_space;
+
+
+ /* check minimum */
+ if (src_rect->w < 16 || src_rect->h < 8) {
+ LOGE("%s src size is not supported by fimc : f_w=%d f_h=%d x=%d y=%d \
+ w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__,
+ params->src.full_width, params->src.full_height,
+ params->src.start_x, params->src.start_y, params->src.width,
+ params->src.height, src_rect->w, src_rect->h,
+ params->src.color_space);
+ return -1;
+ }
+
+switch (rotate_value) {
+ case 0:
+ params->dst.full_width = dst_img->w;
+ params->dst.full_height = dst_img->h;
+
+ params->dst.start_x = dst_rect->x;
+ params->dst.start_y = dst_rect->y;
+
+ params->dst.width =
+ widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
+ params->dst.height = heightOfPP(dst_color_space, dst_rect->h);
+ break;
+ case 90:
+ params->dst.full_width = dst_img->h;
+ params->dst.full_height = dst_img->w;
+
+ params->dst.start_x = dst_rect->y;
+ params->dst.start_y = dst_img->w - (dst_rect->x + dst_rect->w);
+
+ params->dst.width =
+ widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
+ params->dst.height =
+ widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
+
+ if (0x50 > fimc->hw_ver)
+ params->dst.start_y += (dst_rect->w - params->dst.height);
+ break;
+ case 180:
+ params->dst.full_width = dst_img->w;
+ params->dst.full_height = dst_img->h;
+
+ params->dst.start_x = dst_img->w - (dst_rect->x + dst_rect->w);
+ params->dst.start_y = dst_img->h - (dst_rect->y + dst_rect->h);
+
+ params->dst.width =
+ widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
+ params->dst.height = heightOfPP(dst_color_space, dst_rect->h);
+ break;
+ case 270:
+ params->dst.full_width = dst_img->h;
+ params->dst.full_height = dst_img->w;
+
+ params->dst.start_x = dst_img->h - (dst_rect->y + dst_rect->h);
+ params->dst.start_y = dst_rect->x;
+
+ params->dst.width =
+ widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
+ params->dst.height =
+ widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
+
+ if (0x50 > fimc->hw_ver)
+ params->dst.start_y += (dst_rect->w - params->dst.height);
+ break;
+ }
+
+
+ params->dst.color_space = dst_color_space;
+
+ /* check minimum */
+ if (dst_rect->w < 8 || dst_rect->h < 4) {
+ LOGE("%s dst size is not supported by fimc : \
+ f_w=%d f_h=%d x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x",
+ __func__, params->dst.full_width, params->dst.full_height,
+ params->dst.start_x, params->dst.start_y, params->dst.width,
+ params->dst.height, dst_rect->w, dst_rect->h,
+ params->dst.color_space);
+ return -1;
+ }
+
+ /* check scaling limit
+ * the scaling limie must not be more than MAX_RESIZING_RATIO_LIMIT
+ */
+ if (((src_rect->w > dst_rect->w) &&
+ ((src_rect->w / dst_rect->w) > MAX_RESIZING_RATIO_LIMIT)) ||
+ ((dst_rect->w > src_rect->w) &&
+ ((dst_rect->w / src_rect->w) > MAX_RESIZING_RATIO_LIMIT))) {
+ LOGE("%s over scaling limit : src.w=%d dst.w=%d (limit=%d)",
+ __func__, src_rect->w, dst_rect->w, MAX_RESIZING_RATIO_LIMIT);
+ return -1;
+ }
+
+
+ /* set configuration related to destination (DMA-OUT)
+ * - set input format & size
+ * - crop input size
+ * - set input buffer
+ * - set buffer type (V4L2_MEMORY_USERPTR)
+ */
+ if (fimc_v4l2_set_dst(fimc->dev_fd,
+ &params->dst,
+ rotate_value,
+ flag_h_flip,
+ flag_v_flip,
+ dst_phys_addr) < 0) {
+ return -1;
+ }
+
+ /* set configuration related to source (DMA-INPUT)
+ * - set input format & size
+ * - crop input size
+ * - set input buffer
+ * - set buffer type (V4L2_MEMORY_USERPTR)
+ */
+ if (fimc_v4l2_set_src(fimc->dev_fd, fimc->hw_ver, &params->src) < 0)
+ return -1;
+
+ /* set input dma address (Y/RGB, Cb, Cr) */
+ switch (src_img->format) {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ /* for video display zero copy case */
+ fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
+ fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
+ break;
+
+ default:
+ /* set source image */
+ fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
+ break;
+ }
+
+ if (fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf) < 0) {
+ fimc_v4l2_clr_buf(fimc->dev_fd);
+ return -1;
+ }
+
+ return 0;
+}
+
+int createFimc(s5p_fimc_t *fimc)
+{
+ struct v4l2_capability cap;
+ struct v4l2_format fmt;
+ struct v4l2_control vc;
+
+ #define PP_DEVICE_DEV_NAME "/dev/video1"
+
+ /* open device file */
+ if(fimc->dev_fd < 0) {
+ fimc->dev_fd = open(PP_DEVICE_DEV_NAME, O_RDWR);
+
+ if (fimc->dev_fd < 0) {
+ LOGE("%s::Post processor open error (%d)", __func__, errno);
+ goto err;
+ }
+ }
+
+ /* check capability */
+ if (ioctl(fimc->dev_fd, VIDIOC_QUERYCAP, &cap) < 0) {
+ LOGE("VIDIOC_QUERYCAP failed");
+ goto err;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
+ LOGE("%d has no streaming support", fimc->dev_fd);
+ goto err;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
+ LOGE("%d is no video output", fimc->dev_fd);
+ goto err;
+ }
+
+ /*
+ * malloc fimc_outinfo structure
+ */
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ if (ioctl(fimc->dev_fd, VIDIOC_G_FMT, &fmt) < 0) {
+ LOGE("%s::Error in video VIDIOC_G_FMT", __func__);
+ goto err;
+ }
+
+ vc.id = V4L2_CID_FIMC_VERSION;
+ vc.value = 0;
+
+ if (ioctl(fimc->dev_fd, VIDIOC_G_CTRL, &vc) < 0) {
+ LOGE("%s::Error in video VIDIOC_G_CTRL", __func__);
+ goto err;
+ }
+ fimc->hw_ver = vc.value;
+
+ return 0;
+
+err:
+ if (0 <= fimc->dev_fd)
+ close(fimc->dev_fd);
+ fimc->dev_fd = -1;
+
+ return -1;
+}
+
+int destroyFimc(s5p_fimc_t *fimc)
+{
+ if (fimc->out_buf.virt_addr != NULL) {
+ fimc->out_buf.virt_addr = NULL;
+ fimc->out_buf.length = 0;
+ }
+
+ /* close */
+ if (0 <= fimc->dev_fd)
+ close(fimc->dev_fd);
+ fimc->dev_fd = -1;
+
+ return 0;
+}
+
+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,
+ unsigned int *phyAddr,
+ uint32_t transform)
+{
+ s5p_fimc_t *fimc = &ctx->fimc;
+ unsigned int dst_phys_addr = 0;
+ int32_t src_color_space;
+ int32_t dst_color_space;
+
+ /* 1 : source address and size */
+
+ if(0 > get_src_phys_addr(ctx, src_img, phyAddr))
+ return -1;
+
+ /* 2 : destination address and size */
+ if(0 == (dst_phys_addr = get_dst_phys_addr(ctx, dst_img)))
+ return -2;
+
+ /* check whether fimc supports the src format */
+ if (0 > (src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format)))
+ return -3;
+
+ if (0 > (dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format)))
+ return -4;
+
+ if(runcFimcCore(ctx, src_img, src_rect, (uint32_t)src_color_space,
+ dst_phys_addr, dst_img, dst_rect, (uint32_t)dst_color_space, transform) < 0)
+ return -5;
+
+ return 0;
+}
diff --git a/libhwcomposer/SecHWCUtils.h b/libhwcomposer/SecHWCUtils.h
new file mode 100644
index 0000000..7715cb4
--- /dev/null
+++ b/libhwcomposer/SecHWCUtils.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ *
+ * @author Rama, Meka(v.meka@samsung.com)
+ Sangwoo, Park(sw5771.park@samsung.com)
+ Jamie, Oh (jung-min.oh@samsung.com)
+ * @date 2011-07-28
+ *
+ */
+
+#ifndef ANDROID_SEC_HWC_UTILS_H_
+#define ANDROID_SEC_HWC_UTILS_H_
+#include <fcntl.h>
+#include <errno.h>
+#include <cutils/log.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include "linux/fb.h"
+#include <linux/videodev.h>
+
+#include <hardware/gralloc.h>
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
+
+#include "s5p_fimc.h"
+#include "sec_lcd.h"
+#include "sec_format.h"
+#include "sec_utils.h"
+#include "hal_public.h"
+
+#define GRALLOC_USAGE_PHYS_CONTIG GRALLOC_USAGE_PRIVATE_1
+
+#define NUM_OF_WIN (1)
+#define NUM_OF_WIN_BUF (3)
+#define NUM_OF_MEM_OBJ (1)
+#define MAX_NUM_PLANES (3)
+
+#define MAX_RESIZING_RATIO_LIMIT (63)
+
+struct sec_rect {
+ uint32_t x;
+ uint32_t y;
+ uint32_t w;
+ uint32_t h;
+};
+
+struct sec_img {
+ uint32_t w;
+ uint32_t h;
+ uint32_t format;
+ uint32_t base;
+ uint32_t offset;
+ int mem_id;
+ int mem_type;
+};
+
+inline int SEC_MIN(int x, int y) {
+ return ((x < y) ? x : y);
+}
+
+inline int SEC_MAX(int x, int y) {
+ return ((x > y) ? x : y);
+}
+
+struct hwc_win_info_t {
+ int fd;
+ int size;
+ sec_rect rect_info;
+ uint32_t addr[NUM_OF_WIN_BUF];
+ int buf_index;
+ int power_state;
+ int blending;
+ int layer_index;
+ uint32_t layer_prev_buf;
+ int set_win_flag;
+ int status;
+ int vsync;
+
+ struct fb_fix_screeninfo fix_info;
+ struct fb_var_screeninfo var_info;
+ struct fb_var_screeninfo lcd_info;
+};
+
+enum {
+ HWC_WIN_FREE = 0,
+ HWC_WIN_RESERVED,
+};
+
+enum {
+ HWC_UNKNOWN_MEM_TYPE = 0,
+ HWC_PHYS_MEM_TYPE,
+ HWC_VIRT_MEM_TYPE,
+};
+
+struct hwc_context_t {
+ hwc_composer_device_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;
+ unsigned int num_of_fb_layer;
+ unsigned int num_of_hwc_layer;
+};
+
+int window_open(struct hwc_win_info_t *win, int id);
+int window_close(struct hwc_win_info_t *win);
+int window_set_pos(struct hwc_win_info_t *win);
+int window_get_info(struct hwc_win_info_t *win);
+int window_pan_display(struct hwc_win_info_t *win);
+int window_show(struct hwc_win_info_t *win);
+int window_hide(struct hwc_win_info_t *win);
+int window_get_global_lcd_info(int fd, struct fb_var_screeninfo *lcd_info);
+
+int createFimc(s5p_fimc_t *fimc);
+int destroyFimc(s5p_fimc_t *fimc);
+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,
+ unsigned int *phyAddr,
+ uint32_t transform);
+#endif /* ANDROID_SEC_HWC_UTILS_H_*/
+