Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

display: Restructure code for refactor

Change-Id: Id8f350dd7031e0b6c0d99d15a77f620775fe7169
  • Loading branch information...
commit b1a3fbf8a19ae65d2e47974be28ab4e09aaf9978 1 parent 30eee88
Naseer Ahmed authored Ramakrishna Prasad N committed
Showing with 3,924 additions and 340 deletions.
  1. +0 −3  Android.mk
  2. +7 −2 libcopybit/Android.mk
  3. +6 −1 libgenlock/Android.mk
  4. +32 −27 libgralloc/Android.mk
  5. +198 −0 libgralloc/a-family/fb_priv.h
  6. +1 −0  libgralloc/{ → a-family}/framebuffer.cpp
  7. +189 −0 libgralloc/badger/fb_priv.h
  8. +1,123 −0 libgralloc/badger/framebuffer.cpp
  9. +1 −0  libgralloc/gpu.h
  10. +2 −184 libgralloc/gralloc_priv.h
  11. +5 −52 libhwcomposer/Android.mk
  12. +41 −0 libhwcomposer/a-family/Android.mk
  13. 0  libhwcomposer/{ → a-family}/external_display_only.h
  14. +1 −0  libhwcomposer/{ → a-family}/hwcomposer.cpp
  15. +22 −0 libhwcomposer/badger/Android.mk
  16. +2,196 −0 libhwcomposer/badger/hwcomposer.cpp
  17. +5 −41 liboverlay/Android.mk
  18. +47 −0 liboverlay/a-family/Android.mk
  19. 0  liboverlay/{ → a-family}/overlayLib.cpp
  20. 0  liboverlay/{ → a-family}/overlayLib.h
  21. 0  liboverlay/{ → a-family}/overlayLibUI.cpp
  22. 0  liboverlay/{ → a-family}/overlayLibUI.h
  23. 0  {badger/liboverlay2/tests → liboverlay/badger}/Android.mk
  24. +3 −4 {badger/liboverlay2 → liboverlay/badger}/src/Android.mk
  25. 0  {badger/liboverlay2 → liboverlay/badger}/src/mdpWrapper.h
  26. 0  {badger/liboverlay2 → liboverlay/badger}/src/mdpWrapper.inl
  27. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlay.cpp
  28. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlay.h
  29. +1 −0  {badger/liboverlay2 → liboverlay/badger}/src/overlayCtrl.cpp
  30. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayCtrl.h
  31. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayCtrl.inl
  32. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayData.h
  33. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayData.inl
  34. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayFD.h
  35. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayFD.inl
  36. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayGenPipe.h
  37. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayGenPipe_T.cpp
  38. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayImpl.h
  39. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayImpl_T.cpp
  40. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayMdp.cpp
  41. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayMdp.h
  42. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayMdp.inl
  43. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayMem.h
  44. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayMem.inl
  45. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayMgr.cpp
  46. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayMgr.h
  47. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayMgrSingleton.cpp
  48. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayMgrSingleton.h
  49. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayReconf.cpp
  50. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayReconf.h
  51. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayRes.cpp
  52. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayRes.h
  53. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayRotator.cpp
  54. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayRotator.h
  55. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayRotator.inl
  56. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayState.h
  57. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayState.inl
  58. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayStateTraits.h
  59. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayTransitions.cpp
  60. +1 −0  {badger/liboverlay2 → liboverlay/badger}/src/overlayUtils.cpp
  61. +1 −1  {badger/liboverlay2 → liboverlay/badger}/src/overlayUtils.h
  62. 0  {badger/liboverlay2 → liboverlay/badger}/src/overlayUtils.inl
  63. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayBypassPipe.h
  64. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayBypassPipe_T.cpp
  65. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayHdmiPipe.h
  66. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayHdmiPipe.inl
  67. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayM3DExtPipe.h
  68. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayM3DExtPipe_T.cpp
  69. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayM3DPrimaryPipe.h
  70. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayM3DPrimaryPipe_T.cpp
  71. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayRgbPipe.h
  72. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayRgbPipe_T.cpp
  73. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayS3DExtPipe.h
  74. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayS3DExtPipe_T.cpp
  75. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayS3DPrimaryPipe.h
  76. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayS3DPrimaryPipe_T.cpp
  77. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayUIMirrorPipe.h
  78. 0  {badger/liboverlay2 → liboverlay/badger}/src/pipes/overlayUIMirrorPipe.inl
  79. 0  {badger/liboverlay2 → liboverlay/badger/tests}/Android.mk
  80. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/ctrltest/Android.mk
  81. 0  {badger/liboverlay2 → liboverlay/badger}/tests/ctrltest/ctrlTest.cpp
  82. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/datatest/Android.mk
  83. 0  {badger/liboverlay2 → liboverlay/badger}/tests/datatest/dataTest.cpp
  84. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/fdtest/Android.mk
  85. 0  {badger/liboverlay2 → liboverlay/badger}/tests/fdtest/overlayFDTest.cpp
  86. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/genericpipetest/Android.mk
  87. 0  {badger/liboverlay2 → liboverlay/badger}/tests/genericpipetest/genericPipeTest.cpp
  88. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/mdptest/Android.mk
  89. 0  {badger/liboverlay2 → liboverlay/badger}/tests/mdptest/overlayMdpTest.cpp
  90. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/mdpwrappertest/Android.mk
  91. 0  {badger/liboverlay2 → liboverlay/badger}/tests/mdpwrappertest/mdpWrapperTest.cpp
  92. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/memtest/Android.mk
  93. 0  {badger/liboverlay2 → liboverlay/badger}/tests/memtest/overlayMemTest.cpp
  94. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/overlayimpltest/Android.mk
  95. 0  {badger/liboverlay2 → liboverlay/badger}/tests/overlayimpltest/overlayImplTest.cpp
  96. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/overlaytest/Android.mk
  97. 0  {badger/liboverlay2 → liboverlay/badger}/tests/overlaytest/overlayTest.cpp
  98. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/rgbpipetest/Android.mk
  99. 0  {badger/liboverlay2 → liboverlay/badger}/tests/rgbpipetest/rgbPipeTest.cpp
  100. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/rotatortest/Android.mk
  101. 0  {badger/liboverlay2 → liboverlay/badger}/tests/rotatortest/overlayRotatorTest.cpp
  102. +2 −2 {badger/liboverlay2 → liboverlay/badger}/tests/utilstest/Android.mk
  103. 0  {badger/liboverlay2 → liboverlay/badger}/tests/utilstest/utilsTest.cpp
  104. +13 −0 libqcomui/Android.mk
  105. +0 −1  libqcomui/qcom_ui.h
  106. +5 −0 libtilerenderer/Android.mk
View
3  Android.mk
@@ -5,9 +5,6 @@ display-hals := libqcomui libtilerenderer
#libs to be built for QCOM targets only
ifeq ($(call is-vendor-board-platform,QCOM),true)
-ifeq ($(TARGET_BOARD_PLATFORM),copper)
-display-hals += badger/liboverlay2
-endif
display-hals += libhwcomposer liboverlay libgralloc libgenlock libcopybit
endif
View
9 libcopybit/Android.mk
@@ -17,6 +17,11 @@ LOCAL_PATH:= $(call my-dir)
# HAL module implemenation, not prelinked and stored in
# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so
+include $(CLEAR_VARS)
+LOCAL_COPY_HEADERS_TO := qcom/display
+LOCAL_COPY_HEADERS := copybit.h
+include $(BUILD_COPY_HEADERS)
+
ifeq ($(TARGET_USES_C2D_COMPOSITION),true)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
@@ -25,8 +30,8 @@ ifeq ($(TARGET_USES_C2D_COMPOSITION),true)
LOCAL_SRC_FILES := copybit_c2d.cpp software_converter.cpp
LOCAL_MODULE := copybit.$(TARGET_BOARD_PLATFORM)
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+ LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qcom/display
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
- LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
LOCAL_CFLAGS += -DCOPYBIT_Z180=1 -DC2D_SUPPORT_DISPLAY=1
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
@@ -54,8 +59,8 @@ else
LOCAL_MODULE := copybit.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+ LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qcom/display
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
- LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
LOCAL_CFLAGS += -DCOPYBIT_MSM7K=1
include $(BUILD_SHARED_LIBRARY)
endif
View
7 libgenlock/Android.mk
@@ -1,11 +1,16 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
+LOCAL_COPY_HEADERS_TO := qcom/display
+LOCAL_COPY_HEADERS := genlock.h
+include $(BUILD_COPY_HEADERS)
+
+include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_C_INCLUDES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qcom/display
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_SRC_FILES := genlock.cpp
LOCAL_CFLAGS:= -DLOG_TAG=\"libgenlock\"
View
59 libgralloc/Android.mk
@@ -12,9 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Use this flag until pmem/ashmem is implemented in the new gralloc
LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_COPY_HEADERS_TO := qcom/display
+LOCAL_COPY_HEADERS := gralloc_priv.h
+LOCAL_COPY_HEADERS += gr.h
+LOCAL_COPY_HEADERS += alloc_controller.h
+LOCAL_COPY_HEADERS += memalloc.h
+ifeq ($(call is-board-platform-in-list,copper),true)
+LOCAL_COPY_HEADERS += badger/fb_priv.h
+else
+LOCAL_COPY_HEADERS += a-family/fb_priv.h
+endif
+include $(BUILD_COPY_HEADERS)
+
# HAL module implemenation, not prelinked and stored in
# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
include $(CLEAR_VARS)
@@ -24,18 +37,29 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils libGLESv1_CM libutils libmemalloc lib
LOCAL_SHARED_LIBRARIES += libgenlock
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_C_INCLUDES += hardware/qcom/display/libgenlock
-LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qcom/display
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-LOCAL_SRC_FILES := framebuffer.cpp \
- gpu.cpp \
- gralloc.cpp \
- mapper.cpp
-
LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).gralloc\" -DHOST -DDEBUG_CALC_FPS
+LOCAL_SRC_FILES := gpu.cpp \
+ gralloc.cpp \
+ mapper.cpp
+
+ifeq ($(call is-board-platform-in-list,copper),true)
+ LOCAL_SRC_FILES += badger/framebuffer.cpp
+ LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay/badger/src
+ LOCAL_CFLAGS += -DUSE_OVERLAY2 #XXX: Remove later
+else
+ LOCAL_SRC_FILES += a-family/framebuffer.cpp
+ ifeq ($(TARGET_USES_POST_PROCESSING),true)
+ LOCAL_CFLAGS += -DUSES_POST_PROCESSING
+ LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/pp/inc
+ endif
+endif
+
+
ifeq ($(call is-board-platform,msm7627_surf msm7627_6x),true)
LOCAL_CFLAGS += -DTARGET_MSM7x27
endif
@@ -46,28 +70,9 @@ endif
ifeq ($(TARGET_HAVE_HDMI_OUT),true)
LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
-ifeq ($(TARGET_BOARD_PLATFORM),copper)
- LOCAL_CFLAGS += -DUSE_OVERLAY2
- LOCAL_C_INCLUDES += hardware/qcom/display/badger/liboverlay2
- LOCAL_C_INCLUDES += hardware/qcom/display/badger/liboverlay2/src
- LOCAL_SHARED_LIBRARIES += liboverlay2
-endif
- LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay
LOCAL_SHARED_LIBRARIES += liboverlay
endif
-ifeq ($(TARGET_USES_SF_BYPASS),true)
- LOCAL_CFLAGS += -DSF_BYPASS
-endif
-
-ifeq ($(TARGET_GRALLOC_USES_ASHMEM),true)
- LOCAL_CFLAGS += -DUSE_ASHMEM
-endif
-ifeq ($(TARGET_USES_POST_PROCESSING),true)
-LOCAL_CFLAGS += -DUSES_POST_PROCESSING
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/pp/inc
-endif
-
include $(BUILD_SHARED_LIBRARY)
#MemAlloc Library
View
198 libgralloc/a-family/fb_priv.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * 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 FB_PRIV_H
+#define FB_PRIV_H
+#include <linux/fb.h>
+
+#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
+#include "overlayLib.h"
+using namespace overlay;
+#endif
+
+
+#define NUM_FRAMEBUFFERS_MIN 2
+#define NUM_FRAMEBUFFERS_MAX 3
+#define NUM_DEF_FRAME_BUFFERS 2
+
+#define NO_SURFACEFLINGER_SWAPINTERVAL
+#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
+
+#ifdef __cplusplus
+template <class T>
+struct Node
+{
+ T data;
+ Node<T> *next;
+};
+
+template <class T>
+class Queue
+{
+public:
+ Queue(): front(NULL), back(NULL), len(0) {dummy = new T;}
+ ~Queue()
+ {
+ clear();
+ delete dummy;
+ }
+ void push(const T& item) //add an item to the back of the queue
+ {
+ if(len != 0) { //if the queue is not empty
+ back->next = new Node<T>; //create a new node
+ back = back->next; //set the new node as the back node
+ back->data = item;
+ back->next = NULL;
+ } else {
+ back = new Node<T>;
+ back->data = item;
+ back->next = NULL;
+ front = back;
+ }
+ len++;
+ }
+ void pop() //remove the first item from the queue
+ {
+ if (isEmpty())
+ return; //if the queue is empty, no node to dequeue
+ T item = front->data;
+ Node<T> *tmp = front;
+ front = front->next;
+ delete tmp;
+ if(front == NULL) //if the queue is empty, update the back pointer
+ back = NULL;
+ len--;
+ return;
+ }
+ T& getHeadValue() const //return the value of the first item in the queue
+ { //without modification to the structure
+ if (isEmpty()) {
+ LOGE("Error can't get head of empty queue");
+ return *dummy;
+ }
+ return front->data;
+ }
+
+ bool isEmpty() const //returns true if no elements are in the queue
+ {
+ return (front == NULL);
+ }
+
+ size_t size() const //returns the amount of elements in the queue
+ {
+ return len;
+ }
+
+private:
+ Node<T> *front;
+ Node<T> *back;
+ size_t len;
+ void clear()
+ {
+ while (!isEmpty())
+ pop();
+ }
+ T *dummy;
+};
+#endif
+
+#if defined(HDMI_DUAL_DISPLAY)
+enum hdmi_mirroring_state {
+ HDMI_NO_MIRRORING,
+ HDMI_UI_MIRRORING,
+ HDMI_ORIGINAL_RESOLUTION_MIRRORING
+};
+#endif
+
+struct private_handle_t;
+
+struct qbuf_t {
+ buffer_handle_t buf;
+ int idx;
+};
+
+enum buf_state {
+ SUB,
+ REF,
+ AVL
+};
+
+struct avail_t {
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+#ifdef __cplusplus
+ bool is_avail;
+ buf_state state;
+#endif
+};
+
+struct private_module_t {
+ gralloc_module_t base;
+
+ struct private_handle_t* framebuffer;
+ uint32_t fbFormat;
+ uint32_t flags;
+ uint32_t numBuffers;
+ uint32_t bufferMask;
+ pthread_mutex_t lock;
+ buffer_handle_t currentBuffer;
+
+ struct fb_var_screeninfo info;
+ struct fb_fix_screeninfo finfo;
+ float xdpi;
+ float ydpi;
+ float fps;
+ int swapInterval;
+#ifdef __cplusplus
+ Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
+#endif
+ int currentIdx;
+ struct avail_t avail[NUM_FRAMEBUFFERS_MAX];
+ pthread_mutex_t qlock;
+ pthread_cond_t qpost;
+
+ enum {
+ // flag to indicate we'll post this buffer
+ PRIV_USAGE_LOCKED_FOR_POST = 0x80000000,
+ PRIV_MIN_SWAP_INTERVAL = 0,
+ PRIV_MAX_SWAP_INTERVAL = 1,
+ };
+#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
+ Overlay* pobjOverlay;
+ int orientation;
+ int videoOverlay; // VIDEO_OVERLAY - 2D or 3D
+ int secureVideoOverlay; // VideoOverlay is secure
+ uint32_t currentOffset;
+ int enableHDMIOutput; // holds the type of external display
+ bool trueMirrorSupport;
+ bool exitHDMIUILoop;
+ float actionsafeWidthRatio;
+ float actionsafeHeightRatio;
+ bool hdmiStateChanged;
+ hdmi_mirroring_state hdmiMirroringState;
+ pthread_mutex_t overlayLock;
+ pthread_cond_t overlayPost;
+#endif
+ pthread_mutex_t bufferPostLock;
+ pthread_cond_t bufferPostCond;
+ bool bufferPostDone;
+
+};
+
+
+
+#endif /* FB_PRIV_H */
+
View
1  libgralloc/framebuffer.cpp → libgralloc/a-family/framebuffer.cpp
@@ -43,6 +43,7 @@
#include <GLES/gl.h>
#include "gralloc_priv.h"
+#include "fb_priv.h"
#include "gr.h"
#ifdef NO_SURFACEFLINGER_SWAPINTERVAL
#include <cutils/properties.h>
View
189 libgralloc/badger/fb_priv.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * 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 FB_PRIV_H
+#define FB_PRIV_H
+#include <linux/fb.h>
+
+#define NUM_FRAMEBUFFERS_MIN 2
+#define NUM_FRAMEBUFFERS_MAX 3
+#define NUM_DEF_FRAME_BUFFERS 2
+
+#define NO_SURFACEFLINGER_SWAPINTERVAL
+#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
+
+#ifdef __cplusplus
+template <class T>
+struct Node
+{
+ T data;
+ Node<T> *next;
+};
+
+template <class T>
+class Queue
+{
+public:
+ Queue(): front(NULL), back(NULL), len(0) {dummy = new T;}
+ ~Queue()
+ {
+ clear();
+ delete dummy;
+ }
+ void push(const T& item) //add an item to the back of the queue
+ {
+ if(len != 0) { //if the queue is not empty
+ back->next = new Node<T>; //create a new node
+ back = back->next; //set the new node as the back node
+ back->data = item;
+ back->next = NULL;
+ } else {
+ back = new Node<T>;
+ back->data = item;
+ back->next = NULL;
+ front = back;
+ }
+ len++;
+ }
+ void pop() //remove the first item from the queue
+ {
+ if (isEmpty())
+ return; //if the queue is empty, no node to dequeue
+ T item = front->data;
+ Node<T> *tmp = front;
+ front = front->next;
+ delete tmp;
+ if(front == NULL) //if the queue is empty, update the back pointer
+ back = NULL;
+ len--;
+ return;
+ }
+ T& getHeadValue() const //return the value of the first item in the queue
+ { //without modification to the structure
+ if (isEmpty()) {
+ LOGE("Error can't get head of empty queue");
+ return *dummy;
+ }
+ return front->data;
+ }
+
+ bool isEmpty() const //returns true if no elements are in the queue
+ {
+ return (front == NULL);
+ }
+
+ size_t size() const //returns the amount of elements in the queue
+ {
+ return len;
+ }
+
+private:
+ Node<T> *front;
+ Node<T> *back;
+ size_t len;
+ void clear()
+ {
+ while (!isEmpty())
+ pop();
+ }
+ T *dummy;
+};
+#endif
+
+#if defined(HDMI_DUAL_DISPLAY)
+enum hdmi_mirroring_state {
+ HDMI_NO_MIRRORING,
+ HDMI_UI_MIRRORING,
+ HDMI_ORIGINAL_RESOLUTION_MIRRORING
+};
+#endif
+
+struct private_handle_t;
+
+struct qbuf_t {
+ buffer_handle_t buf;
+ int idx;
+};
+
+enum buf_state {
+ SUB,
+ REF,
+ AVL
+};
+
+enum {
+ // flag to indicate we'll post this buffer
+ PRIV_USAGE_LOCKED_FOR_POST = 0x80000000,
+ PRIV_MIN_SWAP_INTERVAL = 0,
+ PRIV_MAX_SWAP_INTERVAL = 1,
+};
+
+
+struct avail_t {
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+#ifdef __cplusplus
+ bool is_avail;
+ buf_state state;
+#endif
+};
+
+struct private_module_t {
+ gralloc_module_t base;
+
+ struct private_handle_t* framebuffer;
+ uint32_t fbFormat;
+ uint32_t flags;
+ uint32_t numBuffers;
+ uint32_t bufferMask;
+ pthread_mutex_t lock;
+ buffer_handle_t currentBuffer;
+
+ struct fb_var_screeninfo info;
+ struct fb_fix_screeninfo finfo;
+ float xdpi;
+ float ydpi;
+ float fps;
+ uint32_t swapInterval;
+#ifdef __cplusplus
+ Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
+#endif
+ int currentIdx;
+ struct avail_t avail[NUM_FRAMEBUFFERS_MAX];
+ pthread_mutex_t qlock;
+ pthread_cond_t qpost;
+
+#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
+ int orientation;
+ int videoOverlay; // VIDEO_OVERLAY - 2D or 3D
+ int secureVideoOverlay; // VideoOverlay is secure
+ uint32_t currentOffset;
+ int enableHDMIOutput; // holds the type of external display
+ bool trueMirrorSupport;
+ bool exitHDMIUILoop;
+ float actionsafeWidthRatio;
+ float actionsafeHeightRatio;
+ bool hdmiStateChanged;
+ hdmi_mirroring_state hdmiMirroringState;
+ pthread_mutex_t overlayLock;
+ pthread_cond_t overlayPost;
+#endif
+};
+
+
+
+#endif /* FB_PRIV_H */
+
View
1,123 libgralloc/badger/framebuffer.cpp
@@ -0,0 +1,1123 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <sys/mman.h>
+
+#include <dlfcn.h>
+
+#include <cutils/ashmem.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <utils/Timers.h>
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+
+#include <GLES/gl.h>
+
+#include "gralloc_priv.h"
+#include "fb_priv.h"
+#include "gr.h"
+#ifdef NO_SURFACEFLINGER_SWAPINTERVAL
+#include <cutils/properties.h>
+#endif
+
+#include <utils/profiler.h>
+#include <qcom_ui.h>
+
+#include "overlayUtils.h"
+#include "overlay.h"
+#include "overlayMgr.h"
+#include "overlayMgrSingleton.h"
+namespace ovutils = overlay2::utils;
+
+#define FB_DEBUG 0
+
+#if defined(HDMI_DUAL_DISPLAY)
+#define EVEN_OUT(x) if (x & 0x0001) {x--;}
+/** min of int a, b */
+static inline int min(int a, int b) {
+ return (a<b) ? a : b;
+}
+/** max of int a, b */
+static inline int max(int a, int b) {
+ return (a>b) ? a : b;
+}
+#endif
+
+char framebufferStateName[] = {'S', 'R', 'A'};
+
+/*****************************************************************************/
+
+enum {
+ MDDI_PANEL = '1',
+ EBI2_PANEL = '2',
+ LCDC_PANEL = '3',
+ EXT_MDDI_PANEL = '4',
+ TV_PANEL = '5'
+};
+
+enum {
+ PAGE_FLIP = 0x00000001,
+ LOCKED = 0x00000002
+};
+
+struct fb_context_t {
+ framebuffer_device_t device;
+};
+
+static int neworientation;
+
+/*****************************************************************************/
+
+static void
+msm_copy_buffer(buffer_handle_t handle, int fd,
+ int width, int height, int format,
+ int x, int y, int w, int h);
+
+static int fb_setSwapInterval(struct framebuffer_device_t* dev,
+ int interval)
+{
+ char pval[PROPERTY_VALUE_MAX];
+ property_get("debug.egl.swapinterval", pval, "-1");
+ int property_interval = atoi(pval);
+ if (property_interval >= 0)
+ interval = property_interval;
+
+ fb_context_t* ctx = (fb_context_t*)dev;
+ private_module_t* m = reinterpret_cast<private_module_t*>(
+ dev->common.module);
+ if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
+ return -EINVAL;
+
+ m->swapInterval = interval;
+ return 0;
+}
+
+static int fb_setUpdateRect(struct framebuffer_device_t* dev,
+ int l, int t, int w, int h)
+{
+ if (((w|h) <= 0) || ((l|t)<0))
+ return -EINVAL;
+ fb_context_t* ctx = (fb_context_t*)dev;
+ private_module_t* m = reinterpret_cast<private_module_t*>(
+ dev->common.module);
+ m->info.reserved[0] = 0x54445055; // "UPDT";
+ m->info.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
+ m->info.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
+ return 0;
+}
+
+static void *disp_loop(void *ptr)
+{
+ struct qbuf_t nxtBuf;
+ static int cur_buf=-1;
+ private_module_t *m = reinterpret_cast<private_module_t*>(ptr);
+
+ while (1) {
+ pthread_mutex_lock(&(m->qlock));
+
+ // wait (sleep) while display queue is empty;
+ if (m->disp.isEmpty()) {
+ pthread_cond_wait(&(m->qpost),&(m->qlock));
+ }
+
+ // dequeue next buff to display and lock it
+ nxtBuf = m->disp.getHeadValue();
+ m->disp.pop();
+ pthread_mutex_unlock(&(m->qlock));
+
+ // post buf out to display synchronously
+ private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>
+ (nxtBuf.buf);
+ const size_t offset = hnd->base - m->framebuffer->base;
+ m->info.activate = FB_ACTIVATE_VBL;
+ m->info.yoffset = offset / m->finfo.line_length;
+
+#if defined(HDMI_DUAL_DISPLAY)
+ pthread_mutex_lock(&m->overlayLock);
+ m->orientation = neworientation;
+ m->currentOffset = offset;
+ m->hdmiStateChanged = true;
+ pthread_cond_signal(&(m->overlayPost));
+ pthread_mutex_unlock(&m->overlayLock);
+#endif
+ if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
+ LOGE("ERROR FBIOPUT_VSCREENINFO failed; frame not displayed");
+ }
+
+ CALC_FPS();
+
+ if (cur_buf == -1) {
+ int nxtAvail = ((nxtBuf.idx + 1) % m->numBuffers);
+ pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
+ m->avail[nxtBuf.idx].is_avail = true;
+ m->avail[nxtBuf.idx].state = REF;
+ pthread_cond_broadcast(&(m->avail[nxtBuf.idx].cond));
+ pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
+ } else {
+ pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
+ if (m->avail[nxtBuf.idx].state != SUB) {
+ LOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", nxtBuf.idx,
+ framebufferStateName[m->avail[nxtBuf.idx].state],
+ framebufferStateName[SUB]);
+ }
+ m->avail[nxtBuf.idx].state = REF;
+ pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
+
+ pthread_mutex_lock(&(m->avail[cur_buf].lock));
+ m->avail[cur_buf].is_avail = true;
+ if (m->avail[cur_buf].state != REF) {
+ LOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", cur_buf,
+ framebufferStateName[m->avail[cur_buf].state],
+ framebufferStateName[REF]);
+ }
+ m->avail[cur_buf].state = AVL;
+ pthread_cond_broadcast(&(m->avail[cur_buf].cond));
+ pthread_mutex_unlock(&(m->avail[cur_buf].lock));
+ }
+ cur_buf = nxtBuf.idx;
+ }
+ return NULL;
+}
+
+#if defined(HDMI_DUAL_DISPLAY)
+static int closeHDMIChannel(private_module_t* m)
+{
+// XXX
+#if 0
+ Overlay* pTemp = m->pobjOverlay;
+ if(pTemp != NULL)
+ pTemp->closeChannel();
+#endif
+ return 0;
+}
+
+// XXX
+#if 0
+static void getSecondaryDisplayDestinationInfo(private_module_t* m, overlay_rect&
+ rect, int& orientation)
+{
+ Overlay* pTemp = m->pobjOverlay;
+ int width = pTemp->getFBWidth();
+ int height = pTemp->getFBHeight();
+ int fbwidth = m->info.xres, fbheight = m->info.yres;
+ rect.x = 0; rect.y = 0;
+ rect.w = width; rect.h = height;
+ int rot = m->orientation;
+ switch(rot) {
+ // ROT_0
+ case 0:
+ // ROT_180
+ case HAL_TRANSFORM_ROT_180:
+ pTemp->getAspectRatioPosition(fbwidth, fbheight,
+ &rect);
+ if(rot == HAL_TRANSFORM_ROT_180)
+ orientation = HAL_TRANSFORM_ROT_180;
+ else
+ orientation = 0;
+ break;
+ // ROT_90
+ case HAL_TRANSFORM_ROT_90:
+ // ROT_270
+ case HAL_TRANSFORM_ROT_270:
+ //Calculate the Aspectratio for the UI
+ //in the landscape mode
+ //Width and height will be swapped as there
+ //is rotation
+ pTemp->getAspectRatioPosition(fbheight, fbwidth,
+ &rect);
+
+ if(rot == HAL_TRANSFORM_ROT_90)
+ orientation = HAL_TRANSFORM_ROT_270;
+ else if(rot == HAL_TRANSFORM_ROT_270)
+ orientation = HAL_TRANSFORM_ROT_90;
+ break;
+ }
+ return;
+}
+#endif
+
+/* Determine overlay state based on whether hardware supports true UI
+ mirroring and whether video is playing or not */
+static ovutils::eOverlayState getOverlayState(struct private_module_t* module)
+{
+ overlay2::OverlayMgr* ovMgr =
+ overlay2::OverlayMgrSingleton::getOverlayMgr();
+ overlay2::Overlay& ov = ovMgr->ov();
+
+ // Default to existing state
+ ovutils::eOverlayState state = ov.getState();
+
+ // Sanity check
+ if (!module) {
+ LOGE("%s: NULL module", __FUNCTION__);
+ return state;
+ }
+
+ // Check if video is playing or not
+ if (module->videoOverlay) {
+ // Video is playing, check if hardware supports true UI mirroring
+ if (module->trueMirrorSupport) {
+ // True UI mirroring is supported by hardware
+ if (ov.getState() == ovutils::OV_2D_VIDEO_ON_PANEL) {
+ // Currently playing 2D video
+ state = ovutils::OV_2D_TRUE_UI_MIRROR;
+ } else if (ov.getState() == ovutils::OV_3D_VIDEO_ON_2D_PANEL) {
+ // Currently playing M3D video
+ // FIXME: Support M3D true UI mirroring
+ state = ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV;
+ }
+ } else {
+ // True UI mirroring is not supported by hardware
+ if (ov.getState() == ovutils::OV_2D_VIDEO_ON_PANEL) {
+ // Currently playing 2D video
+ state = ovutils::OV_2D_VIDEO_ON_PANEL_TV;
+ } else if (ov.getState() == ovutils::OV_3D_VIDEO_ON_2D_PANEL) {
+ // Currently playing M3D video
+ state = ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV;
+ }
+ }
+ } else {
+ // Video is not playing, true UI mirroring support is irrelevant
+ state = ovutils::OV_UI_MIRROR;
+ }
+
+ return state;
+}
+
+/* Set overlay state */
+static void setOverlayState(ovutils::eOverlayState state)
+{
+ overlay2::OverlayMgr* ovMgr =
+ overlay2::OverlayMgrSingleton::getOverlayMgr();
+ if (!ovMgr) {
+ LOGE("%s: NULL ovMgr", __FUNCTION__);
+ return;
+ }
+
+ ovMgr->setState(state);
+}
+
+static void *hdmi_ui_loop(void *ptr)
+{
+ private_module_t* m = reinterpret_cast<private_module_t*>(ptr);
+ while (1) {
+ pthread_mutex_lock(&m->overlayLock);
+ while(!(m->hdmiStateChanged))
+ pthread_cond_wait(&(m->overlayPost), &(m->overlayLock));
+
+ m->hdmiStateChanged = false;
+ if (m->exitHDMIUILoop) {
+ pthread_mutex_unlock(&m->overlayLock);
+ return NULL;
+ }
+
+ // No need to mirror UI if HDMI is not on
+ if (!m->enableHDMIOutput) {
+ LOGE_IF(FB_DEBUG, "%s: hdmi not ON", __FUNCTION__);
+ pthread_mutex_unlock(&m->overlayLock);
+ continue;
+ }
+
+ overlay2::OverlayMgr* ovMgr =
+ overlay2::OverlayMgrSingleton::getOverlayMgr();
+ overlay2::Overlay& ov = ovMgr->ov();
+
+ // Set overlay state
+ ovutils::eOverlayState state = getOverlayState(m);
+ setOverlayState(state);
+
+ // Determine the RGB pipe for UI depending on the state
+ ovutils::eDest dest = ovutils::OV_PIPE_ALL;
+ if (state == ovutils::OV_2D_TRUE_UI_MIRROR) {
+ // True UI mirroring state: external RGB pipe is OV_PIPE2
+ dest = ovutils::OV_PIPE2;
+ } else if (state == ovutils::OV_UI_MIRROR) {
+ // UI-only mirroring state: external RGB pipe is OV_PIPE0
+ dest = ovutils::OV_PIPE0;
+ } else {
+ // No UI in this case
+ pthread_mutex_unlock(&m->overlayLock);
+ continue;
+ }
+
+ if (m->hdmiMirroringState == HDMI_UI_MIRRORING) {
+ int alignedW = ALIGN(m->info.xres, 32);
+
+ private_handle_t const* hnd =
+ reinterpret_cast<private_handle_t const*>(m->framebuffer);
+ unsigned int width = alignedW;
+ unsigned int height = hnd->height;
+ unsigned int format = hnd->format;
+ unsigned int size = hnd->size;
+
+ ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
+ // External display connected during secure video playback
+ // Open secure UI session
+ // NOTE: when external display is already connected and then secure
+ // playback is started, we dont have to do anything
+ if (m->secureVideoOverlay) {
+ ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
+ }
+
+ ovutils::Whf whf(width, height, format, size);
+ ovutils::PipeArgs parg(mdpFlags,
+ ovutils::OVERLAY_TRANSFORM_0,
+ whf,
+ ovutils::WAIT,
+ ovutils::ZORDER_0,
+ ovutils::IS_FG_OFF,
+ ovutils::ROT_FLAG_ENABLED,
+ ovutils::PMEM_SRC_SMI,
+ ovutils::RECONFIG_OFF);
+ ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
+ bool ret = ov.setSource(pargs, dest);
+ if (!ret) {
+ LOGE("%s setSource failed", __FUNCTION__);
+ }
+
+ // we need to communicate m->orientation that will get some
+ // modifications within setParameter func.
+ // FIXME that is ugly.
+ const ovutils::Params prms (ovutils::OVERLAY_TRANSFORM_UI,
+ m->orientation);
+ ov.setParameter(prms, dest);
+ if (!ret) {
+ LOGE("%s setParameter failed transform", __FUNCTION__);
+ }
+
+ // x,y,w,h
+ ovutils::Dim dcrop(0, 0, m->info.xres, m->info.yres);
+ ov.setMemoryId(m->framebuffer->fd, dest);
+ ret = ov.setCrop(dcrop, dest);
+ if (!ret) {
+ LOGE("%s setCrop failed", __FUNCTION__);
+ }
+
+ ovutils::Dim pdim (m->info.xres,
+ m->info.yres,
+ 0,
+ 0,
+ m->orientation);
+ ret = ov.setPosition(pdim, dest);
+ if (!ret) {
+ LOGE("%s setPosition failed", __FUNCTION__);
+ }
+
+ if (!ov.commit(dest)) {
+ LOGE("%s commit fails", __FUNCTION__);
+ }
+
+ ret = ov.queueBuffer(m->currentOffset, dest);
+ if (!ret) {
+ LOGE("%s queueBuffer failed", __FUNCTION__);
+ }
+ } else {
+ setOverlayState(ovutils::OV_CLOSED);
+ }
+ pthread_mutex_unlock(&m->overlayLock);
+ }
+ return NULL;
+}
+
+static int fb_videoOverlayStarted(struct framebuffer_device_t* dev, int started)
+{
+ LOGE_IF(FB_DEBUG, "%s started=%d", __FUNCTION__, started);
+ private_module_t* m = reinterpret_cast<private_module_t*>(
+ dev->common.module);
+ pthread_mutex_lock(&m->overlayLock);
+ if(started != m->videoOverlay) {
+ m->videoOverlay = started;
+ if (!m->trueMirrorSupport) {
+ m->hdmiStateChanged = true;
+ if (started) {
+ m->hdmiMirroringState = HDMI_NO_MIRRORING;
+ ovutils::eOverlayState state = getOverlayState(m);
+ setOverlayState(state);
+ } else if (m->enableHDMIOutput)
+ m->hdmiMirroringState = HDMI_UI_MIRRORING;
+ pthread_cond_signal(&(m->overlayPost));
+ }
+ }
+ pthread_mutex_unlock(&m->overlayLock);
+ return 0;
+}
+
+static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int externaltype)
+{
+ LOGE_IF(FB_DEBUG, "%s externaltype=%d", __FUNCTION__, externaltype);
+ private_module_t* m = reinterpret_cast<private_module_t*>(
+ dev->common.module);
+ pthread_mutex_lock(&m->overlayLock);
+ //Check if true mirroring can be supported
+ m->trueMirrorSupport = ovutils::FrameBufferInfo::getInstance()->supportTrueMirroring();
+ m->enableHDMIOutput = externaltype;
+ if(externaltype) {
+ if (m->trueMirrorSupport) {
+ m->hdmiMirroringState = HDMI_UI_MIRRORING;
+ } else {
+ if(!m->videoOverlay)
+ m->hdmiMirroringState = HDMI_UI_MIRRORING;
+ }
+ } else if (!externaltype) {
+ // Either HDMI is disconnected or suspend occurred
+ m->hdmiMirroringState = HDMI_NO_MIRRORING;
+ ovutils::eOverlayState state = getOverlayState(m);
+ setOverlayState(state);
+ }
+ m->hdmiStateChanged = true;
+ pthread_cond_signal(&(m->overlayPost));
+ pthread_mutex_unlock(&m->overlayLock);
+ return 0;
+}
+
+static int fb_orientationChanged(struct framebuffer_device_t* dev, int orientation)
+{
+ private_module_t* m = reinterpret_cast<private_module_t*>(
+ dev->common.module);
+ pthread_mutex_lock(&m->overlayLock);
+ neworientation = orientation;
+ pthread_mutex_unlock(&m->overlayLock);
+ return 0;
+}
+
+static int handle_open_secure_start(private_module_t* m) {
+ pthread_mutex_lock(&m->overlayLock);
+ m->hdmiMirroringState = HDMI_NO_MIRRORING;
+ m->secureVideoOverlay = true;
+ pthread_mutex_unlock(&m->overlayLock);
+ return 0;
+}
+
+static int handle_open_secure_end(private_module_t* m) {
+ pthread_mutex_lock(&m->overlayLock);
+ if (m->enableHDMIOutput) {
+ if (m->trueMirrorSupport) {
+ m->hdmiMirroringState = HDMI_UI_MIRRORING;
+ } else if(!m->videoOverlay) {
+ m->hdmiMirroringState = HDMI_UI_MIRRORING;
+ }
+ m->hdmiStateChanged = true;
+ pthread_cond_signal(&(m->overlayPost));
+ }
+ pthread_mutex_unlock(&m->overlayLock);
+ return 0;
+}
+
+static int handle_close_secure_start(private_module_t* m) {
+ pthread_mutex_lock(&m->overlayLock);
+ m->hdmiMirroringState = HDMI_NO_MIRRORING;
+ m->secureVideoOverlay = false;
+ pthread_mutex_unlock(&m->overlayLock);
+ return 0;
+}
+
+static int handle_close_secure_end(private_module_t* m) {
+ pthread_mutex_lock(&m->overlayLock);
+ if (m->enableHDMIOutput) {
+ if (m->trueMirrorSupport) {
+ m->hdmiMirroringState = HDMI_UI_MIRRORING;
+ } else if(!m->videoOverlay) {
+ m->hdmiMirroringState = HDMI_UI_MIRRORING;
+ }
+ m->hdmiStateChanged = true;
+ pthread_cond_signal(&(m->overlayPost));
+ }
+ pthread_mutex_unlock(&m->overlayLock);
+ return 0;
+}
+#endif
+
+
+
+/* fb_perform - used to add custom event and handle them in fb HAL
+ * Used for external display related functions as of now
+*/
+static int fb_perform(struct framebuffer_device_t* dev, int event, int value)
+{
+ private_module_t* m = reinterpret_cast<private_module_t*>(
+ dev->common.module);
+ switch(event) {
+#if defined(HDMI_DUAL_DISPLAY)
+ case EVENT_EXTERNAL_DISPLAY:
+ fb_enableHDMIOutput(dev, value);
+ break;
+ case EVENT_VIDEO_OVERLAY:
+ fb_videoOverlayStarted(dev, value);
+ break;
+ case EVENT_ORIENTATION_CHANGE:
+ fb_orientationChanged(dev, value);
+ break;
+ case EVENT_OVERLAY_STATE_CHANGE:
+ if (value == OVERLAY_STATE_CHANGE_START) {
+ // When state change starts, get a lock on overlay
+ pthread_mutex_lock(&m->overlayLock);
+ } else if (value == OVERLAY_STATE_CHANGE_END) {
+ // When state change is complete, unlock overlay
+ pthread_mutex_unlock(&m->overlayLock);
+ }
+ break;
+ case EVENT_OPEN_SECURE_START:
+ handle_open_secure_start(m);
+ break;
+ case EVENT_OPEN_SECURE_END:
+ handle_open_secure_end(m);
+ break;
+ case EVENT_CLOSE_SECURE_START:
+ handle_close_secure_start(m);
+ break;
+ case EVENT_CLOSE_SECURE_END:
+ handle_close_secure_end(m);
+ break;
+#endif
+ default:
+ LOGE("In %s: UNKNOWN Event = %d!!!", __FUNCTION__, event);
+ break;
+ }
+ return 0;
+ }
+
+
+static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
+{
+ if (private_handle_t::validate(buffer) < 0)
+ return -EINVAL;
+
+ int nxtIdx, futureIdx = -1;
+ bool reuse;
+ struct qbuf_t qb;
+ fb_context_t* ctx = (fb_context_t*)dev;
+
+ private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
+ private_module_t* m = reinterpret_cast<private_module_t*>(
+ dev->common.module);
+
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
+
+ reuse = false;
+ nxtIdx = (m->currentIdx + 1) % m->numBuffers;
+ futureIdx = (nxtIdx + 1) % m->numBuffers;
+
+ if (m->swapInterval == 0) {
+ // if SwapInterval = 0 and no buffers available then reuse
+ // current buf for next rendering so don't post new buffer
+ if (pthread_mutex_trylock(&(m->avail[nxtIdx].lock))) {
+ reuse = true;
+ } else {
+ if (! m->avail[nxtIdx].is_avail)
+ reuse = true;
+ pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
+ }
+ }
+
+ if(!reuse){
+ // unlock previous ("current") Buffer and lock the new buffer
+ m->base.lock(&m->base, buffer,
+ PRIV_USAGE_LOCKED_FOR_POST,
+ 0,0, m->info.xres, m->info.yres, NULL);
+
+ // post/queue the new buffer
+ pthread_mutex_lock(&(m->avail[nxtIdx].lock));
+ if (m->avail[nxtIdx].is_avail != true) {
+ LOGE_IF(m->swapInterval != 0, "Found %d buf to be not avail", nxtIdx);
+ }
+
+ m->avail[nxtIdx].is_avail = false;
+
+ if (m->avail[nxtIdx].state != AVL) {
+ LOGD("[%d] state %c, expected %c", nxtIdx,
+ framebufferStateName[m->avail[nxtIdx].state],
+ framebufferStateName[AVL]);
+ }
+
+ m->avail[nxtIdx].state = SUB;
+ pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
+
+ qb.idx = nxtIdx;
+ qb.buf = buffer;
+ pthread_mutex_lock(&(m->qlock));
+ m->disp.push(qb);
+ pthread_cond_signal(&(m->qpost));
+ pthread_mutex_unlock(&(m->qlock));
+
+ if (m->currentBuffer)
+ m->base.unlock(&m->base, m->currentBuffer);
+
+ m->currentBuffer = buffer;
+ m->currentIdx = nxtIdx;
+ } else {
+ if (m->currentBuffer)
+ m->base.unlock(&m->base, m->currentBuffer);
+ m->base.lock(&m->base, buffer,
+ PRIV_USAGE_LOCKED_FOR_POST,
+ 0,0, m->info.xres, m->info.yres, NULL);
+ m->currentBuffer = buffer;
+ }
+
+ } else {
+ void* fb_vaddr;
+ void* buffer_vaddr;
+ m->base.lock(&m->base, m->framebuffer,
+ GRALLOC_USAGE_SW_WRITE_RARELY,
+ 0, 0, m->info.xres, m->info.yres,
+ &fb_vaddr);
+
+ m->base.lock(&m->base, buffer,
+ GRALLOC_USAGE_SW_READ_RARELY,
+ 0, 0, m->info.xres, m->info.yres,
+ &buffer_vaddr);
+
+ //memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
+
+ msm_copy_buffer(
+ m->framebuffer, m->framebuffer->fd,
+ m->info.xres, m->info.yres, m->fbFormat,
+ m->info.xoffset, m->info.yoffset,
+ m->info.width, m->info.height);
+
+ m->base.unlock(&m->base, buffer);
+ m->base.unlock(&m->base, m->framebuffer);
+ }
+
+ LOGD_IF(FB_DEBUG, "Framebuffer state: [0] = %c [1] = %c [2] = %c",
+ framebufferStateName[m->avail[0].state],
+ framebufferStateName[m->avail[1].state],
+ framebufferStateName[m->avail[2].state]);
+ return 0;
+}
+
+static int fb_compositionComplete(struct framebuffer_device_t* dev)
+{
+ // TODO: Properly implement composition complete callback
+ glFinish();
+
+ return 0;
+}
+
+static int fb_lockBuffer(struct framebuffer_device_t* dev, int index)
+{
+ private_module_t* m = reinterpret_cast<private_module_t*>(
+ dev->common.module);
+
+ // Return immediately if the buffer is available
+ if ((m->avail[index].state == AVL) || (m->swapInterval == 0))
+ return 0;
+
+ pthread_mutex_lock(&(m->avail[index].lock));
+ while (m->avail[index].state != AVL) {
+ pthread_cond_wait(&(m->avail[index].cond),
+ &(m->avail[index].lock));
+ }
+ pthread_mutex_unlock(&(m->avail[index].lock));
+
+ return 0;
+}
+
+/*****************************************************************************/
+
+int mapFrameBufferLocked(struct private_module_t* module)
+{
+ // already initialized...
+ if (module->framebuffer) {
+ return 0;
+ }
+ char const * const device_template[] = {
+ "/dev/graphics/fb%u",
+ "/dev/fb%u",
+ 0 };
+
+ int fd = -1;
+ int i=0;
+ char name[64];
+ char property[PROPERTY_VALUE_MAX];
+
+ while ((fd==-1) && device_template[i]) {
+ snprintf(name, 64, device_template[i], 0);
+ fd = open(name, O_RDWR, 0);
+ i++;
+ }
+ if (fd < 0)
+ return -errno;
+
+ struct fb_fix_screeninfo finfo;
+ if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+ return -errno;
+
+ struct fb_var_screeninfo info;
+ if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+ return -errno;
+
+ info.reserved[0] = 0;
+ info.reserved[1] = 0;
+ info.reserved[2] = 0;
+ info.xoffset = 0;
+ info.yoffset = 0;
+ info.activate = FB_ACTIVATE_NOW;
+
+ /* Interpretation of offset for color fields: All offsets are from the right,
+ * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
+ * can use the offset as right argument to <<). A pixel afterwards is a bit
+ * stream and is written to video memory as that unmodified. This implies
+ * big-endian byte order if bits_per_pixel is greater than 8.
+ */
+
+ if(info.bits_per_pixel == 32) {
+ /*
+ * Explicitly request RGBA_8888
+ */
+ info.bits_per_pixel = 32;
+ info.red.offset = 24;
+ info.red.length = 8;
+ info.green.offset = 16;
+ info.green.length = 8;
+ info.blue.offset = 8;
+ info.blue.length = 8;
+ info.transp.offset = 0;
+ info.transp.length = 8;
+
+ /* Note: the GL driver does not have a r=8 g=8 b=8 a=0 config, so if we do
+ * not use the MDP for composition (i.e. hw composition == 0), ask for
+ * RGBA instead of RGBX. */
+ if (property_get("debug.sf.hw", property, NULL) > 0 && atoi(property) == 0)
+ module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
+ else if(property_get("debug.composition.type", property, NULL) > 0 && (strncmp(property, "mdp", 3) == 0))
+ module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
+ else
+ module->fbFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+ } else {
+ /*
+ * Explicitly request 5/6/5
+ */
+ info.bits_per_pixel = 16;
+ info.red.offset = 11;
+ info.red.length = 5;
+ info.green.offset = 5;
+ info.green.length = 6;
+ info.blue.offset = 0;
+ info.blue.length = 5;
+ info.transp.offset = 0;
+ info.transp.length = 0;
+ module->fbFormat = HAL_PIXEL_FORMAT_RGB_565;
+ }
+
+ //adreno needs 4k aligned offsets. Max hole size is 4096-1
+ int size = roundUpToPageSize(info.yres * info.xres * (info.bits_per_pixel/8));
+
+ /*
+ * Request NUM_BUFFERS screens (at lest 2 for page flipping)
+ */
+ int numberOfBuffers = (int)(finfo.smem_len/size);
+ LOGV("num supported framebuffers in kernel = %d", numberOfBuffers);
+
+ if (property_get("debug.gr.numframebuffers", property, NULL) > 0) {
+ int num = atoi(property);
+ if ((num >= NUM_FRAMEBUFFERS_MIN) && (num <= NUM_FRAMEBUFFERS_MAX)) {
+ numberOfBuffers = num;
+ }
+ }
+ if (numberOfBuffers > NUM_FRAMEBUFFERS_MAX)
+ numberOfBuffers = NUM_FRAMEBUFFERS_MAX;
+
+ LOGV("We support %d buffers", numberOfBuffers);
+
+ //consider the included hole by 4k alignment
+ uint32_t line_length = (info.xres * info.bits_per_pixel / 8);
+ info.yres_virtual = (size * numberOfBuffers) / line_length;
+
+ uint32_t flags = PAGE_FLIP;
+ if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
+ info.yres_virtual = size / line_length;
+ flags &= ~PAGE_FLIP;
+ LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
+ }
+
+ if (info.yres_virtual < ((size * 2) / line_length) ) {
+ // we need at least 2 for page-flipping
+ info.yres_virtual = size / line_length;
+ flags &= ~PAGE_FLIP;
+ LOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
+ info.yres_virtual, info.yres*2);
+ }
+
+ if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+ return -errno;
+
+ if (int(info.width) <= 0 || int(info.height) <= 0) {
+ // the driver doesn't return that information
+ // default to 160 dpi
+ info.width = ((info.xres * 25.4f)/160.0f + 0.5f);
+ info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
+ }
+
+ float xdpi = (info.xres * 25.4f) / info.width;
+ float ydpi = (info.yres * 25.4f) / info.height;
+ //The reserved[4] field is used to store FPS by the driver.
+ float fps = info.reserved[4];
+
+ LOGI( "using (fd=%d)\n"
+ "id = %s\n"
+ "xres = %d px\n"
+ "yres = %d px\n"
+ "xres_virtual = %d px\n"
+ "yres_virtual = %d px\n"
+ "bpp = %d\n"
+ "r = %2u:%u\n"
+ "g = %2u:%u\n"
+ "b = %2u:%u\n",
+ fd,
+ finfo.id,
+ info.xres,
+ info.yres,
+ info.xres_virtual,
+ info.yres_virtual,
+ info.bits_per_pixel,
+ info.red.offset, info.red.length,
+ info.green.offset, info.green.length,
+ info.blue.offset, info.blue.length
+ );
+
+ LOGI( "width = %d mm (%f dpi)\n"
+ "height = %d mm (%f dpi)\n"
+ "refresh rate = %.2f Hz\n",
+ info.width, xdpi,
+ info.height, ydpi,
+ fps
+ );
+
+
+ if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+ return -errno;
+
+ if (finfo.smem_len <= 0)
+ return -errno;
+
+ module->flags = flags;
+ module->info = info;
+ module->finfo = finfo;
+ module->xdpi = xdpi;
+ module->ydpi = ydpi;
+ module->fps = fps;
+
+#ifdef NO_SURFACEFLINGER_SWAPINTERVAL
+ char pval[PROPERTY_VALUE_MAX];
+ property_get("debug.gr.swapinterval", pval, "1");
+ module->swapInterval = atoi(pval);
+ if (module->swapInterval < PRIV_MIN_SWAP_INTERVAL ||
+ module->swapInterval > PRIV_MAX_SWAP_INTERVAL) {
+ module->swapInterval = 1;
+ LOGW("Out of range (%d to %d) value for debug.gr.swapinterval, using 1",
+ PRIV_MIN_SWAP_INTERVAL,
+ PRIV_MAX_SWAP_INTERVAL);
+ }
+
+#else
+ /* when surfaceflinger supports swapInterval then can just do this */
+ module->swapInterval = 1;
+#endif
+
+ CALC_INIT();
+
+ module->currentIdx = -1;
+ pthread_cond_init(&(module->qpost), NULL);
+ pthread_mutex_init(&(module->qlock), NULL);
+ for (i = 0; i < NUM_FRAMEBUFFERS_MAX; i++) {
+ pthread_mutex_init(&(module->avail[i].lock), NULL);
+ pthread_cond_init(&(module->avail[i].cond), NULL);
+ module->avail[i].is_avail = true;
+ module->avail[i].state = AVL;
+ }
+
+ /* create display update thread */
+ pthread_t thread1;
+ if (pthread_create(&thread1, NULL, &disp_loop, (void *) module)) {
+ return -errno;
+ }
+
+ /*
+ * map the framebuffer
+ */
+
+ int err;
+ module->numBuffers = info.yres_virtual / info.yres;
+ module->bufferMask = 0;
+ //adreno needs page aligned offsets. Align the fbsize to pagesize.
+ size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres) * module->numBuffers;
+ module->framebuffer = new private_handle_t(fd, fbSize,
+ private_handle_t::PRIV_FLAGS_USES_PMEM, BUFFER_TYPE_UI,
+ module->fbFormat, info.xres, info.yres);
+ void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (vaddr == MAP_FAILED) {
+ LOGE("Error mapping the framebuffer (%s)", strerror(errno));
+ return -errno;
+ }
+ module->framebuffer->base = intptr_t(vaddr);
+ memset(vaddr, 0, fbSize);
+
+#if defined(HDMI_DUAL_DISPLAY)
+ /* Overlay for HDMI*/
+ pthread_mutex_init(&(module->overlayLock), NULL);
+ pthread_cond_init(&(module->overlayPost), NULL);
+ module->currentOffset = 0;
+ module->exitHDMIUILoop = false;
+ module->hdmiStateChanged = false;
+ pthread_t hdmiUIThread;
+ pthread_create(&hdmiUIThread, NULL, &hdmi_ui_loop, (void *) module);
+ module->hdmiMirroringState = HDMI_NO_MIRRORING;
+ module->trueMirrorSupport = false;
+#endif
+
+ return 0;
+}
+
+static int mapFrameBuffer(struct private_module_t* module)
+{
+ pthread_mutex_lock(&module->lock);
+ int err = mapFrameBufferLocked(module);
+ pthread_mutex_unlock(&module->lock);
+ return err;
+}
+
+/*****************************************************************************/
+
+static int fb_close(struct hw_device_t *dev)
+{
+ fb_context_t* ctx = (fb_context_t*)dev;
+#if defined(HDMI_DUAL_DISPLAY)
+ private_module_t* m = reinterpret_cast<private_module_t*>(
+ ctx->device.common.module);
+ pthread_mutex_lock(&m->overlayLock);
+ m->exitHDMIUILoop = true;
+ pthread_cond_signal(&(m->overlayPost));
+ pthread_mutex_unlock(&m->overlayLock);
+#endif
+ if (ctx) {
+ free(ctx);
+ }
+ return 0;
+}
+
+int fb_device_open(hw_module_t const* module, const char* name,
+ hw_device_t** device)
+{
+ int status = -EINVAL;
+ if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
+ alloc_device_t* gralloc_device;
+ status = gralloc_open(module, &gralloc_device);
+ if (status < 0)
+ return status;
+
+ /* initialize our state here */
+ fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
+ 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 = fb_close;
+ dev->device.setSwapInterval = fb_setSwapInterval;
+ dev->device.post = fb_post;
+ dev->device.setUpdateRect = 0;
+ dev->device.compositionComplete = fb_compositionComplete;
+ dev->device.lockBuffer = fb_lockBuffer;
+#if defined(HDMI_DUAL_DISPLAY)
+ dev->device.perform = fb_perform;
+#endif
+
+ private_module_t* m = (private_module_t*)module;
+ status = mapFrameBuffer(m);
+ if (status >= 0) {
+ int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
+ const_cast<uint32_t&>(dev->device.flags) = 0;
+ const_cast<uint32_t&>(dev->device.width) = m->info.xres;
+ const_cast<uint32_t&>(dev->device.height) = m->info.yres;
+ const_cast<int&>(dev->device.stride) = stride;
+ const_cast<int&>(dev->device.format) = m->fbFormat;
+ const_cast<float&>(dev->device.xdpi) = m->xdpi;
+ const_cast<float&>(dev->device.ydpi) = m->ydpi;
+ const_cast<float&>(dev->device.fps) = m->fps;
+ const_cast<int&>(dev->device.minSwapInterval) = PRIV_MIN_SWAP_INTERVAL;
+ const_cast<int&>(dev->device.maxSwapInterval) = PRIV_MAX_SWAP_INTERVAL;
+ const_cast<int&>(dev->device.numFramebuffers) = m->numBuffers;
+ if (m->finfo.reserved[0] == 0x5444 &&
+ m->finfo.reserved[1] == 0x5055) {
+ dev->device.setUpdateRect = fb_setUpdateRect;
+ LOGD("UPDATE_ON_DEMAND supported");
+ }
+
+ *device = &dev->device.common;
+ }
+
+ // Close the gralloc module
+ gralloc_close(gralloc_device);
+ }
+ return status;
+}
+
+/* Copy a pmem buffer to the framebuffer */
+
+static void
+msm_copy_buffer(buffer_handle_t handle, int fd,
+ int width, int height, int format,
+ int x, int y, int w, int h)
+{
+ struct {
+ unsigned int count;
+ mdp_blit_req req;
+ } blit;
+ private_handle_t *priv = (private_handle_t*) handle;
+
+ memset(&blit, 0, sizeof(blit));
+ blit.count = 1;
+
+ blit.req.flags = 0;
+ blit.req.alpha = 0xff;
+ blit.req.transp_mask = 0xffffffff;
+
+ blit.req.src.width = width;
+ blit.req.src.height = height;
+ blit.req.src.offset = 0;
+ blit.req.src.memory_id = priv->fd;
+
+ blit.req.dst.width = width;
+ blit.req.dst.height = height;
+ blit.req.dst.offset = 0;
+ blit.req.dst.memory_id = fd;
+ blit.req.dst.format = format;
+
+ blit.req.src_rect.x = blit.req.dst_rect.x = x;
+ blit.req.src_rect.y = blit.req.dst_rect.y = y;
+ blit.req.src_rect.w = blit.req.dst_rect.w = w;
+ blit.req.src_rect.h = blit.req.dst_rect.h = h;
+
+ if (ioctl(fd, MSMFB_BLIT, &blit))
+ LOGE("MSMFB_BLIT failed = %d", -errno);
+}
View
1  libgralloc/gpu.h
@@ -28,6 +28,7 @@
#include <utils/RefBase.h>
#include "gralloc_priv.h"
+#include <fb_priv.h>
namespace gralloc {
class IAllocController;
View
186 libgralloc/gralloc_priv.h
@@ -28,13 +28,6 @@
#include <cutils/native_handle.h>
-#include <linux/fb.h>
-
-#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
-#include "overlayLib.h"
-using namespace overlay;
-#endif
-
#include <cutils/log.h>
enum {
@@ -111,100 +104,12 @@ enum {
CPU_COMPOSITION,
};
-/* numbers of max buffers for page flipping */
-#define NUM_FRAMEBUFFERS_MIN 2
-#define NUM_FRAMEBUFFERS_MAX 3
-
-/* number of default bufers for page flipping */
-#define NUM_DEF_FRAME_BUFFERS 2
-#define NO_SURFACEFLINGER_SWAPINTERVAL
#define INTERLACE_MASK 0x80
#define S3D_FORMAT_MASK 0xFF000
-#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
#define DEVICE_PMEM "/dev/pmem"
#define DEVICE_PMEM_ADSP "/dev/pmem_adsp"
#define DEVICE_PMEM_SMIPOOL "/dev/pmem_smipool"
/*****************************************************************************/
-#ifdef __cplusplus
-
-//XXX: Remove framebuffer specific classes and defines to a different header
-template <class T>
-struct Node
-{
- T data;
- Node<T> *next;
-};
-
-template <class T>
-class Queue
-{
-public:
- Queue(): front(NULL), back(NULL), len(0) {dummy = new T;}
- ~Queue()
- {
- clear();
- delete dummy;
- }
- void push(const T& item) //add an item to the back of the queue
- {
- if(len != 0) { //if the queue is not empty
- back->next = new Node<T>; //create a new node
- back = back->next; //set the new node as the back node
- back->data = item;
- back->next = NULL;
- } else {
- back = new Node<T>;
- back->data = item;
- back->next = NULL;
- front = back;
- }
- len++;
- }
- void pop() //remove the first item from the queue
- {
- if (isEmpty())
- return; //if the queue is empty, no node to dequeue
- T item = front->data;
- Node<T> *tmp = front;
- front = front->next;
- delete tmp;
- if(front == NULL) //if the queue is empty, update the back pointer
- back = NULL;
- len--;
- return;
- }
- T& getHeadValue() const //return the value of the first item in the queue
- { //without modification to the structure
- if (isEmpty()) {
- LOGE("Error can't get head of empty queue");
- return *dummy;
- }
- return front->data;
- }
-
- bool isEmpty() const //returns true if no elements are in the queue
- {
- return (front == NULL);
- }
-
- size_t size() const //returns the amount of elements in the queue
- {
- return len;
- }
-
-private:
- Node<T> *front;
- Node<T> *back;
- size_t len;
- void clear()
- {
- while (!isEmpty())
- pop();
- }
- T *dummy;
-};
-#endif
-
enum {
/* OEM specific HAL formats */
HAL_PIXEL_FORMAT_NV12_ENCODEABLE = 0x102,
@@ -234,95 +139,8 @@ enum {
};
enum {
- BUFFER_TYPE_UI = 0,
- BUFFER_TYPE_VIDEO
-};
-
-#if defined(HDMI_DUAL_DISPLAY)
-enum hdmi_mirroring_state {
- HDMI_NO_MIRRORING,
- HDMI_UI_MIRRORING,
- HDMI_ORIGINAL_RESOLUTION_MIRRORING
-};
-#endif
-/*****************************************************************************/
-
-struct private_module_t;
-struct private_handle_t;
-struct PmemAllocator;
-
-struct qbuf_t {
- buffer_handle_t buf;
- int idx;
-};
-
-enum buf_state {
- SUB,
- REF,
- AVL
-};
-
-struct avail_t {
- pthread_mutex_t lock;
- pthread_cond_t cond;
-#ifdef __cplusplus
- bool is_avail;
- buf_state state;
-#endif
-};
-
-struct private_module_t {
- gralloc_module_t base;
-
- struct private_handle_t* framebuffer;
- uint32_t fbFormat;
- uint32_t flags;
- uint32_t numBuffers;
- uint32_t bufferMask;
- pthread_mutex_t lock;
- buffer_handle_t currentBuffer;
-
- struct fb_var_screeninfo info;
- struct fb_fix_screeninfo finfo;
- float xdpi;
- float ydpi;
- float fps;
- int swapInterval;
-#ifdef __cplusplus
- Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
-#endif
- int currentIdx;
- struct avail_t avail[NUM_FRAMEBUFFERS_MAX];
- pthread_mutex_t qlock;
- pthread_cond_t qpost;
-
- enum {
- // flag to indicate we'll post this buffer
- PRIV_USAGE_LOCKED_FOR_POST = 0x80000000,
- PRIV_MIN_SWAP_INTERVAL = 0,
- PRIV_MAX_SWAP_INTERVAL = 1,
- };
-#if defined(__cplusplus)
-#if defined(HDMI_DUAL_DISPLAY)
- Overlay* pobjOverlay;
- int orientation;
- int videoOverlay; // VIDEO_OVERLAY - 2D or 3D
- int secureVideoOverlay; // VideoOverlay is secure
- uint32_t currentOffset;
- int enableHDMIOutput; // holds the type of external display
- bool trueMirrorSupport;
- bool exitHDMIUILoop;
- float actionsafeWidthRatio;
- float actionsafeHeightRatio;
- bool hdmiStateChanged;
- hdmi_mirroring_state hdmiMirroringState;
- pthread_mutex_t overlayLock;
- pthread_cond_t overlayPost;
-#endif
- pthread_mutex_t bufferPostLock;
- pthread_cond_t bufferPostCond;
- bool bufferPostDone;
-#endif
+ BUFFER_TYPE_UI = 0,
+ BUFFER_TYPE_VIDEO
};
/*****************************************************************************/
View
57 libhwcomposer/Android.mk
@@ -1,53 +1,6 @@
-LOCAL_PATH := $(call my-dir)
-
-# HAL module implemenation, not prelinked and stored in
-# hw/<OVERLAY_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 libutils liboverlay
-LOCAL_SHARED_LIBRARIES += libgenlock libQcomUI libmemalloc
-ifeq ($(TARGET_BOARD_PLATFORM),copper)
-LOCAL_SHARED_LIBRARIES += liboverlay2
+ifeq ($(call is-board-platform-in-list,copper),true)
+ hwc-hal := badger
+else
+ hwc-hal := a-family
endif
-
-LOCAL_SRC_FILES := \
- hwcomposer.cpp \
- external_display_only.h
-
-LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
-LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).hwcomposer\" -DDEBUG_CALC_FPS
-
-LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
-ifeq ($(TARGET_BOARD_PLATFORM),copper)
-LOCAL_C_INCLUDES += hardware/qcom/display/badger/liboverlay2
-LOCAL_C_INCLUDES += hardware/qcom/display/badger/liboverlay2/src
-endif
-LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay
-LOCAL_C_INCLUDES += hardware/qcom/display/libcopybit
-LOCAL_C_INCLUDES += hardware/qcom/display/libgenlock
-LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui
-LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-
-LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-ifeq ($(TARGET_HAVE_HDMI_OUT),true)
-LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
-endif
-ifeq ($(TARGET_USES_OVERLAY),true)
-LOCAL_CFLAGS += -DUSE_OVERLAY
-ifeq ($(TARGET_BOARD_PLATFORM),copper)
-LOCAL_CFLAGS += -DUSE_OVERLAY2
-endif
-endif
-ifeq ($(TARGET_HAVE_BYPASS),true)
-LOCAL_CFLAGS += -DCOMPOSITION_BYPASS
-endif
-ifeq ($(TARGET_USE_HDMI_AS_PRIMARY),true)
-LOCAL_CFLAGS += -DHDMI_AS_PRIMARY
-endif
-ifeq ($(TARGET_USES_POST_PROCESSING),true)
-LOCAL_CFLAGS += -DUSES_POST_PROCESSING
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/pp/inc
-endif
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_SHARED_LIBRARY)
+include $(call all-named-subdir-makefiles,$(hwc-hal))
View
41 libhwcomposer/a-family/Android.mk
@@ -0,0 +1,41 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_COPY_HEADERS_TO := qcom/display
+LOCAL_COPY_HEADERS := external_display_only.h
+include $(BUILD_COPY_HEADERS)
+# HAL module implemenation, not prelinked and stored in
+# hw/<OVERLAY_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 libutils liboverlay
+LOCAL_SHARED_LIBRARIES += libgenlock libQcomUI libmemalloc
+
+LOCAL_SRC_FILES := hwcomposer.cpp external_display_only.h
+
+LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
+LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).hwcomposer\" -DDEBUG_CALC_FPS
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qcom/display
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+ifeq ($(TARGET_HAVE_HDMI_OUT),true)
+LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
+endif
+ifeq ($(TARGET_USES_OVERLAY),true)
+LOCAL_CFLAGS += -DUSE_OVERLAY
+endif
+ifeq ($(TARGET_HAVE_BYPASS),true)
+LOCAL_CFLAGS += -DCOMPOSITION_BYPASS
+endif
+ifeq ($(TARGET_USE_HDMI_AS_PRIMARY),true)
+LOCAL_CFLAGS += -DHDMI_AS_PRIMARY
+endif
+ifeq ($(TARGET_USES_POST_PROCESSING),true)
+LOCAL_CFLAGS += -DUSES_POST_PROCESSING
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/pp/inc
+endif
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_SHARED_LIBRARY)
View
0  libhwcomposer/external_display_only.h → libhwcomposer/a-family/external_display_only.h
File renamed without changes
View
1  libhwcomposer/hwcomposer.cpp → libhwcomposer/a-family/hwcomposer.cpp
@@ -29,6 +29,7 @@
#include <cutils/properties.h>
#include <gralloc_priv.h>
+#include <fb_priv.h>
#include <hardware/hwcomposer.h>
#include <overlayLib.h>
#include <overlayLibUI.h>
View
22 libhwcomposer/badger/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH := $(call my-dir)
+
+# HAL module implemenation, not prelinked and stored in
+# hw/<OVERLAY_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 libutils liboverlay
+LOCAL_SHARED_LIBRARIES += libgenlock libQcomUI libmemalloc
+LOCAL_SRC_FILES := hwcomposer.cpp
+LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
+LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).hwcomposer\" -DDEBUG_CALC_FPS
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qcom/display
+LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay/badger/src
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+
+#XXX Temporary include for compiling
+LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay/a-family
+
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_SHARED_LIBRARY)
View
2,196 libhwcomposer/badger/hwcomposer.cpp
@@ -0,0 +1,2196 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <hardware/hardware.h>
+
+#include <fcntl.h>
+#include <errno.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h>
+
+#include <gralloc_priv.h>
+#include <fb_priv.h>
+#include <hardware/hwcomposer.h>
+#include <overlayLib.h>
+#include <overlayLibUI.h>
+#include <copybit.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <ui/android_native_buffer.h>
+#include <genlock.h>
+#include <qcom_ui.h>
+#include <gr.h>
+#include <utils/profiler.h>
+#include <utils/IdleTimer.h>
+
+#include <overlayMgr.h>
+#include <overlayMgrSingleton.h>
+#include <overlay.h>
+namespace ovutils = overlay2::utils;
+
+/*****************************************************************************/
+#define ALIGN(x, align) (((x) + ((align)-1)) & ~((align)-1))
+#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
+#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
+
+#define DEBUG_HWC 0
+
+#ifdef COMPOSITION_BYPASS
+#define MAX_BYPASS_LAYERS 3
+#define BYPASS_DEBUG 0
+#define BYPASS_INDEX_OFFSET 4
+#define DEFAULT_IDLE_TIME 2000
+
+enum BypassState {
+ BYPASS_ON,
+ BYPASS_OFF,
+ BYPASS_OFF_PENDING,
+};
+
+enum BypassBufferLockState {
+ BYPASS_BUFFER_UNLOCKED,
+ BYPASS_BUFFER_LOCKED,
+};
+#endif
+
+enum HWCLayerType{
+ HWC_SINGLE_VIDEO = 0x1,
+ HWC_ORIG_RESOLUTION = 0x2,
+ HWC_S3D_LAYER = 0x4,
+ HWC_STOP_UI_MIRRORING_MASK = 0xF
+};
+
+enum eHWCOverlayStatus {
+ HWC_OVERLAY_OPEN,
+ HWC_OVERLAY_PREPARE_TO_CLOSE,
+ HWC_OVERLAY_CLOSED
+};
+
+struct hwc_context_t {
+ hwc_composer_device_t device;
+ /* our private state goes below here */
+ overlay2::OverlayMgr* mOverlayLibObject;
+ native_handle_t *previousOverlayHandle;
+ native_handle_t *currentOverlayHandle;
+ int yuvBufferCount;
+ int numLayersNotUpdating;
+#ifdef COMPOSITION_BYPASS
+ native_handle_t* previousBypassHandle[MAX_BYPASS_LAYERS];
+ BypassBufferLockState bypassBufferLockState[MAX_BYPASS_LAYERS];
+ int layerindex[MAX_BYPASS_LAYERS];
+ int nPipesUsed;
+ BypassState bypassState;
+ IdleTimer idleTimer;
+ bool idleTimeOut;
+#endif
+ external_display_type mHDMIEnabled; // Type of external display
+ bool pendingHDMI;
+ int previousLayerCount;
+ eHWCOverlayStatus hwcOverlayStatus;
+ int swapInterval;
+};
+
+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
+};
+
+
+struct private_hwc_module_t {
+ hwc_module_t base;
+ copybit_device_t *copybitEngine;
+ framebuffer_device_t *fbDevice;
+ int compositionType;
+ bool isBypassEnabled; //from build.prop ro.sf.compbypass.enable
+};
+
+struct private_hwc_module_t HAL_MODULE_INFO_SYM = {
+ base: {
+ common: {
+ tag: HARDWARE_MODULE_TAG,
+ version_major: 1,
+ version_minor: 0,
+ id: HWC_HARDWARE_MODULE_ID,
+ name: "Hardware Composer Module",
+ author: "The Android Open Source Project",
+ methods: &hwc_module_methods,
+ }
+ },
+ copybitEngine: NULL,
+ fbDevice: NULL,
+ compositionType: 0,
+ isBypassEnabled: false,
+};
+
+//Only at this point would the compiler know all storage class sizes.
+//The header has hooks which need to know those beforehand.
+#include "../a-family/external_display_only.h"
+
+/*****************************************************************************/
+
+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 & FINAL_TRANSFORM_MASK, 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 inline int min(const int& a, const int& b) {
+ return (a < b) ? a : b;
+}
+
+static inline int max(const int& a, const int& b) {
+ return (a > b) ? a : b;
+}
+
+/* Determine overlay state based on decoded video info */
+static ovutils::eOverlayState getOverlayState(hwc_context_t* ctx,
+ uint32_t bypassLayer,
+ uint32_t format)
+{
+ ovutils::eOverlayState state = ovutils::OV_CLOSED;
+
+ // Sanity check
+ if (!ctx) {
+ LOGE("%s: NULL ctx", __FUNCTION__);
+ return state;
+ }
+
+ overlay2::Overlay& ov = ctx->mOverlayLibObject->ov();
+ state = ov.getState();
+
+ // If there are any bypassLayers, state is based on number of layers
+ if ((bypassLayer > 0) && (ctx->mHDMIEnabled == EXT_TYPE_NONE)) {
+ if (bypassLayer == 1) {
+ state = ovutils::OV_BYPASS_1_LAYER;
+ } else if (bypassLayer == 2) {
+ state = ovutils::OV_BYPASS_2_LAYER;
+ } else if (bypassLayer == 3) {
+ state = ovutils::OV_BYPASS_3_LAYER;
+ }
+ return state;
+ }
+
+ // RGB is ambiguous for determining overlay state
+ if (ovutils::isRgb(ovutils::getMdpFormat(format))) {
+ return state;
+ }
+
+ // Content type is either 2D or 3D
+ uint32_t fmt3D = ovutils::getS3DFormat(format);
+
+ // Determine state based on the external display, content type, and hw type
+ if (ctx->mHDMIEnabled == EXT_TYPE_HDMI) {
+ // External display is HDMI
+ if (fmt3D) {
+ // Content type is 3D
+ if (ovutils::is3DTV()) {
+ // TV panel type is 3D
+ state = ovutils::OV_3D_VIDEO_ON_3D_TV;
+ } else {
+ // TV panel type is 2D
+ state = ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV;
+ }
+ } else {
+ // Content type is 2D
+ if (ovutils::FrameBufferInfo::getInstance()->supportTrueMirroring()) {
+ // True UI mirroring is supported
+ state = ovutils::OV_2D_TRUE_UI_MIRROR;
+ } else {
+ // True UI mirroring is not supported
+ state = ovutils::OV_2D_VIDEO_ON_PANEL_TV;
+ }
+ }
+ } else if (ctx->mHDMIEnabled == EXT_TYPE_WIFI) {
+ // External display is Wifi (currently unsupported)
+ LOGE("%s: WIFI external display is unsupported", __FUNCTION__);
+ return state;
+ } else {
+ // No external display (primary panel only)
+ if (fmt3D) {
+ // Content type is 3D
+ if (ovutils::usePanel3D()) {
+ // Primary panel type is 3D
+ state = ovutils::OV_3D_VIDEO_ON_3D_PANEL;
+ } else {
+ // Primary panel type is 2D
+ state = ovutils::OV_3D_VIDEO_ON_2D_PANEL;
+ }
+ } else {
+ // Content type is 2D
+ state = ovutils::OV_2D_VIDEO_ON_PANEL;
+ }
+ }
+
+ return state;
+}
+
+/* Set overlay state */
+static void setOverlayState(hwc_context_t* ctx, ovutils::eOverlayState state)
+{
+ // Sanity check
+ if (!ctx) {
+ LOGE("%s: NULL ctx", __FUNCTION__);
+ return;
+ }
+
+ private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
+ ctx->device.common.module);
+ if (!hwcModule) {
+ LOGE("%s: NULL hwcModule", __FUNCTION__);
+ return;
+ }
+
+ framebuffer_device_t *fbDev = hwcModule->fbDevice;
+ if (!fbDev) {
+ LOGE("%s: NULL fbDev", __FUNCTION__);
+ return;
+ }
+
+ overlay2::OverlayMgr *ovMgr = ctx->mOverlayLibObject;
+ if (!ovMgr) {
+ LOGE("%s: NULL ovMgr", __FUNCTION__);
+ return;
+ }
+
+ // Using perform ensures a lock on overlay is obtained before changing state
+ fbDev->perform(fbDev, EVENT_OVERLAY_STATE_CHANGE, OVERLAY_STATE_CHANGE_START);
+ ovMgr->setState(state);
+ fbDev->perform(fbDev, EVENT_OVERLAY_STATE_CHANGE, OVERLAY_STATE_CHANGE_END);
+}
+
+#ifdef COMPOSITION_BYPASS
+static void timeout_handler(void *udata) {
+ struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
+
+ if(!ctx) {
+ LOGE("%s: received empty data in timer callback", __FUNCTION__);
+ return;
+ }
+
+ hwc_procs* proc = (hwc_procs*)ctx->device.reserved_proc[0];
+
+ if(!proc) {
+ LOGE("%s: HWC proc not registered", __FUNCTION__);
+ return;
+ }
+ /* Trigger SF to redraw the current frame */
+ proc->invalidate(proc);
+ ctx->idleTimeOut = true;
+}
+
+void setLayerbypassIndex(hwc_layer_t* layer, const int bypass_index)
+{
+ layer->flags &= ~HWC_BYPASS_INDEX_MASK;
+ layer->flags |= bypass_index << BYPASS_INDEX_OFFSET;
+}
+
+int getLayerbypassIndex(hwc_layer_t* layer)
+{
+ int byp_index = -1;
+
+ if(layer->flags & HWC_COMP_BYPASS) {
+ byp_index = ((layer->flags & HWC_BYPASS_INDEX_MASK) >> BYPASS_INDEX_OFFSET);
+ byp_index = (byp_index < MAX_BYPASS_LAYERS ? byp_index : -1 );
+ }
+ return byp_index;
+}
+
+void unlockPreviousBypassBuffers(hwc_context_t* ctx) {
+ // Unlock the previous bypass buffers. We can blindly unlock the buffers
+ // here, because buffers will be in this list only if the lock was
+ // successfully acquired.
+ for(int i = 0; i < MAX_BYPASS_LAYERS; i++) {
+ private_handle_t *hnd = (private_handle_t*) ctx->previousBypassHandle[i];
+ if (!hnd)
+ continue;
+ // Validate the handle to make sure it hasn't been deallocated.
+ if (private_handle_t::validate(hnd)) {
+ LOGE("%s: Unregistering invalid gralloc handle %p.", __FUNCTION__, hnd);
+ ctx->previousBypassHandle[i] = NULL;
+ continue;
+ }
+ // Check if the handle was locked previously
+ if (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags) {
+ if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
+ LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+ } else {
+ ctx->previousBypassHandle[i] = NULL;
+ // Reset the lock flag
+ hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
+ }
+ }
+ }
+}
+
+void print_info(hwc_layer_t* layer)
+{
+ hwc_rect_t sourceCrop = layer->sourceCrop;
+ hwc_rect_t displayFrame = layer->displayFrame;
+
+ int s_l = sourceCrop.left;
+ int s_t = sourceCrop.top;
+ int s_r = sourceCrop.right;
+ int s_b = sourceCrop.bottom;
+
+ int d_l = displayFrame.left;
+ int d_t = displayFrame.top;
+ int d_r = displayFrame.right;
+ int d_b = displayFrame.bottom;
+
+ LOGE_IF(BYPASS_DEBUG, "src:[%d,%d,%d,%d] (%d x %d) dst:[%d,%d,%d,%d] (%d x %d)",
+ s_l, s_t, s_r, s_b, (s_r - s_l), (s_b - s_t),
+ d_l, d_t, d_r, d_b, (d_r - d_l), (d_b - d_t));
+}
+
+//Crops source buffer against destination and FB boundaries
+void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst, int hw_w, int hw_h) {
+
+ int& crop_x = crop.left;
+ int& crop_y = crop.top;
+ int& crop_r = crop.right;
+ int& crop_b = crop.bottom;
+ int crop_w = crop.right - crop.left;
+ int crop_h = crop.bottom - crop.top;
+
+ int& dst_x = dst.left;
+ int& dst_y = dst.top;
+ int& dst_r = dst.right;
+ int& dst_b = dst.bottom;
+ int dst_w = dst.right - dst.left;
+ int dst_h = dst.bottom - dst.top;
+
+ if(dst_x < 0) {
+ float scale_x = crop_w * 1.0f / dst_w;
+ float diff_factor = (scale_x * abs(dst_x));
+ crop_x = crop_x + (int)diff_factor;
+ crop_w = crop_r - crop_x;
+
+ dst_x = 0;
+ dst_w = dst_r - dst_x;;
+ }
+ if(dst_r > hw_w) {
+ float scale_x = crop_w * 1.0f / dst_w;
+ float diff_factor = scale_x * (dst_r - hw_w);
+ crop_r = crop_r - diff_factor;
+ crop_w = crop_r - crop_x;
+
+ dst_r = hw_w;
+ dst_w = dst_r - dst_x;
+ }
+ if(dst_y < 0) {
+ float scale_y = crop_h * 1.0f / dst_h;
+ float diff_factor = scale_y * abs(dst_y);
+ crop_y = crop_y + diff_factor;
+ crop_h = crop_b - crop_y;
+
+ dst_y = 0;
+ dst_h = dst_b - dst_y;
+ }
+ if(dst_b > hw_h) {
+ float scale_y = crop_h * 1.0f / dst_h;
+ float diff_factor = scale_y * (dst_b - hw_h);
+ crop_b = crop_b - diff_factor;
+ crop_h = crop_b - crop_y;
+
+ dst_b = hw_h;
+ dst_h = dst_b - dst_y;
+ }
+
+ LOGE_IF(BYPASS_DEBUG,"crop: [%d,%d,%d,%d] dst:[%d,%d,%d,%d]",
+ crop_x, crop_y, crop_w, crop_h,dst_x, dst_y, dst_w, dst_h);
+}
+
+/*
+ * Configures pipe(s) for composition bypass
+ */
+static int prepareBypass(hwc_context_t *ctx, hwc_layer_t *layer,
+ int nPipeIndex, int vsync_wait, int isFG) {
+
+ if (ctx && layer) {
+
+ private_hwc_module_t* hwcModule = reinterpret_cast<
+ private_hwc_module_t*>(ctx->device.common.module);
+ if (!hwcModule) {
+ LOGE("%s: NULL Module", __FUNCTION__);
+ return -1;
+ }
+
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if(!hnd) {
+ LOGE("%s: layer handle is NULL", __FUNCTION__);
+ return -1;
+ }
+
+ int hw_w = hwcModule->fbDevice->width;
+ int hw_h = hwcModule->fbDevice->height;
+
+ hwc_rect_t sourceCrop = layer->sourceCrop;
+ hwc_rect_t displayFrame = layer->displayFrame;
+
+ hwc_rect_t crop = sourceCrop;
+ int crop_w = crop.right - crop.left;
+ int crop_h = crop.bottom - crop.top;
+
+ hwc_rect_t dst = displayFrame;
+ int dst_w = dst.right - dst.left;
+ int dst_h = dst.bottom - dst.top;
+
+ if(hnd != NULL && (hnd->flags & private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM )) {
+ LOGE("%s: Unable to setup bypass due to non-pmem memory",__FUNCTION__);
+ return -1;
+ }
+
+ if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {