Merge "Merge Android Pie into master"
diff --git a/Android.mk b/Android.mk
index e6670f3..6ff7ecf 100644
--- a/Android.mk
+++ b/Android.mk
@@ -8,6 +8,12 @@
include $(call all-named-subdir-makefiles,msm8226)
else ifneq ($(filter msm8992,$(TARGET_BOARD_PLATFORM)),)
include $(call all-named-subdir-makefiles,msm8994)
+else ifneq ($(filter msm8909,$(TARGET_BOARD_PLATFORM)),)
+ ifeq ($(TARGET_SUPPORTS_QCOM_3100),true)
+ include $(call all-named-subdir-makefiles,msm8909w_3100)
+ else
+ include $(call all-named-subdir-makefiles,msm8909)
+ endif
else ifneq ($(wildcard $(LOCAL_PATH)/$(TARGET_BOARD_PLATFORM)),)
include $(call all-named-subdir-makefiles,$(TARGET_BOARD_PLATFORM))
endif
diff --git a/msm8909/.clang-format b/msm8909/.clang-format
new file mode 100644
index 0000000..9082c40
--- /dev/null
+++ b/msm8909/.clang-format
@@ -0,0 +1,13 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortBlocksOnASingleLine: false
+ColumnLimit: 100
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+DerivePointerAlignment: false
+PointerAlignment: Right
+#ReflowComments: false
diff --git a/msm8909/.gitignore b/msm8909/.gitignore
new file mode 100644
index 0000000..ad71dd6
--- /dev/null
+++ b/msm8909/.gitignore
@@ -0,0 +1,4 @@
+CMakeLists.txt
+.idea/
+.editorconfig
+.clang-complete
diff --git a/msm8909/Android.bp b/msm8909/Android.bp
new file mode 100644
index 0000000..ea40594
--- /dev/null
+++ b/msm8909/Android.bp
@@ -0,0 +1,42 @@
+soong_namespace {
+}
+
+cc_defaults {
+ name: "display_defaults",
+ cflags: [
+ "-Wno-missing-field-initializers",
+ "-Wconversion",
+ "-Wall",
+ "-Werror",
+ "-std=c++14",
+ ],
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ "libutils",
+ ],
+ header_libs: ["display_headers"],
+ clang: true,
+}
+
+cc_library_headers {
+ name: "display_headers",
+ vendor_available: true,
+ export_include_dirs: [
+ "include",
+ "libcopybit",
+ "libdrmutils",
+ "libqdutils",
+ "libqservice",
+ "gpu_tonemapper",
+ "sdm/include",
+ "gralloc",
+ ],
+ header_libs: ["libhardware_headers"],
+ export_header_lib_headers: ["libhardware_headers"],
+}
+
+subdirs = [
+ "libqservice",
+ "libqdutils",
+]
diff --git a/msm8909/Android.mk b/msm8909/Android.mk
index d8b168d..f354caf 100644
--- a/msm8909/Android.mk
+++ b/msm8909/Android.mk
@@ -1,6 +1,13 @@
-display-hals := libgralloc libgenlock libcopybit liblight
-display-hals += libhwcomposer liboverlay libqdutils libhdmi libqservice
-display-hals += libmemtrack
+sdm-libs := sdm/libs
+display-hals := include $(sdm-libs)/utils $(sdm-libs)/core
+
+ifneq ($(TARGET_IS_HEADLESS), true)
+ display-hals += libcopybit liblight libmemtrack hdmi_cec \
+ $(sdm-libs)/hwc $(sdm-libs)/hwc2 gpu_tonemapper libdrmutils libdisplayconfig
+endif
+
+display-hals += gralloc
+
ifeq ($(call is-vendor-board-platform,QCOM),true)
include $(call all-named-subdir-makefiles,$(display-hals))
else
diff --git a/msm8909/common.mk b/msm8909/common.mk
index 2465cc8..f8fe936 100644
--- a/msm8909/common.mk
+++ b/msm8909/common.mk
@@ -1,69 +1,81 @@
#Common headers
-common_includes := $(LOCAL_PATH)/../libgralloc
-common_includes += $(LOCAL_PATH)/../liboverlay
-common_includes += $(LOCAL_PATH)/../libcopybit
-common_includes += $(LOCAL_PATH)/../libqdutils
-common_includes += $(LOCAL_PATH)/../libhwcomposer
-common_includes += $(LOCAL_PATH)/../libhdmi
-common_includes += $(LOCAL_PATH)/../libqservice
+display_top := $(call my-dir)
+display_config_version := $(shell \
+ if [ -d "$(TOP)/vendor/qcom/codeaurora/interfaces/vendor/display/config/1.1" ];\
+ then echo DISPLAY_CONFIG_1_1; fi)
-ifeq ($(TARGET_USES_POST_PROCESSING),true)
- common_flags += -DUSES_POST_PROCESSING
- common_includes += $(TARGET_OUT_HEADERS)/pp/inc
+#Common C flags
+common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
+common_flags += -Wconversion -Wall -Werror -std=c++14
+ifeq ($(TARGET_IS_HEADLESS), true)
+ common_flags += -DTARGET_HEADLESS
+ LOCAL_CLANG := false
+endif
+
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_1)
+ common_flags += -DDISPLAY_CONFIG_1_1
+endif
+
+ifeq ($(TARGET_USES_COLOR_METADATA), true)
+ common_flags += -DUSE_COLOR_METADATA
+endif
+
+ifeq ($(TARGET_USES_QCOM_BSP),true)
+ common_flags += -DQTI_BSP
+endif
+
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
+ common_flags += -D__ARM_HAVE_NEON
+endif
+
+ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true)
+ common_flags += -DMASTER_SIDE_CP
+endif
+
+use_hwc2 := false
+ifeq ($(TARGET_USES_HWC2), true)
+ use_hwc2 := true
+ common_flags += -DVIDEO_MODE_DEFER_RETIRE_FENCE
+endif
+
+ifeq ($(TARGET_USES_GRALLOC1), true)
+ common_flags += -DUSE_GRALLOC1
+endif
+
+common_includes := system/core/base/include
+CHECK_VERSION_LE = $(shell if [ $(1) -le $(2) ] ; then echo true ; else echo false ; fi)
+PLATFORM_SDK_NOUGAT = 25
+ifeq "REL" "$(PLATFORM_VERSION_CODENAME)"
+ifeq ($(call CHECK_VERSION_LE, $(PLATFORM_SDK_VERSION), $(PLATFORM_SDK_NOUGAT)), true)
+version_flag := -D__NOUGAT__
+
+# These include paths are deprecated post N
+common_includes += $(display_top)/libqdutils
+common_includes += $(display_top)/libqservice
+common_includes += $(display_top)/gpu_tonemapper
+ifneq ($(TARGET_IS_HEADLESS), true)
+ common_includes += $(display_top)/libcopybit
+endif
+
+common_includes += $(display_top)/include
+common_includes += $(display_top)/sdm/include
+common_flags += -isystem $(TARGET_OUT_HEADERS)/qcom/display
+endif
endif
common_header_export_path := qcom/display
#Common libraries external to display HAL
common_libs := liblog libutils libcutils libhardware
-
-#Common C flags
-common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
-common_flags += -Wconversion -Wall -Werror -Wno-sign-conversion
-
-ifeq ($(ARCH_ARM_HAVE_NEON),true)
- common_flags += -D__ARM_HAVE_NEON
-endif
-
-ifeq ($(call is-board-platform-in-list, $(MSM_VIDC_TARGET_LIST)), true)
- common_flags += -DVENUS_COLOR_FORMAT
-endif
-
-ifeq ($(call is-board-platform-in-list, msm8974 msm8226 msm8610 apq8084 \
- mpq8092 msm_bronze msm8916 msm8994), true)
- common_flags += -DMDSS_TARGET
-endif
-ifeq ($(call is-board-platform-in-list, msm8909), true)
- common_flags += -DVENUS_COLOR_FORMAT
- common_flags += -DMDSS_TARGET
-endif
-
-ifeq ($(DISPLAY_DEBUG_SWAPINTERVAL),true)
- common_flags += -DDEBUG_SWAPINTERVAL
-endif
-
-common_flags += -D__STDC_FORMAT_MACROS
-
common_deps :=
kernel_includes :=
-# Executed only on QCOM BSPs
-ifeq ($(TARGET_USES_QCOM_BSP),true)
-# Enable QCOM Display features
- common_flags += -DQTI_BSP
- common_includes += $(BOARD_OPENSOURCE_DIR)/display-frameworks/include
-endif
-ifneq ($(call is-platform-sdk-version-at-least,18),true)
- common_flags += -DANDROID_JELLYBEAN_MR1=1
-endif
-ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
# This check is to pick the kernel headers from the right location.
# If the macro above is defined, we make the assumption that we have the kernel
# available in the build tree.
# If the macro is not present, the headers are picked from hardware/qcom/msmXXXX
# failing which, they are picked from bionic.
- common_deps += $(BOARD_KERNEL_HEADER_DEPENDENCIES)
- kernel_includes += $(BOARD_KERNEL_HEADER_DIR)
+ common_deps += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+ kernel_includes += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
endif
-
-common_clang_flags := true
diff --git a/sdm845/gpu_tonemapper/Android.mk b/msm8909/gpu_tonemapper/Android.mk
similarity index 92%
copy from sdm845/gpu_tonemapper/Android.mk
copy to msm8909/gpu_tonemapper/Android.mk
index 769d0ab..77ecc4a 100644
--- a/sdm845/gpu_tonemapper/Android.mk
+++ b/msm8909/gpu_tonemapper/Android.mk
@@ -12,7 +12,7 @@
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(TARGET_OUT_HEADERS)/qcom/display/
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_SHARED_LIBRARIES := libEGL libGLESv2 libui libutils liblog
+LOCAL_SHARED_LIBRARIES := libEGL libGLESv2 libGLESv3 libui libutils liblog
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
LOCAL_CFLAGS := $(version_flag) -Wno-missing-field-initializers -Wall \
diff --git a/sdm845/gpu_tonemapper/EGLImageBuffer.cpp b/msm8909/gpu_tonemapper/EGLImageBuffer.cpp
similarity index 100%
rename from sdm845/gpu_tonemapper/EGLImageBuffer.cpp
rename to msm8909/gpu_tonemapper/EGLImageBuffer.cpp
diff --git a/sdm845/gpu_tonemapper/EGLImageBuffer.h b/msm8909/gpu_tonemapper/EGLImageBuffer.h
similarity index 100%
rename from sdm845/gpu_tonemapper/EGLImageBuffer.h
rename to msm8909/gpu_tonemapper/EGLImageBuffer.h
diff --git a/sdm845/gpu_tonemapper/EGLImageWrapper.cpp b/msm8909/gpu_tonemapper/EGLImageWrapper.cpp
similarity index 100%
rename from sdm845/gpu_tonemapper/EGLImageWrapper.cpp
rename to msm8909/gpu_tonemapper/EGLImageWrapper.cpp
diff --git a/sdm845/gpu_tonemapper/EGLImageWrapper.h b/msm8909/gpu_tonemapper/EGLImageWrapper.h
similarity index 100%
rename from sdm845/gpu_tonemapper/EGLImageWrapper.h
rename to msm8909/gpu_tonemapper/EGLImageWrapper.h
diff --git a/msm8909/gpu_tonemapper/TonemapFactory.cpp b/msm8909/gpu_tonemapper/TonemapFactory.cpp
new file mode 100644
index 0000000..db4b8be
--- /dev/null
+++ b/msm8909/gpu_tonemapper/TonemapFactory.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright 2015 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 "TonemapFactory.h"
+#include <log/log.h>
+#include "Tonemapper.h"
+#include "engine.h"
+
+//----------------------------------------------------------------------------------------------------------------------------------------------------------
+Tonemapper *TonemapperFactory_GetInstance(int type, void *colorMap, int colorMapSize,
+ void *lutXform, int lutXformSize, bool isSecure)
+//----------------------------------------------------------------------------------------------------------------------------------------------------------
+{
+ // build the tonemapper
+ Tonemapper *tonemapper = Tonemapper::build(type, colorMap, colorMapSize, lutXform, lutXformSize, isSecure);
+
+ return tonemapper;
+}
diff --git a/sdm845/gpu_tonemapper/TonemapFactory.h b/msm8909/gpu_tonemapper/TonemapFactory.h
similarity index 100%
rename from sdm845/gpu_tonemapper/TonemapFactory.h
rename to msm8909/gpu_tonemapper/TonemapFactory.h
diff --git a/sdm845/gpu_tonemapper/Tonemapper.cpp b/msm8909/gpu_tonemapper/Tonemapper.cpp
similarity index 91%
rename from sdm845/gpu_tonemapper/Tonemapper.cpp
rename to msm8909/gpu_tonemapper/Tonemapper.cpp
index 981863d..811e091 100644
--- a/sdm845/gpu_tonemapper/Tonemapper.cpp
+++ b/msm8909/gpu_tonemapper/Tonemapper.cpp
@@ -45,7 +45,6 @@
Tonemapper::~Tonemapper()
//-----------------------------------------------------------------------------
{
- void* caller_context = engine_backup();
engine_bind(engineContext);
engine_deleteInputBuffer(tonemapTexture);
engine_deleteInputBuffer(lutXformTexture);
@@ -58,9 +57,6 @@
}
engine_shutdown(engineContext);
- // restore the caller context
- engine_bind(caller_context);
- engine_free_backup(caller_context);
}
//-----------------------------------------------------------------------------
@@ -78,7 +74,6 @@
tonemapper->engineContext = engine_initialize(isSecure);
- void* caller_context = engine_backup();
engine_bind(tonemapper->engineContext);
// load the 3d lut
@@ -117,10 +112,6 @@
tonemapper->programID =
engine_loadProgram(1, &fullscreen_vertex_shader, fragmentShaderCount, fragmentShaders);
- // restore the caller context
- engine_bind(caller_context);
- engine_free_backup(caller_context);
-
return tonemapper;
}
@@ -128,7 +119,6 @@
int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd)
//-----------------------------------------------------------------------------
{
- void* caller_context = engine_backup();
// make current
engine_bind(engineContext);
@@ -159,10 +149,5 @@
// perform
int fenceFD = engine_blit(srcFenceFd);
- // restore the caller context
- engine_bind(caller_context);
- engine_free_backup(caller_context);
-
-
return fenceFD;
}
diff --git a/sdm845/gpu_tonemapper/Tonemapper.h b/msm8909/gpu_tonemapper/Tonemapper.h
similarity index 100%
rename from sdm845/gpu_tonemapper/Tonemapper.h
rename to msm8909/gpu_tonemapper/Tonemapper.h
diff --git a/sdm845/gpu_tonemapper/engine.h b/msm8909/gpu_tonemapper/engine.h
similarity index 96%
rename from sdm845/gpu_tonemapper/engine.h
rename to msm8909/gpu_tonemapper/engine.h
index e0bf2aa..8fb9452 100644
--- a/sdm845/gpu_tonemapper/engine.h
+++ b/msm8909/gpu_tonemapper/engine.h
@@ -22,8 +22,6 @@
void* engine_initialize(bool isSecure);
void engine_bind(void*);
-void* engine_backup();
-void engine_free_backup(void*);
void engine_shutdown(void*);
unsigned int engine_loadProgram(int, const char **, int, const char **);
diff --git a/sdm845/gpu_tonemapper/forward_tonemap.inl b/msm8909/gpu_tonemapper/forward_tonemap.inl
similarity index 100%
rename from sdm845/gpu_tonemapper/forward_tonemap.inl
rename to msm8909/gpu_tonemapper/forward_tonemap.inl
diff --git a/sdm845/gpu_tonemapper/fullscreen_vertex_shader.inl b/msm8909/gpu_tonemapper/fullscreen_vertex_shader.inl
similarity index 100%
rename from sdm845/gpu_tonemapper/fullscreen_vertex_shader.inl
rename to msm8909/gpu_tonemapper/fullscreen_vertex_shader.inl
diff --git a/sdm845/gpu_tonemapper/glengine.cpp b/msm8909/gpu_tonemapper/glengine.cpp
similarity index 95%
copy from sdm845/gpu_tonemapper/glengine.cpp
copy to msm8909/gpu_tonemapper/glengine.cpp
index 6cfe15f..35e1932 100644
--- a/sdm845/gpu_tonemapper/glengine.cpp
+++ b/msm8909/gpu_tonemapper/glengine.cpp
@@ -18,7 +18,7 @@
*/
#include "glengine.h"
-#include <utils/Log.h>
+#include <log/log.h>
#include "engine.h"
void checkGlError(const char *, int);
@@ -47,27 +47,6 @@
}
//-----------------------------------------------------------------------------
-// store the current context(caller)
-void* engine_backup()
-{
- EngineContext* callerContext = new EngineContext();
- // store the previous display/context
- callerContext->eglDisplay = eglGetCurrentDisplay();
- callerContext->eglContext = eglGetCurrentContext();
- callerContext->eglSurface = eglGetCurrentSurface(EGL_DRAW);
-
- return (void*)callerContext;
-}
-//-----------------------------------------------------------------------------
-// frees the backed up caller context
-void engine_free_backup(void* context)
-{
- EngineContext* callerContext = (EngineContext*)(context);
-
- delete callerContext;
-}
-
-//-----------------------------------------------------------------------------
// initialize GL
//
void* engine_initialize(bool isSecure)
diff --git a/sdm845/gpu_tonemapper/glengine.h b/msm8909/gpu_tonemapper/glengine.h
similarity index 100%
rename from sdm845/gpu_tonemapper/glengine.h
rename to msm8909/gpu_tonemapper/glengine.h
diff --git a/sdm845/gpu_tonemapper/rgba_inverse_tonemap.inl b/msm8909/gpu_tonemapper/rgba_inverse_tonemap.inl
similarity index 100%
rename from sdm845/gpu_tonemapper/rgba_inverse_tonemap.inl
rename to msm8909/gpu_tonemapper/rgba_inverse_tonemap.inl
diff --git a/sdm845/libgralloc1/Android.mk b/msm8909/gralloc/Android.mk
similarity index 100%
copy from sdm845/libgralloc1/Android.mk
copy to msm8909/gralloc/Android.mk
diff --git a/sdm845/libgralloc1/gr_adreno_info.cpp b/msm8909/gralloc/gr_adreno_info.cpp
similarity index 85%
copy from sdm845/libgralloc1/gr_adreno_info.cpp
copy to msm8909/gralloc/gr_adreno_info.cpp
index ecac238..c681daa 100644
--- a/sdm845/libgralloc1/gr_adreno_info.cpp
+++ b/msm8909/gralloc/gr_adreno_info.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -27,7 +27,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/properties.h>
#include <dlfcn.h>
#include <mutex>
@@ -48,22 +48,16 @@
lock_guard<mutex> obj(s_lock);
if (!s_instance) {
s_instance = new AdrenoMemInfo();
- if (!s_instance->Init()) {
- delete s_instance;
- s_instance = nullptr;
- }
}
return s_instance;
}
-bool AdrenoMemInfo::Init() {
+AdrenoMemInfo::AdrenoMemInfo() {
libadreno_utils_ = ::dlopen("libadreno_utils.so", RTLD_NOW);
if (libadreno_utils_) {
*reinterpret_cast<void **>(&LINK_adreno_compute_aligned_width_and_height) =
::dlsym(libadreno_utils_, "compute_aligned_width_and_height");
- *reinterpret_cast<void **>(&LINK_adreno_compute_fmt_aligned_width_and_height) =
- ::dlsym(libadreno_utils_, "compute_fmt_aligned_width_and_height");
*reinterpret_cast<void **>(&LINK_adreno_compute_padding) =
::dlsym(libadreno_utils_, "compute_surface_padding");
*reinterpret_cast<void **>(&LINK_adreno_compute_compressedfmt_aligned_width_and_height) =
@@ -74,25 +68,22 @@
::dlsym(libadreno_utils_, "get_gpu_pixel_alignment");
} else {
ALOGE(" Failed to load libadreno_utils.so");
- return false;
}
// Check if the overriding property debug.gralloc.gfx_ubwc_disable
// that disables UBWC allocations for the graphics stack is set
char property[PROPERTY_VALUE_MAX];
- property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
+ property_get(DISABLE_UBWC_PROP, property, "0");
if (!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
!(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
gfx_ubwc_disable_ = true;
}
- if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+ if ((property_get(MAP_FB_MEMORY_PROP, property, NULL) > 0) &&
(!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
(!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
map_fb_ = true;
}
-
- return true;
}
AdrenoMemInfo::~AdrenoMemInfo() {
@@ -132,15 +123,7 @@
int padding_threshold = 512; // Threshold for padding surfaces.
// the function below computes aligned width and aligned height
// based on linear or macro tile mode selected.
- if (LINK_adreno_compute_fmt_aligned_width_and_height) {
- // We call into adreno_utils only for RGB formats. So plane_id is 0 and
- // num_samples is 1 always. We may have to add uitility function to
- // find out these if there is a need to call this API for YUV formats.
- LINK_adreno_compute_fmt_aligned_width_and_height(
- width, height, 0/*plane_id*/, GetGpuPixelFormat(format), 1/*num_samples*/,
- tile_enabled, raster_mode, padding_threshold,
- reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h));
- } else if (LINK_adreno_compute_aligned_width_and_height) {
+ if (LINK_adreno_compute_aligned_width_and_height) {
LINK_adreno_compute_aligned_width_and_height(
width, height, bpp, tile_enabled, raster_mode, padding_threshold,
reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h));
@@ -152,7 +135,6 @@
} else {
ALOGW(
"%s: Warning!! Symbols compute_surface_padding and "
- "compute_fmt_aligned_width_and_height and "
"compute_aligned_width_and_height not found",
__FUNCTION__);
}
@@ -170,6 +152,8 @@
width, height, format, 0, raster_mode, padding_threshold,
reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h), &bytesPerPixel);
} else {
+ *aligned_w = (unsigned int)ALIGN(width, 32);
+ *aligned_h = (unsigned int)ALIGN(height, 32);
ALOGW("%s: Warning!! compute_compressedfmt_aligned_width_and_height not found", __FUNCTION__);
}
}
@@ -217,6 +201,8 @@
return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
case HAL_PIXEL_FORMAT_ABGR_2101010:
return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ return ADRENO_PIXELFORMAT_R8G8B8;
default:
ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
break;
diff --git a/sdm845/libgralloc1/gr_adreno_info.h b/msm8909/gralloc/gr_adreno_info.h
similarity index 92%
rename from sdm845/libgralloc1/gr_adreno_info.h
rename to msm8909/gralloc/gr_adreno_info.h
index 75ba507..478b527 100644
--- a/sdm845/libgralloc1/gr_adreno_info.h
+++ b/msm8909/gralloc/gr_adreno_info.h
@@ -71,8 +71,6 @@
class AdrenoMemInfo {
public:
- bool Init();
-
/*
* Function to compute aligned width and aligned height based on
* width, height, format and usage flags.
@@ -123,6 +121,7 @@
static AdrenoMemInfo *GetInstance();
private:
+ AdrenoMemInfo();
~AdrenoMemInfo();
// link(s)to adreno surface padding library.
int (*LINK_adreno_compute_padding)(int width, int bpp, int surface_tile_height,
@@ -131,11 +130,6 @@
int tile_mode, int raster_mode,
int padding_threshold, int *aligned_w,
int *aligned_h) = NULL;
- void (*LINK_adreno_compute_fmt_aligned_width_and_height)(int width, int height, int plane_id,
- int format, int num_samples,
- int tile_mode, int raster_mode,
- int padding_threshold, int *aligned_w,
- int *aligned_h) = NULL;
void (*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
int width, int height, int format, int tile_mode, int raster_mode, int padding_threshold,
int *aligned_w, int *aligned_h, int *bpp) = NULL;
diff --git a/msm8909/gralloc/gr_allocator.cpp b/msm8909/gralloc/gr_allocator.cpp
new file mode 100644
index 0000000..330da18
--- /dev/null
+++ b/msm8909/gralloc/gr_allocator.cpp
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <log/log.h>
+#include <algorithm>
+#include <vector>
+
+#include "gr_utils.h"
+#include "gr_allocator.h"
+#include "gralloc_priv.h"
+
+#include "qd_utils.h"
+
+#ifndef ION_FLAG_CP_PIXEL
+#define ION_FLAG_CP_PIXEL 0
+#endif
+
+#ifndef ION_FLAG_ALLOW_NON_CONTIG
+#define ION_FLAG_ALLOW_NON_CONTIG 0
+#endif
+
+#ifndef ION_FLAG_CP_CAMERA_PREVIEW
+#define ION_FLAG_CP_CAMERA_PREVIEW 0
+#endif
+
+#ifdef MASTER_SIDE_CP
+#define CP_HEAP_ID ION_SECURE_HEAP_ID
+#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
+#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
+#define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA)
+#define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW)
+#else // SLAVE_SIDE_CP
+#define CP_HEAP_ID ION_CP_MM_HEAP_ID
+#define SD_HEAP_ID CP_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
+#define ION_SD_FLAGS ION_SECURE
+#define ION_SC_FLAGS ION_SECURE
+#define ION_SC_PREVIEW_FLAGS ION_SECURE
+#endif
+
+using std::vector;
+using std::shared_ptr;
+
+namespace gralloc1 {
+
+static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
+ return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
+ descriptor.GetProducerUsage(), descriptor.GetConsumerUsage());
+}
+
+Allocator::Allocator() : ion_allocator_(NULL) {
+}
+
+bool Allocator::Init() {
+ ion_allocator_ = new IonAlloc();
+ if (!ion_allocator_->Init()) {
+ return false;
+ }
+
+ return true;
+}
+
+Allocator::~Allocator() {
+ if (ion_allocator_) {
+ delete ion_allocator_;
+ }
+}
+
+int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage,
+ gralloc1_consumer_usage_t cons_usage) {
+ int ret;
+ alloc_data->uncached = UseUncached(prod_usage, cons_usage);
+
+ // After this point we should have the right heap set, there is no fallback
+ GetIonHeapInfo(prod_usage, cons_usage, &alloc_data->heap_id, &alloc_data->alloc_type,
+ &alloc_data->flags);
+
+ ret = ion_allocator_->AllocBuffer(alloc_data);
+ if (ret >= 0) {
+ alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION;
+ } else {
+ ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__,
+ alloc_data->heap_id, alloc_data->flags);
+ }
+
+ return ret;
+}
+
+int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
+ if (ion_allocator_) {
+ return ion_allocator_->MapBuffer(base, size, offset, fd);
+ }
+
+ return -EINVAL;
+}
+
+int Allocator::ImportBuffer(int fd) {
+ if (ion_allocator_) {
+ return ion_allocator_->ImportBuffer(fd);
+ }
+ return -EINVAL;
+}
+
+int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd,
+ int handle) {
+ if (ion_allocator_) {
+ return ion_allocator_->FreeBuffer(base, size, offset, fd, handle);
+ }
+
+ return -EINVAL;
+}
+
+int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) {
+ if (ion_allocator_) {
+ return ion_allocator_->CleanBuffer(base, size, offset, handle, op);
+ }
+
+ return -EINVAL;
+}
+
+bool Allocator::CheckForBufferSharing(uint32_t num_descriptors,
+ const vector<shared_ptr<BufferDescriptor>>& descriptors,
+ ssize_t *max_index) {
+ unsigned int cur_heap_id = 0, prev_heap_id = 0;
+ unsigned int cur_alloc_type = 0, prev_alloc_type = 0;
+ unsigned int cur_ion_flags = 0, prev_ion_flags = 0;
+ bool cur_uncached = false, prev_uncached = false;
+ unsigned int alignedw, alignedh;
+ unsigned int max_size = 0;
+
+ *max_index = -1;
+ for (uint32_t i = 0; i < num_descriptors; i++) {
+ // Check Cached vs non-cached and all the ION flags
+ cur_uncached = UseUncached(descriptors[i]->GetProducerUsage(),
+ descriptors[i]->GetConsumerUsage());
+ GetIonHeapInfo(descriptors[i]->GetProducerUsage(), descriptors[i]->GetConsumerUsage(),
+ &cur_heap_id, &cur_alloc_type, &cur_ion_flags);
+
+ if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type ||
+ cur_ion_flags != prev_ion_flags)) {
+ return false;
+ }
+
+ // For same format type, find the descriptor with bigger size
+ GetAlignedWidthAndHeight(GetBufferInfo(*descriptors[i]), &alignedw, &alignedh);
+ unsigned int size = GetSize(GetBufferInfo(*descriptors[i]), alignedw, alignedh);
+ if (max_size < size) {
+ *max_index = INT(i);
+ max_size = size;
+ }
+
+ prev_heap_id = cur_heap_id;
+ prev_uncached = cur_uncached;
+ prev_ion_flags = cur_ion_flags;
+ prev_alloc_type = cur_alloc_type;
+ }
+
+ return true;
+}
+
+int Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
+ gralloc1_consumer_usage_t cons_usage, int format) {
+ int gr_format = format;
+
+ // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
+ // the usage bits, gralloc assigns a format.
+ if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+ format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) {
+ gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+ } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
+ gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; // NV12
+ } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
+ if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
+ // Assumed ZSL if both producer and consumer camera flags set
+ gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
+ } else {
+ gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; // NV21
+ }
+ } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
+ if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
+ } else {
+ gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; // NV12 preview
+ }
+ } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
+ // XXX: If we still haven't set a format, default to RGBA8888
+ gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
+ } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ // If no other usage flags are detected, default the
+ // flexible YUV format to NV21_ZSL
+ gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
+ }
+ }
+
+ return gr_format;
+}
+
+/* The default policy is to return cached buffers unless the client explicity
+ * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
+ * read or written in software. */
+bool Allocator::UseUncached(gralloc1_producer_usage_t prod_usage,
+ gralloc1_consumer_usage_t cons_usage) {
+ if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED) ||
+ (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED)) {
+ return true;
+ }
+
+ // CPU read rarely
+ if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) &&
+ !(prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)) {
+ return true;
+ }
+
+ // CPU write rarely
+ if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) &&
+ !(prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) {
+ return true;
+ }
+
+ if ((prod_usage & GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA) ||
+ (cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER)) {
+ return true;
+ }
+
+ return false;
+}
+
+void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage,
+ gralloc1_consumer_usage_t cons_usage, unsigned int *ion_heap_id,
+ unsigned int *alloc_type, unsigned int *ion_flags) {
+ unsigned int heap_id = 0;
+ unsigned int type = 0;
+ uint32_t flags = 0;
+ if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
+ if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
+ heap_id = ION_HEAP(SD_HEAP_ID);
+ /*
+ * There is currently no flag in ION for Secure Display
+ * VM. Please add it to the define once available.
+ */
+ flags |= UINT(ION_SD_FLAGS);
+ } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
+ heap_id = ION_HEAP(SD_HEAP_ID);
+ if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
+ flags |= UINT(ION_SC_PREVIEW_FLAGS);
+ } else {
+ flags |= UINT(ION_SC_FLAGS);
+ }
+ } else {
+ heap_id = ION_HEAP(CP_HEAP_ID);
+ flags |= UINT(ION_CP_FLAGS);
+ }
+ } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP) {
+ // MM Heap is exclusively a secure heap.
+ // If it is used for non secure cases, fallback to IOMMU heap
+ ALOGW("MM_HEAP cannot be used as an insecure heap. Using system heap instead!!");
+ heap_id |= ION_HEAP(ION_SYSTEM_HEAP_ID);
+ }
+
+ if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP) {
+ heap_id |= ION_HEAP(ION_CAMERA_HEAP_ID);
+ }
+
+ if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP ||
+ prod_usage & GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA) {
+ heap_id |= ION_HEAP(ION_ADSP_HEAP_ID);
+ }
+
+ if (flags & UINT(ION_SECURE)) {
+ type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
+ }
+
+ // if no ion heap flags are set, default to system heap
+ if (!heap_id) {
+ heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
+ }
+
+ *alloc_type = type;
+ *ion_flags = flags;
+ *ion_heap_id = heap_id;
+
+ return;
+}
+} // namespace gralloc1
diff --git a/sdm845/libgralloc1/gr_allocator.h b/msm8909/gralloc/gr_allocator.h
similarity index 100%
copy from sdm845/libgralloc1/gr_allocator.h
copy to msm8909/gralloc/gr_allocator.h
diff --git a/sdm845/libgralloc1/gr_buf_descriptor.h b/msm8909/gralloc/gr_buf_descriptor.h
similarity index 100%
copy from sdm845/libgralloc1/gr_buf_descriptor.h
copy to msm8909/gralloc/gr_buf_descriptor.h
diff --git a/sdm845/libgralloc1/gr_buf_mgr.cpp b/msm8909/gralloc/gr_buf_mgr.cpp
similarity index 92%
copy from sdm845/libgralloc1/gr_buf_mgr.cpp
copy to msm8909/gralloc/gr_buf_mgr.cpp
index 7e0ba14..23bed23 100644
--- a/sdm845/libgralloc1/gr_buf_mgr.cpp
+++ b/msm8909/gralloc/gr_buf_mgr.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
* Not a Contribution
*
* Copyright (C) 2010 The Android Open Source Project
@@ -43,19 +43,12 @@
char property[PROPERTY_VALUE_MAX];
// Map framebuffer memory
- if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+ if ((property_get(MAP_FB_MEMORY_PROP, property, NULL) > 0) &&
(!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
(!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
map_fb_mem_ = true;
}
- // Enable UBWC for framebuffer
- if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
- (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
- ubwc_for_fb_ = true;
- }
-
handles_map_.clear();
allocator_ = new Allocator();
allocator_->Init();
@@ -199,7 +192,13 @@
gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
auto hnd = buf->handle;
- ALOGD_IF(DEBUG, "FreeBuffer handle:%p id: %" PRIu64, hnd, hnd->id);
+ ALOGD_IF(DEBUG, "FreeBuffer handle:%p", hnd);
+
+ if (private_handle_t::validate(hnd) != 0) {
+ ALOGE("FreeBuffer: Invalid handle: %p", hnd);
+ return GRALLOC1_ERROR_BAD_HANDLE;
+ }
+
if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
hnd->fd, buf->ion_handle_main) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
@@ -214,7 +213,9 @@
private_handle_t * handle = const_cast<private_handle_t *>(hnd);
handle->fd = -1;
handle->fd_metadata = -1;
- delete handle;
+ if (!(handle->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED)) {
+ delete handle;
+ }
return GRALLOC1_ERROR_NONE;
}
@@ -260,27 +261,14 @@
ALOGD_IF(DEBUG, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);
hnd->base = 0;
- hnd->base_metadata = 0;
-
if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
hnd->fd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
-
- unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), getpagesize());
- if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
- hnd->offset_metadata, hnd->fd_metadata) != 0) {
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
return GRALLOC1_ERROR_NONE;
}
gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
- if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
- return GRALLOC1_ERROR_NONE;
- }
-
ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
gralloc1_error_t err = GRALLOC1_ERROR_NONE;
std::lock_guard<std::mutex> lock(buffer_lock_);
@@ -290,23 +278,12 @@
} else {
private_handle_t *handle = const_cast<private_handle_t *>(hnd);
err = ImportHandleLocked(handle);
- if (err == GRALLOC1_ERROR_NONE) {
- // TODO(user): See bug 35955598
- if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
- return GRALLOC1_ERROR_NONE; // Don't map secure buffer
- }
- err = MapBuffer(hnd);
- }
}
return err;
}
gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
- if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
- return GRALLOC1_ERROR_NONE;
- }
-
- ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id);
+ ALOGD_IF(DEBUG, "Release buffer handle:%p", hnd);
std::lock_guard<std::mutex> lock(buffer_lock_);
auto buf = GetBufferFromHandleLocked(hnd);
if (buf == nullptr) {
@@ -344,16 +321,20 @@
err = MapBuffer(hnd);
}
- // Invalidate if CPU reads in software and there are non-CPU
- // writers. No need to do this for the metadata buffer as it is
- // only read/written in software.
-
// todo use handle here
if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
(hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
- if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
- buf->ion_handle_main, CACHE_INVALIDATE)) {
- return GRALLOC1_ERROR_BAD_HANDLE;
+
+ // Invalidate if CPU reads in software and there are non-CPU
+ // writers. No need to do this for the metadata buffer as it is
+ // only read/written in software.
+ if ((cons_usage & (GRALLOC1_CONSUMER_USAGE_CPU_READ | GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN))
+ && (hnd->flags & private_handle_t::PRIV_FLAGS_NON_CPU_WRITER)) {
+ if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
+ buf->ion_handle_main, CACHE_INVALIDATE)) {
+
+ return GRALLOC1_ERROR_BAD_HANDLE;
+ }
}
}
@@ -438,7 +419,7 @@
flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
}
- if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
+ if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
}
@@ -497,14 +478,14 @@
BufferInfo info = GetBufferInfo(descriptor);
GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
size = (bufferSize >= size) ? bufferSize : size;
- size = size * layer_count;
int err = 0;
int flags = 0;
auto page_size = UINT(getpagesize());
AllocData data;
data.align = GetDataAlignment(format, prod_usage, cons_usage);
- data.size = ALIGN(size, data.align);
+ size = ALIGN(size, data.align) * layer_count;
+ data.size = size;
data.handle = (uintptr_t) handle;
data.uncached = allocator_->UseUncached(prod_usage, cons_usage);
@@ -541,7 +522,7 @@
descriptor.GetHeight(),
format,
buffer_type,
- size,
+ data.size,
prod_usage,
cons_usage);
@@ -573,6 +554,10 @@
int format = va_arg(args, int);
native_handle_t **handle = va_arg(args, native_handle_t **);
+ if (!handle) {
+ return GRALLOC1_ERROR_BAD_HANDLE;
+ }
+
private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
if (hnd) {
@@ -582,7 +567,7 @@
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
hnd->size = size;
hnd->offset = offset;
- hnd->base = uint64_t(base) + offset;
+ hnd->base = uint64_t(base);
hnd->gpuaddr = 0;
BufferInfo info(width, height, format);
GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
@@ -600,6 +585,11 @@
int format = va_arg(args, int);
int *stride = va_arg(args, int *);
unsigned int alignedw = 0, alignedh = 0;
+
+ if (!stride) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
BufferInfo info(width, width, format);
GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
*stride = INT(alignedw);
@@ -612,6 +602,10 @@
return GRALLOC1_ERROR_BAD_HANDLE;
}
+ if (!stride) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
BufferDim_t buffer_dim;
if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
*stride = buffer_dim.sliceWidth;
@@ -629,6 +623,10 @@
return GRALLOC1_ERROR_BAD_HANDLE;
}
+ if (!stride || !height) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
BufferDim_t buffer_dim;
if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
*stride = buffer_dim.sliceWidth;
@@ -653,6 +651,10 @@
int *aligned_width = va_arg(args, int *);
int *aligned_height = va_arg(args, int *);
int *tile_enabled = va_arg(args, int *);
+ if (!aligned_width || !aligned_height || !tile_enabled) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
unsigned int alignedw, alignedh;
BufferInfo info(width, height, format, prod_usage, cons_usage);
*tile_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
@@ -664,11 +666,16 @@
case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *color_space = va_arg(args, int *);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!color_space) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
*color_space = 0;
-#ifdef USE_COLOR_METADATA
ColorMetaData color_metadata;
if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
switch (color_metadata.colorPrimaries) {
@@ -686,11 +693,9 @@
break;
}
break;
- }
- if (getMetaData(hnd, GET_COLOR_SPACE, &color_metadata) != 0) {
+ } else if (getMetaData(hnd, GET_COLOR_SPACE, color_space) != 0) {
*color_space = 0;
}
-#endif
} break;
case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
@@ -698,6 +703,11 @@
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!ycbcr) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
if (GetYUVPlaneInfo(hnd, ycbcr)) {
return GRALLOC1_ERROR_UNDEFINED;
}
@@ -706,10 +716,15 @@
case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *map_secure_buffer = va_arg(args, int *);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+ if (!map_secure_buffer) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) == 0) {
*map_secure_buffer = 0;
}
@@ -718,18 +733,36 @@
case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *flag = va_arg(args, int *);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!flag) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
*flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ int linear_format = 0;
+ if (getMetaData(hnd, GET_LINEAR_FORMAT, &linear_format) == 0) {
+ if (linear_format) {
+ *flag = 0;
+ }
+ }
} break;
case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
void **rgb_data = va_arg(args, void **);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!rgb_data) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
if (GetRgbDataAddress(hnd, rgb_data)) {
return GRALLOC1_ERROR_UNDEFINED;
}
@@ -746,6 +779,11 @@
uint32_t *aligned_width = va_arg(args, uint32_t *);
uint32_t *aligned_height = va_arg(args, uint32_t *);
uint32_t *size = va_arg(args, uint32_t *);
+
+ if (!aligned_width || !aligned_height || !size) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
auto info = BufferInfo(width, height, format, producer_usage, consumer_usage);
GetBufferSizeAndDimensions(info, size, aligned_width, aligned_height);
// Align size
@@ -753,9 +791,8 @@
*size = ALIGN(*size, align);
} break;
- // TODO(user): Break out similar functionality, preferably moving to a common lib.
-
case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
+ std::lock_guard<std::mutex> lock(buffer_lock_);
int width = va_arg(args, int);
int height = va_arg(args, int);
int format = va_arg(args, int);
@@ -774,9 +811,15 @@
case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *flag = va_arg(args, int *);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!flag) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
*flag = 0;
}
diff --git a/sdm845/libgralloc1/gr_buf_mgr.h b/msm8909/gralloc/gr_buf_mgr.h
similarity index 98%
copy from sdm845/libgralloc1/gr_buf_mgr.h
copy to msm8909/gralloc/gr_buf_mgr.h
index 4476eaf..861a7a7 100644
--- a/sdm845/libgralloc1/gr_buf_mgr.h
+++ b/msm8909/gralloc/gr_buf_mgr.h
@@ -118,7 +118,6 @@
std::shared_ptr<Buffer> GetBufferFromHandleLocked(const private_handle_t *hnd);
bool map_fb_mem_ = false;
- bool ubwc_for_fb_ = false;
Allocator *allocator_ = NULL;
std::mutex buffer_lock_;
std::mutex descriptor_lock_;
diff --git a/sdm845/libgralloc1/gr_device_impl.cpp b/msm8909/gralloc/gr_device_impl.cpp
similarity index 95%
copy from sdm845/libgralloc1/gr_device_impl.cpp
copy to msm8909/gralloc/gr_device_impl.cpp
index ee90090..7a3c16d 100644
--- a/sdm845/libgralloc1/gr_device_impl.cpp
+++ b/msm8909/gralloc/gr_device_impl.cpp
@@ -27,10 +27,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-#include <cutils/log.h>
-#include <utils/Trace.h>
-#include <cutils/trace.h>
+#include <log/log.h>
#include <sync/sync.h>
#include <algorithm>
#include <sstream>
@@ -347,6 +344,10 @@
gralloc1_error_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_producer_usage_t *outUsage) {
+ if (!outUsage) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
@@ -358,6 +359,10 @@
gralloc1_error_t GrallocImpl::GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *outStride) {
+ if (!outStride) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
*outStride = UINT(PRIV_HANDLE_CONST(buffer)->GetStride());
@@ -373,6 +378,10 @@
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
+ if (!device) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
GrallocImpl const *dev = GRALLOC_IMPL(device);
gralloc1_error_t status = dev->buf_mgr_->AllocateBuffers(num_descriptors, descriptors,
out_buffers);
@@ -392,18 +401,21 @@
}
gralloc1_error_t GrallocImpl::ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
- gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
- if (status == GRALLOC1_ERROR_NONE) {
- const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
- GrallocImpl const *dev = GRALLOC_IMPL(device);
- status = dev->buf_mgr_->ReleaseBuffer(hnd);
+ if (!device || !buffer) {
+ return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
- return status;
+ const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+ GrallocImpl const *dev = GRALLOC_IMPL(device);
+ return dev->buf_mgr_->ReleaseBuffer(hnd);
}
gralloc1_error_t GrallocImpl::GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *out_num_planes) {
+ if (!out_num_planes) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
GrallocImpl const *dev = GRALLOC_IMPL(device);
@@ -424,17 +436,15 @@
gralloc1_consumer_usage_t cons_usage,
const gralloc1_rect_t *region, void **out_data,
int32_t acquire_fence) {
- ATRACE_CALL();
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
- if (status != GRALLOC1_ERROR_NONE) {
+ if (status != GRALLOC1_ERROR_NONE || !out_data ||
+ !region) { // currently we ignore the region/rect client wants to lock
CloseFdIfValid(acquire_fence);
return status;
}
if (acquire_fence > 0) {
- ATRACE_BEGIN("fence wait");
int error = sync_wait(acquire_fence, 1000);
- ATRACE_END();
CloseFdIfValid(acquire_fence);
if (error < 0) {
ALOGE("%s: sync_wait timedout! error = %s", __FUNCTION__, strerror(errno));
@@ -453,13 +463,8 @@
// return GRALLOC1_ERROR_BAD_VALUE;
}
- // currently we ignore the region/rect client wants to lock
- if (region == NULL) {
- return GRALLOC1_ERROR_BAD_VALUE;
- }
// TODO(user): Need to check if buffer was allocated with the same flags
status = dev->buf_mgr_->LockBuffer(hnd, prod_usage, cons_usage);
-
*out_data = reinterpret_cast<void *>(hnd->base);
return status;
@@ -471,7 +476,12 @@
const gralloc1_rect_t *region,
struct android_flex_layout *out_flex_layout,
int32_t acquire_fence) {
- void *out_data;
+ if (!out_flex_layout) {
+ CloseFdIfValid(acquire_fence);
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
+ void *out_data {};
gralloc1_error_t status = GrallocImpl::LockBuffer(device, buffer, prod_usage, cons_usage, region,
&out_data, acquire_fence);
if (status != GRALLOC1_ERROR_NONE) {
@@ -487,11 +497,14 @@
gralloc1_error_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
int32_t *release_fence) {
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-
if (status != GRALLOC1_ERROR_NONE) {
return status;
}
+ if (!release_fence) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
GrallocImpl const *dev = GRALLOC_IMPL(device);
@@ -501,6 +514,10 @@
}
gralloc1_error_t GrallocImpl::Gralloc1Perform(gralloc1_device_t *device, int operation, ...) {
+ if (!device) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
va_list args;
va_start(args, operation);
GrallocImpl const *dev = GRALLOC_IMPL(device);
diff --git a/sdm845/libgralloc1/gr_device_impl.h b/msm8909/gralloc/gr_device_impl.h
similarity index 100%
copy from sdm845/libgralloc1/gr_device_impl.h
copy to msm8909/gralloc/gr_device_impl.h
diff --git a/sdm845/libgralloc1/gr_ion_alloc.cpp b/msm8909/gralloc/gr_ion_alloc.cpp
similarity index 95%
rename from sdm845/libgralloc1/gr_ion_alloc.cpp
rename to msm8909/gralloc/gr_ion_alloc.cpp
index c8300ab..680a516 100644
--- a/sdm845/libgralloc1/gr_ion_alloc.cpp
+++ b/msm8909/gralloc/gr_ion_alloc.cpp
@@ -29,15 +29,14 @@
#define DEBUG 0
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <fcntl.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <errno.h>
#include <utils/Trace.h>
-#include <cutils/trace.h>
-#include <string>
#include "gralloc_priv.h"
#include "gr_utils.h"
@@ -79,29 +78,21 @@
ion_alloc_data.heap_id_mask = data->heap_id;
ion_alloc_data.flags = data->flags;
ion_alloc_data.flags |= data->uncached ? 0 : ION_FLAG_CACHED;
- std::string tag_name{};
- if (ATRACE_ENABLED()) {
- tag_name = "ION_IOC_ALLOC size: " + std::to_string(data->size);
- }
- ATRACE_BEGIN(tag_name.c_str());
if (ioctl(ion_dev_fd_, INT(ION_IOC_ALLOC), &ion_alloc_data)) {
err = -errno;
ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
return err;
}
- ATRACE_END();
fd_data.handle = ion_alloc_data.handle;
handle_data.handle = ion_alloc_data.handle;
- ATRACE_BEGIN("ION_IOC_MAP");
if (ioctl(ion_dev_fd_, INT(ION_IOC_MAP), &fd_data)) {
err = -errno;
ALOGE("%s: ION_IOC_MAP failed with error - %s", __FUNCTION__, strerror(errno));
ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
return err;
}
- ATRACE_END();
data->fd = fd_data.fd;
data->ion_handle = handle_data.handle;
diff --git a/sdm845/libgralloc1/gr_ion_alloc.h b/msm8909/gralloc/gr_ion_alloc.h
similarity index 100%
copy from sdm845/libgralloc1/gr_ion_alloc.h
copy to msm8909/gralloc/gr_ion_alloc.h
diff --git a/sdm845/libgralloc1/gr_priv_handle.h b/msm8909/gralloc/gr_priv_handle.h
similarity index 96%
copy from sdm845/libgralloc1/gr_priv_handle.h
copy to msm8909/gralloc/gr_priv_handle.h
index 49e09a5..8c4797a 100644
--- a/sdm845/libgralloc1/gr_priv_handle.h
+++ b/msm8909/gralloc/gr_priv_handle.h
@@ -20,10 +20,13 @@
#ifndef __GR_PRIV_HANDLE_H__
#define __GR_PRIV_HANDLE_H__
-#include <cutils/log.h>
+#include <errno.h>
+#include <log/log.h>
#include <hardware/gralloc1.h>
#include <hardware/gralloc.h>
+#ifdef __cplusplus
#include <cinttypes>
+#endif
#define GRALLOC1_FUNCTION_PERFORM 0x00001000
@@ -33,7 +36,12 @@
#define PRIV_HANDLE_CONST(exp) static_cast<const private_handle_t *>(exp)
+#ifdef __cplusplus
struct private_handle_t : public native_handle_t {
+#else
+struct private_handle_t {
+ native_handle_t nativeHandle;
+#endif
enum {
PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
PRIV_FLAGS_USES_ION = 0x00000008,
@@ -83,7 +91,7 @@
gralloc1_producer_usage_t producer_usage __attribute__((aligned(8)));
gralloc1_consumer_usage_t consumer_usage __attribute__((aligned(8)));
unsigned int layer_count;
-
+#ifdef __cplusplus
static const int kNumFds = 2;
static const int kMagic = 'gmsm';
@@ -160,7 +168,6 @@
return 0;
}
-
static void Dump(const private_handle_t *hnd) {
ALOGD("handle id:%" PRIu64 " wxh:%dx%d uwxuh:%dx%d size: %d fd:%d fd_meta:%d flags:0x%x "
"prod_usage:0x%" PRIx64" cons_usage:0x%" PRIx64 " format:0x%x layer_count: %d",
@@ -187,6 +194,7 @@
gralloc1_producer_usage_t GetProducerUsage() const { return producer_usage; }
uint64_t GetBackingstore() const { return id; }
+#endif
};
#endif // __GR_PRIV_HANDLE_H__
diff --git a/sdm845/libgralloc1/gr_utils.cpp b/msm8909/gralloc/gr_utils.cpp
similarity index 95%
rename from sdm845/libgralloc1/gr_utils.cpp
rename to msm8909/gralloc/gr_utils.cpp
index b3056e1..d89b8fe 100644
--- a/sdm845/libgralloc1/gr_utils.cpp
+++ b/msm8909/gralloc/gr_utils.cpp
@@ -357,29 +357,33 @@
bool interlaced = false;
memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
- MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
// Check if UBWC buffer has been rendered in linear format.
- if (metadata && (metadata->operation & LINEAR_FORMAT)) {
- format = INT(metadata->linearFormat);
+ int linear_format = 0;
+ if (getMetaData(const_cast<private_handle_t *>(hnd),
+ GET_LINEAR_FORMAT, &linear_format) == 0) {
+ format = INT(linear_format);
}
// Check metadata if the geometry has been updated.
- if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+ BufferDim_t buffer_dim;
+ if (getMetaData(const_cast<private_handle_t *>(hnd),
+ GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
int usage = 0;
-
if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
}
- BufferInfo info(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
+ BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format,
prod_usage, cons_usage);
GetAlignedWidthAndHeight(info, &width, &height);
}
// Check metadata for interlaced content.
- if (metadata && (metadata->operation & PP_PARAM_INTERLACED)) {
- interlaced = metadata->interlaced ? true : false;
+ int interlace_flag = 0;
+ if (getMetaData(const_cast<private_handle_t *>(hnd),
+ GET_PP_PARAM_INTERLACED, &interlace_flag) != 0) {
+ interlaced = interlace_flag;
}
// Get the chroma offsets from the handle width/height. We take advantage
@@ -509,7 +513,9 @@
// Query GPU for UBWC only if buffer is intended to be used by GPU.
if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
(prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
- enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
+ if (AdrenoMemInfo::GetInstance()) {
+ enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
+ }
}
// Allow UBWC, only if CPU usage flags are not set
@@ -675,8 +681,10 @@
int tile = ubwc_enabled;
if (IsUncompressedRGBFormat(format)) {
- AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
- alignedh);
+ if (AdrenoMemInfo::GetInstance()) {
+ AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
+ alignedh);
+ }
return;
}
@@ -686,7 +694,9 @@
}
if (IsCompressedRGBFormat(format)) {
- AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
+ if (AdrenoMemInfo::GetInstance()) {
+ AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
+ }
return;
}
@@ -698,6 +708,9 @@
switch (format) {
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ if (AdrenoMemInfo::GetInstance() == nullptr) {
+ return;
+ }
alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
aligned_w = ALIGN(width, alignment);
break;
diff --git a/sdm845/libgralloc1/gr_utils.h b/msm8909/gralloc/gr_utils.h
similarity index 100%
copy from sdm845/libgralloc1/gr_utils.h
copy to msm8909/gralloc/gr_utils.h
diff --git a/sdm845/libgralloc1/gralloc_priv.h b/msm8909/gralloc/gralloc_priv.h
similarity index 93%
copy from sdm845/libgralloc1/gralloc_priv.h
copy to msm8909/gralloc/gralloc_priv.h
index 1839d2f..5e619eb 100644
--- a/sdm845/libgralloc1/gralloc_priv.h
+++ b/msm8909/gralloc/gralloc_priv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
* Not a Contribution
*
* Copyright (C) 2008 The Android Open Source Project
@@ -23,6 +23,13 @@
#include <unistd.h>
#include "gr_priv_handle.h"
+#define GRALLOC_PROP_PREFIX "vendor.gralloc."
+#define GRALLOC_PROP(prop_name) GRALLOC_PROP_PREFIX prop_name
+
+#define DISABLE_UBWC_PROP GRALLOC_PROP("disable_ubwc")
+#define ENABLE_FB_UBWC_PROP GRALLOC_PROP("enable_fb_ubwc")
+#define MAP_FB_MEMORY_PROP GRALLOC_PROP("map_fb_memory")
+
#define ROUND_UP_PAGESIZE(x) roundUpToPageSize(x)
inline int roundUpToPageSize(int x) {
return (x + (getpagesize()-1)) & ~(getpagesize()-1);
@@ -61,7 +68,7 @@
#define GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD 0x00200000
/* This flag is used for SECURE display usecase */
-#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY 0x00800000
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY 0x02000000
/* Buffer content should be displayed on a primary display only */
#define GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY 0x04000000
@@ -77,6 +84,7 @@
#define GRALLOC_USAGE_PRIVATE_IOMMU_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_IOMMU_HEAP
#define GRALLOC_USAGE_PRIVATE_WFD GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD
#define GRALLOC_USAGE_PRIVATE_CAMERA_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP
+#define GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY
#define GRALLOC_USAGE_PRIVATE_MM_HEAP 0x0
diff --git a/sdm845/hdmi_cec/Android.mk b/msm8909/hdmi_cec/Android.mk
similarity index 76%
rename from sdm845/hdmi_cec/Android.mk
rename to msm8909/hdmi_cec/Android.mk
index a333654..4fed1f0 100644
--- a/sdm845/hdmi_cec/Android.mk
+++ b/msm8909/hdmi_cec/Android.mk
@@ -8,11 +8,11 @@
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes)
LOCAL_HEADER_LIBRARIES := display_headers
-LOCAL_SHARED_LIBRARIES := $(common_libs) libqservice libbinder libqdutils
+LOCAL_SHARED_LIBRARIES := $(common_libs)
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhdmi_cec\" -Wno-sign-conversion
LOCAL_CLANG := true
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := qhdmi_cec.cpp \
- QHDMIClient.cpp
+LOCAL_SRC_FILES := qhdmi_cec.cpp
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/sdm845/hdmi_cec/qhdmi_cec.cpp b/msm8909/hdmi_cec/qhdmi_cec.cpp
similarity index 66%
copy from sdm845/hdmi_cec/qhdmi_cec.cpp
copy to msm8909/hdmi_cec/qhdmi_cec.cpp
index 0923d92..be3ff99 100644
--- a/sdm845/hdmi_cec/qhdmi_cec.cpp
+++ b/msm8909/hdmi_cec/qhdmi_cec.cpp
@@ -29,14 +29,14 @@
#define DEBUG 0
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-#include <cstdlib>
-#include <cutils/log.h>
+#include <log/log.h>
#include <errno.h>
-#include <fcntl.h>
#include <hardware/hdmi_cec.h>
#include <utils/Trace.h>
+#include <utils/debug.h>
+#include <utils/sys.h>
+#include <vector>
#include "qhdmi_cec.h"
-#include "QHDMIClient.h"
namespace qhdmicec {
@@ -45,6 +45,10 @@
const int MAX_CEC_FRAME_SIZE = 20;
const int MAX_SEND_MESSAGE_RETRIES = 1;
+const char* SYSFS_BASE = "/sys/devices/virtual/graphics/fb";
+const char* UEVENT_SWITCH_HDMI = "change@/devices/virtual/switch/hdmi";
+const char* FB_PATH = "/sys/devices/virtual/graphics/fb";
+
enum {
LOGICAL_ADDRESS_SET = 1,
LOGICAL_ADDRESS_UNSET = -1,
@@ -66,6 +70,17 @@
static void cec_close_context(cec_context_t* ctx __unused);
static int cec_enable(cec_context_t *ctx, int enable);
static int cec_is_connected(const struct hdmi_cec_device* dev, int port_id);
+static void cec_monitor_deinit(cec_context_t* ctx);
+static void handle_cec_msg_event(cec_context_t* ctx, uint32_t node_event);
+
+void event_monitor(cec_context_t* ctx); // hdmi event monitor function
+static int get_event_value(const char *uevent_data, int length, const char *event_info);
+static int uevent_init(int *uevent_fd);
+static void handle_hdmihotplug_event(cec_context_t* ctx, uint32_t node_event);
+
+static int populate_event_data(cec_context_t* ctx, std::vector<eventData> *event_data_list);
+static int set_event_params(cec_context_t* ctx, uint32_t node_event, eventData *event_data);
+static void handle_exit_event(cec_context_t* ctx, uint32_t node_event);
static ssize_t read_node(const char *path, char *data)
{
@@ -108,12 +123,12 @@
const char *path_postfix,
const int value)
{
- char sysfs_full_path[MAX_PATH_LENGTH];
+ std::string sysfs_full_path;
char sysfs_data[MAX_SYSFS_DATA];
snprintf(sysfs_data, sizeof(sysfs_data), "%d",value);
- snprintf(sysfs_full_path,sizeof(sysfs_full_path), "%s/%s",
- ctx->fb_sysfs_path, path_postfix);
- ssize_t err = write_node(sysfs_full_path, sysfs_data, strlen(sysfs_data));
+ sysfs_full_path = ctx->fb_sysfs_path + "/";
+ sysfs_full_path.append(path_postfix);
+ ssize_t err = write_node(sysfs_full_path.c_str(), sysfs_data, strlen(sysfs_data));
return err;
}
@@ -135,21 +150,18 @@
//XXX: Do this from a common utility library across the display HALs
const int MAX_FB_DEVICES = 2;
ssize_t len = 0;
- char fb_type_path[MAX_PATH_LENGTH];
+ std::string fb_type_path;
char fb_type[MAX_SYSFS_DATA];
const char *dtv_panel_str = "dtv panel";
for(int num = 0; num < MAX_FB_DEVICES; num++) {
- snprintf(fb_type_path, sizeof(fb_type_path),"%s%d/msm_fb_type",
- SYSFS_BASE,num);
- ALOGD_IF(DEBUG, "%s: num: %d fb_type_path: %s", __FUNCTION__, num, fb_type_path);
- len = read_node(fb_type_path, fb_type);
+ fb_type_path = SYSFS_BASE + std::to_string(ctx->fb_num) + "/msm_fb_type";
+ len = read_node(fb_type_path.c_str(), fb_type);
ALOGD_IF(DEBUG, "%s: fb_type:%s", __FUNCTION__, fb_type);
if(len > 0 && (strncmp(fb_type, dtv_panel_str, strlen(dtv_panel_str)) == 0)){
ALOGD_IF(DEBUG, "%s: Found DTV panel at fb%d", __FUNCTION__, num);
ctx->fb_num = num;
- snprintf(ctx->fb_sysfs_path, sizeof(ctx->fb_sysfs_path),
- "%s%d", SYSFS_BASE, num);
+ ctx->fb_sysfs_path = SYSFS_BASE + std::to_string(ctx->fb_num);
break;
}
}
@@ -190,11 +202,11 @@
uint16_t* addr)
{
cec_context_t* ctx = (cec_context_t*)(dev);
- char pa_path[MAX_PATH_LENGTH];
+ std::string pa_path;
char pa_data[MAX_SYSFS_DATA];
- snprintf (pa_path, sizeof(pa_path),"%s/pa",
- ctx->fb_sysfs_path);
- int err = (int) read_node(pa_path, pa_data);
+ pa_path = ctx->fb_sysfs_path;
+ pa_path.append("/pa");
+ int err = (int) read_node(pa_path.c_str(), pa_data);
*addr = (uint16_t) atoi(pa_data);
ALOGD_IF(DEBUG, "%s: Physical Address: 0x%x", __FUNCTION__, *addr);
if (err < 0)
@@ -222,7 +234,7 @@
ALOGD_IF(DEBUG, "%s: message from framework: %s", __FUNCTION__, dump);
}
- char write_msg_path[MAX_PATH_LENGTH];
+ std::string write_msg_path;
char write_msg[MAX_CEC_FRAME_SIZE];
memset(write_msg, 0, sizeof(write_msg));
// See definition of struct hdmi_cec_msg in driver code
@@ -240,14 +252,13 @@
//msg length + initiator + destination
write_msg[CEC_OFFSET_FRAME_LENGTH] = (unsigned char) (msg->length + 1);
hex_to_string(write_msg, sizeof(write_msg), dump);
- ALOGD_IF(DEBUG, "%s: message to driver: %s", __FUNCTION__, dump);
- snprintf(write_msg_path, sizeof(write_msg_path), "%s/cec/wr_msg",
- ctx->fb_sysfs_path);
+ write_msg_path = ctx->fb_sysfs_path;
+ write_msg_path.append("/cec/wr_msg");
int retry_count = 0;
ssize_t err = 0;
//HAL spec requires us to retry at least once.
while (true) {
- err = write_node(write_msg_path, write_msg, sizeof(write_msg));
+ err = write_node(write_msg_path.c_str(), write_msg, sizeof(write_msg));
retry_count++;
if (err == -EAGAIN && retry_count <= MAX_SEND_MESSAGE_RETRIES) {
ALOGE("%s: CEC line busy, retrying", __FUNCTION__);
@@ -383,11 +394,11 @@
// Ignore port_id since we have only one port
int connected = 0;
cec_context_t* ctx = (cec_context_t*)(dev);
- char connected_path[MAX_PATH_LENGTH];
+ std::string connected_path;
char connected_data[MAX_SYSFS_DATA];
- snprintf (connected_path, sizeof(connected_path),"%s/connected",
- ctx->fb_sysfs_path);
- ssize_t err = read_node(connected_path, connected_data);
+ connected_path = ctx->fb_sysfs_path;
+ connected_path.append("/connected");
+ ssize_t err = read_node(connected_path.c_str(), connected_data);
connected = atoi(connected_data);
ALOGD_IF(DEBUG, "%s: HDMI at port %d is - %s", __FUNCTION__, port_id,
@@ -429,6 +440,7 @@
static void cec_init_context(cec_context_t *ctx)
{
ALOGD_IF(DEBUG, "%s: Initializing context", __FUNCTION__);
+ int err = -EINVAL;
cec_get_fb_node_number(ctx);
//Initialize ports - We support only one output port
@@ -445,20 +457,42 @@
ctx->vendor_id = 0xA47733;
cec_clear_logical_address((hdmi_cec_device_t*)ctx);
- //Set up listener for HDMI events
- ctx->disp_client = new qClient::QHDMIClient();
- ctx->disp_client->setCECContext(ctx);
- ctx->disp_client->registerClient(ctx->disp_client);
-
//Enable CEC - framework expects it to be enabled by default
cec_enable(ctx, true);
ALOGD("%s: CEC enabled", __FUNCTION__);
+
+ ctx->node_list.push_back("cec_msg_event");
+ ctx->node_list.push_back("hotplug_event");
+ ctx->node_list.push_back("exit_event");
+
+ err = populate_event_data(ctx, &ctx->event_data_list);
+ if (err < 0) {
+ ALOGE("Failed to populate poll parameters for monitoring HDMI CEC events. Exiting.");
+ cec_enable(ctx, false);
+ return;
+ }
+
+ ctx->hdmi_cec_monitor = std::thread(event_monitor, ctx);
+
}
static void cec_close_context(cec_context_t* ctx __unused)
{
ALOGD("%s: Closing context", __FUNCTION__);
+
+ uint64_t exit_value = 1;
+ long int write_size = write(ctx->exit_fd, &exit_value, sizeof(uint64_t));
+
+ if (write_size != sizeof(uint64_t)) {
+ ALOGE("Error triggering exit_fd (%d). write size = %ld, error = %s",
+ ctx->exit_fd, write_size, strerror(errno));
+ return;
+ }
+
+ if (ctx->hdmi_cec_monitor.joinable()) {
+ ctx->hdmi_cec_monitor.join();
+ }
}
static int cec_device_open(const struct hw_module_t* module,
@@ -472,7 +506,6 @@
dev = (cec_context_t *) calloc (1, sizeof(*dev));
if (dev) {
cec_init_context(dev);
-
//Setup CEC methods
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = HDMI_CEC_DEVICE_API_VERSION_1_0;
@@ -498,6 +531,176 @@
}
return status;
}
+
+void event_monitor(cec_context_t* ctx) {
+ ALOGD("%s IN", __FUNCTION__);
+ int err = -EINVAL;
+
+ prctl(PR_SET_NAME, "cec_monitor", 0, 0, 0);
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+ while (!ctx->cec_exit_thread) {
+ err = poll(ctx->poll_fds.data(), (nfds_t)ctx->event_data_list.size(), -1);
+ if ( err <= 0 ) {
+ ALOGI("Failed to poll, Error %s", strerror(errno));
+ continue;
+ }
+
+ for (uint32_t event = 0; event < ctx->event_data_list.size(); event++) {
+ pollfd &poll_fd = ctx->poll_fds[event];
+
+ if (poll_fd.revents & POLLIN || poll_fd.revents & POLLPRI) {
+ ctx->event_data_list[event].event_parser(ctx, event);
+ }
+ }
+ }
+
+ cec_monitor_deinit(ctx);
+ ALOGD("%s OUT", __FUNCTION__);
+ return;
+}
+
+static int populate_event_data(cec_context_t* ctx, std::vector<eventData> *event_data_list) {
+ int err = -EINVAL;
+ ctx->poll_fds.resize(ctx->node_list.size());
+
+ for (uint32_t event = 0; event < ctx->node_list.size(); event++) {
+ const char *event_name = ctx->node_list.at(event).c_str();
+ eventData event_data;
+ event_data.event_name = event_name;
+ err = set_event_params(ctx, event, &event_data);
+ if (err < 0) {
+ ALOGE("Failed to set poll event parameters");
+ return err;
+ }
+
+ event_data_list->push_back(event_data);
+ }
+
+ return 0;
+}
+
+static int set_event_params(cec_context_t* ctx, uint32_t node_event, eventData *event_data) {
+ pollfd poll_fd;
+ poll_fd.fd = -EINVAL;
+
+ if (!strncmp(event_data->event_name, "cec_msg_event", strlen("cec_msg_event"))) {
+ char node_path[MAX_STRING_LENGTH] = {0};
+
+ snprintf(node_path, sizeof(node_path), "%s%d/%s", FB_PATH, ctx->fb_num, "cec/rd_msg");
+ poll_fd.fd = open(node_path, O_RDONLY);
+ if (poll_fd.fd < 0) {
+ ALOGE("Node open failed for display %d event %s error %s",
+ ctx->fb_num, "cec/rd_msg", strerror(errno));
+ return poll_fd.fd;
+ }
+
+ poll_fd.events |= POLLPRI | POLLERR;
+ // Read once on fd to clear the data
+ pread(poll_fd.fd, ctx->data, MAX_STRING_LENGTH, 0);
+ event_data->event_parser = &handle_cec_msg_event;
+ } else if (!strncmp(event_data->event_name, "hotplug_event", strlen("hotplug_event"))) {
+ if (!uevent_init(&poll_fd.fd)) {
+ ALOGE("Failed to register uevent for hotplug detection");
+ return -1;
+ }
+
+ poll_fd.events |= POLLIN | POLLERR;
+ event_data->event_parser = &handle_hdmihotplug_event;
+ } else if (!strncmp(event_data->event_name, "exit_event", strlen("exit_event"))) {
+ poll_fd.fd = eventfd(0, 0);
+ poll_fd.events |= POLLIN;
+ event_data->event_parser = &handle_exit_event;
+ ctx->exit_fd = poll_fd.fd;
+ }
+
+ ctx->poll_fds[node_event] = poll_fd;
+ return 0;
+}
+
+static void handle_cec_msg_event(cec_context_t* ctx, uint32_t node_event) {
+ if ((ctx->poll_fds[node_event].revents & POLLPRI) &&
+ (pread(ctx->poll_fds[node_event].fd, ctx->data, MAX_STRING_LENGTH, 0) > 0)) {
+ ALOGD_IF(DEBUG, "Handling CEC message %s", __FUNCTION__);
+ cec_receive_message(ctx, ctx->data, 0);
+ }
+
+ return;
+}
+
+static void handle_hdmihotplug_event(cec_context_t* ctx, uint32_t node_event) {
+ char uevent_data[PAGE_SIZE];
+ int count = 0;
+
+ if (ctx->poll_fds[node_event].revents & POLLIN) {
+ count = static_cast<int> (recv(ctx->poll_fds[node_event].fd, uevent_data,
+ (INT32(sizeof(uevent_data))) - 2, 0));
+
+ if ((count > 0) && (strcasestr(UEVENT_SWITCH_HDMI, uevent_data))) {
+ int connected = get_event_value(uevent_data, count, "SWITCH_STATE=");
+ ALOGD("HDMI CEC is %s", connected ? "connected" : "disconnected");
+ cec_hdmi_hotplug(ctx, connected);
+ }
+ }
+
+ return;
+}
+
+static void handle_exit_event(cec_context_t* ctx, uint32_t node_event) {
+ ALOGD_IF(DEBUG, "Enter %s", __FUNCTION__);
+
+ if (ctx->poll_fds[node_event].revents & POLLIN) {
+ ctx->cec_exit_thread = true;
+ }
+
+ return;
+}
+
+static void cec_monitor_deinit(cec_context_t* ctx) {
+ for (uint32_t event = 0; event < ctx->poll_fds.size(); event++) {
+ close(ctx->poll_fds[event].fd);
+ ctx->poll_fds[event].fd = -1;
+ }
+}
+
+static int get_event_value(const char *uevent_data, int length, const char *event_info) {
+ const char *iterator_str = uevent_data;
+ while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
+ const char *pstr = strstr(iterator_str, event_info);
+ if (pstr != NULL) {
+ return (atoi(iterator_str + strlen(event_info)));
+ }
+ iterator_str += strlen(iterator_str) + 1;
+ }
+ return -1;
+}
+
+/* Returns 0 on failure, 1 on success */
+static int uevent_init(int *uevent_fd) {
+ struct sockaddr_nl addr;
+ int sz = 64*1024;
+ int s;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.nl_family = AF_NETLINK;
+ addr.nl_pid = getpid();
+ addr.nl_groups = 0xffffffff;
+
+ s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+ if (s < 0)
+ return 0;
+
+ setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz));
+
+ if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ close(s);
+ return 0;
+ }
+
+ *uevent_fd = s;
+ return (*uevent_fd > 0);
+}
+
}; //namespace qhdmicec
// Standard HAL module, should be outside qhdmicec namespace
@@ -516,5 +719,3 @@
.methods = &cec_module_methods,
}
};
-
-
diff --git a/sdm845/hdmi_cec/qhdmi_cec.h b/msm8909/hdmi_cec/qhdmi_cec.h
similarity index 74%
rename from sdm845/hdmi_cec/qhdmi_cec.h
rename to msm8909/hdmi_cec/qhdmi_cec.h
index aa97620..e2c9755 100644
--- a/sdm845/hdmi_cec/qhdmi_cec.h
+++ b/msm8909/hdmi_cec/qhdmi_cec.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,16 +30,17 @@
#define QHDMI_CEC_H
#include <hardware/hdmi_cec.h>
-#include <utils/RefBase.h>
-
-namespace qClient {
- class QHDMIClient;
-};
+#include <sys/poll.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/resource.h>
+#include <linux/netlink.h>
+#include <thread>
+#include <vector>
namespace qhdmicec {
-#define SYSFS_BASE "/sys/class/graphics/fb"
-#define MAX_PATH_LENGTH 128
+static const int MAX_STRING_LENGTH = 1024;
struct cec_callback_t {
// Function in HDMI service to call back on CEC messages
@@ -49,6 +50,8 @@
};
+struct eventData;
+
struct cec_context_t {
hdmi_cec_device_t device; // Device for HW module
cec_callback_t callback; // Struct storing callback object
@@ -56,7 +59,7 @@
bool arc_enabled;
bool system_control; // If true, HAL/driver handle CEC messages
int fb_num; // Framebuffer node for HDMI
- char fb_sysfs_path[MAX_PATH_LENGTH];
+ std::string fb_sysfs_path;
hdmi_port_info *port_info; // HDMI port info
// Logical address is stored in an array, the index of the array is the
@@ -64,7 +67,21 @@
int logical_address[CEC_ADDR_BROADCAST];
int version;
uint32_t vendor_id;
- android::sp<qClient::QHDMIClient> disp_client;
+
+ std::vector<pollfd> poll_fds; // poll fds for cec message monitor and exit signal
+ // on cec message monitor thread
+ int exit_fd = -1;
+ bool cec_exit_thread = false;
+ std::thread hdmi_cec_monitor; // hdmi plugin monitor thread variable
+ char data[MAX_STRING_LENGTH] = {0};
+
+ std::vector<std::string> node_list = {};
+ std::vector<eventData> event_data_list = {};
+};
+
+struct eventData {
+ const char* event_name = NULL;
+ void (*event_parser)(cec_context_t* ctx, uint32_t node_event) = NULL;
};
void cec_receive_message(cec_context_t *ctx, char *msg, ssize_t len);
diff --git a/msm8909/include/Android.mk b/msm8909/include/Android.mk
new file mode 100644
index 0000000..74c37af
--- /dev/null
+++ b/msm8909/include/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH:= $(call my-dir)
+include $(LOCAL_PATH)/../common.mk
+include $(CLEAR_VARS)
+
+# Legacy header copy. This is deprecated.
+# Modules using these headers should shift to using
+# LOCAL_HEADER_LIBRARIES := display_headers
+LOCAL_VENDOR_MODULE := true
+LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
+LOCAL_COPY_HEADERS := color_metadata.h \
+ display_properties.h \
+ ../libqdutils/qd_utils.h \
+ ../libqdutils/qdMetaData.h \
+ ../libqdutils/display_config.h \
+ ../libqservice/QServiceUtils.h \
+ ../libqservice/IQService.h \
+ ../libqservice/IQHDMIClient.h \
+ ../libqservice/IQClient.h
+
+include $(BUILD_COPY_HEADERS)
diff --git a/sdm845/include/color_metadata.h b/msm8909/include/color_metadata.h
similarity index 100%
rename from sdm845/include/color_metadata.h
rename to msm8909/include/color_metadata.h
diff --git a/msm8909/include/display_properties.h b/msm8909/include/display_properties.h
new file mode 100644
index 0000000..b9c8971
--- /dev/null
+++ b/msm8909/include/display_properties.h
@@ -0,0 +1,101 @@
+/*
+* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DISPLAY_PROPERTIES_H__
+#define __DISPLAY_PROPERTIES_H__
+
+#define DISP_PROP_PREFIX "vendor.display."
+#define GRALLOC_PROP_PREFIX "vendor.gralloc."
+#define RO_DISP_PROP_PREFIX "ro.vendor.display."
+#define PERSIST_DISP_PROP_PREFIX "persist.vendor.display."
+
+#define DISPLAY_PROP(prop_name) DISP_PROP_PREFIX prop_name
+#define GRALLOC_PROP(prop_name) GRALLOC_PROP_PREFIX prop_name
+#define RO_DISPLAY_PROP(prop_name) RO_DISP_PROP_PREFIX prop_name
+#define PERSIST_DISPLAY_PROP(prop_name) PERSIST_DISP_PROP_PREFIX prop_name
+
+#define COMPOSITION_MASK_PROP DISPLAY_PROP("comp_mask")
+#define HDMI_CONFIG_INDEX_PROP DISPLAY_PROP("hdmi_cfg_idx")
+#define IDLE_TIME_PROP DISPLAY_PROP("idle_time")
+#define IDLE_TIME_INACTIVE_PROP DISPLAY_PROP("idle_time_inactive")
+#define BOOT_ANIMATION_LAYER_COUNT_PROP DISPLAY_PROP("boot_anim_layer_count")
+#define DISABLE_ROTATOR_DOWNSCALE_PROP DISPLAY_PROP("disable_rotator_downscale")
+#define DISABLE_DECIMATION_PROP DISPLAY_PROP("disable_decimation")
+#define PRIMARY_MIXER_STAGES_PROP DISPLAY_PROP("primary_mixer_stages")
+#define EXTERNAL_MIXER_STAGES_PROP DISPLAY_PROP("external_mixer_stages")
+#define VIRTUAL_MIXER_STAGES_PROP DISPLAY_PROP("virtual_mixer_stages")
+#define MAX_UPSCALE_PROP DISPLAY_PROP("max_upscale")
+#define VIDEO_MODE_PANEL_PROP DISPLAY_PROP("video_mode_panel")
+#define DISABLE_ROTATOR_UBWC_PROP DISPLAY_PROP("disable_rotator_ubwc")
+#define DISABLE_ROTATOR_SPLIT_PROP DISPLAY_PROP("disable_rotator_split")
+#define DISABLE_SCALER_PROP DISPLAY_PROP("disable_scaler")
+#define DISABLE_AVR_PROP DISPLAY_PROP("disable_avr")
+#define DISABLE_EXTERNAL_ANIMATION_PROP DISPLAY_PROP("disable_ext_anim")
+#define DISABLE_PARTIAL_SPLIT_PROP DISPLAY_PROP("disable_partial_split")
+#define PREFER_SOURCE_SPLIT_PROP DISPLAY_PROP("prefer_source_split")
+#define MIXER_RESOLUTION_PROP DISPLAY_PROP("mixer_resolution")
+#define SIMULATED_CONFIG_PROP DISPLAY_PROP("simulated_config")
+#define MAX_EXTERNAL_LAYERS_PROP DISPLAY_PROP("max_external_layers")
+#define PERF_HINT_WINDOW_PROP DISPLAY_PROP("perf_hint_window")
+#define ENABLE_EXTERNAL_DOWNSCALE_PROP DISPLAY_PROP("enable_external_downscale")
+#define EXTERNAL_ACTION_SAFE_WIDTH_PROP DISPLAY_PROP("external_action_safe_width")
+#define EXTERNAL_ACTION_SAFE_HEIGHT_PROP DISPLAY_PROP("external_action_safe_height")
+#define FB_WIDTH_PROP DISPLAY_PROP("fb_width")
+#define FB_HEIGHT_PROP DISPLAY_PROP("fb_height")
+#define DISABLE_METADATA_DYNAMIC_FPS_PROP DISPLAY_PROP("disable_metadata_dynamic_fps")
+#define DISABLE_BLIT_COMPOSITION_PROP DISPLAY_PROP("disable_blit_comp")
+#define DISABLE_SKIP_VALIDATE_PROP DISPLAY_PROP("disable_skip_validate")
+#define HDMI_S3D_MODE_PROP DISPLAY_PROP("hdmi_s3d_mode")
+#define DISABLE_DESTINATION_SCALER_PROP DISPLAY_PROP("disable_dest_scaler")
+#define ENABLE_PARTIAL_UPDATE_PROP DISPLAY_PROP("enable_partial_update")
+#define ENABLE_ROTATOR_SYNC_ALLOC DISPLAY_PROP("rotator_sync_alloc")
+#define WRITEBACK_SUPPORTED DISPLAY_PROP("support_writeback")
+#define DISABLE_UBWC_PROP GRALLOC_PROP("disable_ubwc")
+#define ENABLE_FB_UBWC_PROP GRALLOC_PROP("enable_fb_ubwc")
+#define MAP_FB_MEMORY_PROP GRALLOC_PROP("map_fb_memory")
+
+#define MAX_BLIT_FACTOR_PROP DISPLAY_PROP("max_blit_factor")
+#define DISABLE_SECURE_INLINE_ROTATOR_PROP DISPLAY_PROP("disable_secure_inline_rotator")
+#define DISABLE_MULTIRECT_PROP DISPLAY_PROP("disable_multirect")
+#define DISABLE_UBWC_FF_VOTING_PROP DISPLAY_PROP("disable_ubwc_ff_voting")
+#define DISABLE_INLINE_ROTATOR_PROP DISPLAY_PROP("disable_inline_rotator")
+#define DISABLE_FB_CROPPING_PROP DISPLAY_PROP("disable_fb_cropping")
+#define PRIORITIZE_CACHE_COMPOSITION_PROP DISPLAY_PROP("prioritize_cache_comp")
+
+#define DISABLE_HDR_LUT_GEN DISPLAY_PROP("disable_hdr_lut_gen")
+#define ENABLE_DEFAULT_COLOR_MODE DISPLAY_PROP("enable_default_color_mode")
+#define DISABLE_HDR DISPLAY_PROP("disable_hdr")
+
+#define HDR_CONFIG_PROP RO_DISPLAY_PROP("hdr.config")
+#define QDCM_PCC_TRANS_PROP DISPLAY_PROP("qdcm.pcc_for_trans")
+#define QDCM_DIAGONAL_MATRIXMODE_PROP DISPLAY_PROP("qdcm.diagonal_matrix_mode")
+#define QDCM_DISABLE_TIMEOUT_PROP PERSIST_DISPLAY_PROP("qdcm.disable_timeout")
+
+
+#endif // __DISPLAY_PROPERTIES_H__
diff --git a/msm8909/libcopybit/Android.mk b/msm8909/libcopybit/Android.mk
index f2c78b2..6e906c3 100644
--- a/msm8909/libcopybit/Android.mk
+++ b/msm8909/libcopybit/Android.mk
@@ -14,22 +14,24 @@
LOCAL_PATH:= $(call my-dir)
include $(LOCAL_PATH)/../common.mk
-
include $(CLEAR_VARS)
+
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := copybit.h copybit_priv.h c2d2.h
+#Copy the headers regardless of whether copybit is built
include $(BUILD_COPY_HEADERS)
include $(CLEAR_VARS)
+ifneq ($(TARGET_USES_GRALLOC1), true)
LOCAL_MODULE := copybit.$(TARGET_BOARD_PLATFORM)
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SHARED_LIBRARIES := $(common_libs) libdl libmemalloc
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdcopybit\"
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdcopybit\" -Wno-sign-conversion
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_CLANG := $(common_clang_flags)
+LOCAL_CLANG := true
ifeq ($(TARGET_USES_C2D_COMPOSITION),true)
LOCAL_CFLAGS += -DCOPYBIT_Z180=1 -DC2D_SUPPORT_DISPLAY=1
@@ -48,3 +50,4 @@
endif
endif
endif
+endif
diff --git a/msm8909/libcopybit/c2d2.h b/msm8909/libcopybit/c2d2.h
index 886f38a..315a3ba 100644
--- a/msm8909/libcopybit/c2d2.h
+++ b/msm8909/libcopybit/c2d2.h
@@ -72,6 +72,7 @@
C2D_FORMAT_MACROTILED = (1 << 16), /* tiled in macro level */
C2D_FORMAT_TILED_4x4 = (1 << 17), /* 4x4 tiled format */
C2D_FORMAT_SWAP_RB = (1 << 18), /* Swap R & B color components */
+ C2D_FORMAT_UBWC_COMPRESSED = (1 << 23), /* UBWC compressed format */
} C2D_FORMAT_MODE;
/* Definitions of supported RGB formats, used in C2D_RGB_SURFACE_DEF.
@@ -408,7 +409,8 @@
C2D_DRIVER_SUPPORTS_TARGET_RECT_OP = (1 << 15),
C2D_DRIVER_SUPPORTS_ROTATE_OP = (1 << 16), /* all rotations */
C2D_DRIVER_SUPPORTS_FLUSH_WITH_FENCE_FD_OP = (1 << 17), /* all rotations */
- C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP = ((0xFFFFFFFF) >> (31 - 17)) /* mask for all capabilities supported */
+ C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP = (1 << 18), /* UBWC Compression */
+ C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP = ((0xFFFFFFFF) >> (31 - 18)) /* mask for all capabilities supported */
} C2D_DRIVER_CAPABILITIES;
/* 2D driver workaround bits used by the 2D applications */
diff --git a/msm8909/libcopybit/copybit.cpp b/msm8909/libcopybit/copybit.cpp
index c2790f8..bd49edc 100644
--- a/msm8909/libcopybit/copybit.cpp
+++ b/msm8909/libcopybit/copybit.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010 - 2014,2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are retained
* for attribution purposes only.
@@ -18,7 +18,7 @@
* limitations under the License.
*/
-#include <cutils/log.h>
+#include <log/log.h>
#include <linux/msm_mdp.h>
#include <linux/fb.h>
@@ -75,22 +75,22 @@
struct hw_device_t** device);
static struct hw_module_methods_t copybit_module_methods = {
- .open = open_copybit
+open: open_copybit
};
/*
* The COPYBIT Module
*/
struct copybit_module_t HAL_MODULE_INFO_SYM = {
- .common = {
- .tag = HARDWARE_MODULE_TAG,
- .version_major = 1,
- .version_minor = 0,
- .id = COPYBIT_HARDWARE_MODULE_ID,
- .name = "QCT MSM7K COPYBIT Module",
- .author = "Google, Inc.",
- .methods = ©bit_module_methods
- }
+common: {
+tag: HARDWARE_MODULE_TAG,
+ version_major: 1,
+ version_minor: 0,
+ id: COPYBIT_HARDWARE_MODULE_ID,
+ name: "QCT MSM7K COPYBIT Module",
+ author: "Google, Inc.",
+ methods: ©bit_module_methods
+ }
};
/******************************************************************************/
@@ -131,6 +131,8 @@
static int get_format(int format) {
switch (format) {
case HAL_PIXEL_FORMAT_RGB_565: return MDP_RGB_565;
+ case HAL_PIXEL_FORMAT_RGBA_5551: return MDP_RGBA_5551;
+ case HAL_PIXEL_FORMAT_RGBA_4444: return MDP_RGBA_4444;
case HAL_PIXEL_FORMAT_RGBX_8888: return MDP_RGBX_8888;
case HAL_PIXEL_FORMAT_BGRX_8888: return MDP_BGRX_8888;
case HAL_PIXEL_FORMAT_RGB_888: return MDP_RGB_888;
@@ -144,7 +146,10 @@
case HAL_PIXEL_FORMAT_YCbCr_420_SP: return MDP_Y_CBCR_H2V2;
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: return MDP_Y_CBCR_H2V2_VENUS;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: return MDP_Y_CRCB_H2V2_VENUS;
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
+ case HAL_PIXEL_FORMAT_CbYCrY_422_I: return MDP_CBYCRY_H2V1;
+ case HAL_PIXEL_FORMAT_BGR_888: return MDP_BGR_888;
}
return -1;
}
@@ -454,6 +459,8 @@
// we don't support plane alpha with RGBA formats
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
src->format);
return -EINVAL;
diff --git a/msm8909/libcopybit/copybit.h b/msm8909/libcopybit/copybit.h
index b4af021..de585ee 100644
--- a/msm8909/libcopybit/copybit.h
+++ b/msm8909/libcopybit/copybit.h
@@ -49,6 +49,8 @@
COPYBIT_FORMAT_RGB_888 = HAL_PIXEL_FORMAT_RGB_888,
COPYBIT_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565,
COPYBIT_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888,
+ COPYBIT_FORMAT_RGBA_5551 = HAL_PIXEL_FORMAT_RGBA_5551,
+ COPYBIT_FORMAT_RGBA_4444 = HAL_PIXEL_FORMAT_RGBA_4444,
COPYBIT_FORMAT_YCbCr_422_SP = 0x10,
COPYBIT_FORMAT_YCrCb_420_SP = 0x11,
};
@@ -78,6 +80,10 @@
COPYBIT_FRAMEBUFFER_HEIGHT = 8,
COPYBIT_FG_LAYER = 9,
COPYBIT_DYNAMIC_FPS = 10,
+ /* Source Format Mode */
+ COPYBIT_SRC_FORMAT_MODE = 11,
+ /* Destination Format Mode */
+ COPYBIT_DST_FORMAT_MODE = 12,
};
/* values for copybit_set_parameter(COPYBIT_TRANSFORM) */
@@ -114,6 +120,13 @@
COPYBIT_BLENDING_COVERAGE = 0x0405
};
+enum {
+ /* Linear format mode*/
+ COPYBIT_LINEAR = 0x0000,
+ /* UBWC format mode*/
+ COPYBIT_UBWC_COMPRESSED = 0x0001,
+};
+
/* use get_static_info() to query static informations about the hardware */
enum {
/* Maximum amount of minification supported by the hardware*/
@@ -124,6 +137,8 @@
COPYBIT_SCALING_FRAC_BITS = 3,
/* Supported rotation step in degres. */
COPYBIT_ROTATION_STEP_DEG = 4,
+ /* UBWC support*/
+ COPYBIT_UBWC_SUPPORT = 5,
};
/* Image structure */
diff --git a/msm8909/libcopybit/copybit_c2d.cpp b/msm8909/libcopybit/copybit_c2d.cpp
index 4340855..63c1379 100644
--- a/msm8909/libcopybit/copybit_c2d.cpp
+++ b/msm8909/libcopybit/copybit_c2d.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are retained
* for attribution purposes only.
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include <cutils/log.h>
+#include <log/log.h>
#include <sys/resource.h>
#include <sys/prctl.h>
@@ -124,7 +124,8 @@
enum eC2DFlags {
FLAGS_PREMULTIPLIED_ALPHA = 1<<0,
FLAGS_YUV_DESTINATION = 1<<1,
- FLAGS_TEMP_SRC_DST = 1<<2
+ FLAGS_TEMP_SRC_DST = 1<<2,
+ FLAGS_UBWC_FORMAT_MODE = 1<<3
};
static gralloc::IAllocController* sAlloc = 0;
@@ -159,6 +160,8 @@
void* time_stamp;
bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
void* dst_surface_base; // Stores the dst surface addr
+ bool is_src_ubwc_format;
+ bool is_dst_ubwc_format;
// used for signaling the wait thread
bool wait_timestamp;
@@ -264,6 +267,8 @@
case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB |
C2D_FORMAT_SWAP_RB;
case HAL_PIXEL_FORMAT_BGRA_8888: return C2D_COLOR_FORMAT_8888_ARGB;
+ case HAL_PIXEL_FORMAT_RGBA_5551: return C2D_COLOR_FORMAT_5551_RGBA;
+ case HAL_PIXEL_FORMAT_RGBA_4444: return C2D_COLOR_FORMAT_4444_RGBA;
case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV12;
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV21;
@@ -348,12 +353,7 @@
if(!handle)
return 0;
- if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
- private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP))
- memtype = KGSL_USER_MEM_TYPE_PMEM;
- else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
- memtype = KGSL_USER_MEM_TYPE_ASHMEM;
- else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+ if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
memtype = KGSL_USER_MEM_TYPE_ION;
else {
ALOGE("Invalid handle flags: 0x%x", handle->flags);
@@ -402,7 +402,9 @@
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:
- case HAL_PIXEL_FORMAT_BGRA_8888: {
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444: {
return COPYBIT_SUCCESS;
}
default:
@@ -544,6 +546,10 @@
surfaceDef.format = c2d_format |
((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
+
+ surfaceDef.format = surfaceDef.format |
+ ((flags & FLAGS_UBWC_FORMAT_MODE) ? C2D_FORMAT_UBWC_COMPRESSED : 0);
+
surfaceDef.width = rhs->w;
surfaceDef.height = rhs->h;
int aligned_width = ALIGN((int)surfaceDef.width,32);
@@ -700,6 +706,8 @@
int flags = FLAGS_PREMULTIPLIED_ALPHA;
int mapped_dst_idx = -1;
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+ if (ctx->is_dst_ubwc_format)
+ flags |= FLAGS_UBWC_FORMAT_MODE;
C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
pthread_mutex_lock(&ctx->wait_cleanup_lock);
if(!ctx->dst_surface_mapped) {
@@ -865,6 +873,12 @@
case COPYBIT_BLIT_TO_FRAMEBUFFER:
// Do nothing
break;
+ case COPYBIT_SRC_FORMAT_MODE:
+ ctx->is_src_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
+ break;
+ case COPYBIT_DST_FORMAT_MODE:
+ ctx->is_dst_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
+ break;
default:
ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
status = -EINVAL;
@@ -898,6 +912,12 @@
case COPYBIT_ROTATION_STEP_DEG:
value = 1;
break;
+ case COPYBIT_UBWC_SUPPORT:
+ value = 0;
+ if (ctx->c2d_driver_info.capabilities_mask & C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP) {
+ value = 1;
+ }
+ break;
default:
ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
value = -EINVAL;
@@ -980,7 +1000,7 @@
data.size = get_size(info);
data.align = getpagesize();
data.uncached = true;
- int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
+ int allocFlags = 0;
if (sAlloc == 0) {
sAlloc = gralloc::IAllocController::getInstance();
@@ -1103,6 +1123,9 @@
}
int dst_surface_type;
+ if (ctx->is_dst_ubwc_format)
+ flags |= FLAGS_UBWC_FORMAT_MODE;
+
if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
dst_surface_type = RGB_SURFACE;
flags |= FLAGS_PREMULTIPLIED_ALPHA;
@@ -1285,6 +1308,7 @@
flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
+ flags |= (ctx->is_src_ubwc_format) ? FLAGS_UBWC_FORMAT_MODE : 0;
status = set_image(ctx, src_surface.surface_id, &src_image,
(eC2DFlags)flags, mapped_src_idx);
if(status) {
diff --git a/msm8909/libcopybit/software_converter.cpp b/msm8909/libcopybit/software_converter.cpp
index e5c03b5..1aa3ce6 100644
--- a/msm8909/libcopybit/software_converter.cpp
+++ b/msm8909/libcopybit/software_converter.cpp
@@ -27,7 +27,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <cutils/log.h>
+#include <log/log.h>
#include <stdlib.h>
#include <errno.h>
#include "software_converter.h"
diff --git a/msm8909/libcopybit/software_converter.h b/msm8909/libcopybit/software_converter.h
index 6e53e16..cc6ae34 100644
--- a/msm8909/libcopybit/software_converter.h
+++ b/msm8909/libcopybit/software_converter.h
@@ -31,11 +31,12 @@
#include <copybit.h>
#include "gralloc_priv.h"
-#include "gr.h"
#define COPYBIT_SUCCESS 0
#define COPYBIT_FAILURE -1
+#define ALIGN(x, y) (((x) + y - 1) & (~(y - 1)))
+
int convertYV12toYCrCb420SP(const copybit_image_t *src,private_handle_t *yv12_handle);
/*
diff --git a/msm8909/libdisplayconfig/Android.mk b/msm8909/libdisplayconfig/Android.mk
new file mode 100644
index 0000000..3d44444
--- /dev/null
+++ b/msm8909/libdisplayconfig/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libdisplayconfig
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_HEADER_LIBRARIES := display_headers
+LOCAL_SRC_FILES := DisplayConfig.cpp
+LOCAL_SHARED_LIBRARIES := libhidlbase libhidltransport libutils \
+ vendor.display.config@1.0
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/msm8909/libdisplayconfig/DisplayConfig.cpp b/msm8909/libdisplayconfig/DisplayConfig.cpp
new file mode 100644
index 0000000..29fcc94
--- /dev/null
+++ b/msm8909/libdisplayconfig/DisplayConfig.cpp
@@ -0,0 +1,363 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <vendor/display/config/1.0/IDisplayConfig.h>
+
+#include "DisplayConfig.h"
+
+namespace display {
+
+using vendor::display::config::V1_0::IDisplayConfig;
+
+//=============================================================================
+// The functions below run in the client process and wherever necessary
+// do a binder call to HWC to get/set data.
+
+IDisplayConfig::DisplayType MapDisplayType(int dpy) {
+ switch (dpy) {
+ case DISPLAY_PRIMARY:
+ return IDisplayConfig::DisplayType::DISPLAY_PRIMARY;
+
+ case DISPLAY_EXTERNAL:
+ return IDisplayConfig::DisplayType::DISPLAY_EXTERNAL;
+
+ case DISPLAY_VIRTUAL:
+ return IDisplayConfig::DisplayType::DISPLAY_VIRTUAL;
+
+ default:
+ break;
+ }
+
+ return IDisplayConfig::DisplayType::INVALID;
+}
+
+IDisplayConfig::DisplayExternalStatus MapExternalStatus(uint32_t status) {
+ switch (status) {
+ case EXTERNAL_OFFLINE:
+ return IDisplayConfig::DisplayExternalStatus::EXTERNAL_OFFLINE;
+
+ case EXTERNAL_ONLINE:
+ return IDisplayConfig::DisplayExternalStatus::EXTERNAL_ONLINE;
+
+ case EXTERNAL_PAUSE:
+ return IDisplayConfig::DisplayExternalStatus::EXTERNAL_PAUSE;
+
+ case EXTERNAL_RESUME:
+ return IDisplayConfig::DisplayExternalStatus::EXTERNAL_RESUME;
+
+ default:
+ break;
+ }
+
+ return IDisplayConfig::DisplayExternalStatus::INVALID;
+}
+
+IDisplayConfig::DisplayDynRefreshRateOp MapDynRefreshRateOp(uint32_t op) {
+ switch (op) {
+ case DISABLE_METADATA_DYN_REFRESH_RATE:
+ return IDisplayConfig::DisplayDynRefreshRateOp::DISABLE_METADATA_DYN_REFRESH_RATE;
+
+ case ENABLE_METADATA_DYN_REFRESH_RATE:
+ return IDisplayConfig::DisplayDynRefreshRateOp::ENABLE_METADATA_DYN_REFRESH_RATE;
+
+ case SET_BINDER_DYN_REFRESH_RATE:
+ return IDisplayConfig::DisplayDynRefreshRateOp::SET_BINDER_DYN_REFRESH_RATE;
+
+ default:
+ break;
+ }
+
+ return IDisplayConfig::DisplayDynRefreshRateOp::INVALID;
+}
+
+int MapDisplayPortType(IDisplayConfig::DisplayPortType panelType) {
+ switch (panelType) {
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DEFAULT:
+ return DISPLAY_PORT_DEFAULT;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DSI:
+ return DISPLAY_PORT_DSI;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DTV:
+ return DISPLAY_PORT_DTV;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_WRITEBACK:
+ return DISPLAY_PORT_WRITEBACK;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_LVDS:
+ return DISPLAY_PORT_LVDS;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_EDP:
+ return DISPLAY_PORT_EDP;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DP:
+ return DISPLAY_PORT_DP;
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+int isExternalConnected() {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return 0;
+ }
+
+ int connected = 0;
+ intf->isDisplayConnected(IDisplayConfig::DisplayType::DISPLAY_EXTERNAL,
+ [&](const auto &tmpError, const auto &tmpStatus) {
+ if (tmpError) {
+ return;
+ }
+
+ connected = tmpStatus;
+ });
+
+ return connected;
+}
+
+int setSecondayDisplayStatus(int dpy, uint32_t status) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setSecondayDisplayStatus(MapDisplayType(dpy), MapExternalStatus(status));
+}
+
+int configureDynRefeshRate(uint32_t op, uint32_t refreshRate) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->configureDynRefeshRate(MapDynRefreshRateOp(op), refreshRate);
+}
+
+int getConfigCount(int dpy) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ int count = 0;
+ intf->getConfigCount(MapDisplayType(dpy),
+ [&](const auto &tmpError, const auto &tmpCount) {
+ if (tmpError) {
+ return;
+ }
+
+ count = tmpCount;
+ });
+
+ return count;
+}
+
+int getActiveConfig(int dpy) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ int config = 0;
+ intf->getActiveConfig(MapDisplayType(dpy),
+ [&](const auto &tmpError, const auto &tmpConfig) {
+ if (tmpError) {
+ return;
+ }
+
+ config = tmpConfig;
+ });
+
+ return config;
+}
+
+int setActiveConfig(int dpy, uint32_t config) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setActiveConfig(MapDisplayType(dpy), config);
+}
+
+DisplayAttributes getDisplayAttributes(uint32_t configIndex, int dpy) {
+ DisplayAttributes attributes;
+
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return attributes;
+ }
+
+ intf->getDisplayAttributes(configIndex, MapDisplayType(dpy),
+ [&](const auto &tmpError, const auto &tmpAttributes) {
+ if (tmpError) {
+ return;
+ }
+
+ attributes.vsync_period = tmpAttributes.vsyncPeriod;
+ attributes.xres = tmpAttributes.xRes;
+ attributes.yres = tmpAttributes.yRes;
+ attributes.xdpi = tmpAttributes.xDpi;
+ attributes.ydpi = tmpAttributes.yDpi;
+ attributes.panel_type = MapDisplayPortType(tmpAttributes.panelType);
+ attributes.is_yuv = tmpAttributes.isYuv;
+ });
+
+ return attributes;
+}
+
+int setPanelBrightness(uint32_t level) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setPanelBrightness(level);
+}
+
+uint32_t getPanelBrightness() {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return 0;
+ }
+
+ int level = 0;
+ intf->getPanelBrightness(
+ [&](const auto &tmpError, const auto &tmpLevel) {
+ if (tmpError) {
+ return;
+ }
+
+ level = tmpLevel;
+ });
+
+ return level;
+}
+
+int minHdcpEncryptionLevelChanged(int dpy, uint32_t min_enc_level) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->minHdcpEncryptionLevelChanged(MapDisplayType(dpy), min_enc_level);
+}
+
+int refreshScreen() {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->refreshScreen();
+}
+
+int controlPartialUpdate(int dpy, bool enable) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->controlPartialUpdate(MapDisplayType(dpy), enable);
+}
+
+int toggleScreenUpdate(uint32_t on) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->toggleScreenUpdate(on == 1);
+}
+
+int setIdleTimeout(uint32_t value) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setIdleTimeout(value);
+}
+
+int getHDRCapabilities(int dpy, DisplayHDRCapabilities *caps) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL || caps == NULL) {
+ return -1;
+ }
+
+ int error = -1;
+ intf->getHDRCapabilities(MapDisplayType(dpy),
+ [&](const auto &tmpError, const auto &tmpCaps) {
+ error = tmpError;
+ if (error) {
+ return;
+ }
+
+ caps->supported_hdr_types = tmpCaps.supportedHdrTypes;
+ caps->max_luminance = tmpCaps.maxLuminance;
+ caps->max_avg_luminance = tmpCaps.maxAvgLuminance;
+ caps->min_luminance = tmpCaps.minLuminance;
+ });
+
+ return error;
+}
+
+int setCameraLaunchStatus(uint32_t on) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setCameraLaunchStatus(on);
+}
+
+bool displayBWTransactionPending() {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return 0;
+ }
+
+ int status = 0;
+ intf->displayBWTransactionPending(
+ [&](const auto &tmpError, const auto &tmpStatus) {
+ if (tmpError) {
+ return;
+ }
+
+ status = tmpStatus;
+ });
+
+ return status;
+}
+
+} // namespace display
diff --git a/msm8909/libdisplayconfig/DisplayConfig.h b/msm8909/libdisplayconfig/DisplayConfig.h
new file mode 100644
index 0000000..17b6421
--- /dev/null
+++ b/msm8909/libdisplayconfig/DisplayConfig.h
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DISPLAY_CONFIG_H__
+#define __DISPLAY_CONFIG_H__
+
+#include <stdint.h>
+#include <vector>
+
+// This header is for clients to use to set/get global display configuration.
+
+namespace display {
+
+enum {
+ DISPLAY_PRIMARY = 0,
+ DISPLAY_EXTERNAL,
+ DISPLAY_VIRTUAL,
+};
+
+enum {
+ EXTERNAL_OFFLINE = 0,
+ EXTERNAL_ONLINE,
+ EXTERNAL_PAUSE,
+ EXTERNAL_RESUME,
+};
+
+enum {
+ DISABLE_METADATA_DYN_REFRESH_RATE = 0,
+ ENABLE_METADATA_DYN_REFRESH_RATE,
+ SET_BINDER_DYN_REFRESH_RATE,
+};
+
+enum {
+ DISPLAY_PORT_DEFAULT = 0,
+ DISPLAY_PORT_DSI,
+ DISPLAY_PORT_DTV,
+ DISPLAY_PORT_WRITEBACK,
+ DISPLAY_PORT_LVDS,
+ DISPLAY_PORT_EDP,
+ DISPLAY_PORT_DP,
+};
+
+struct DisplayAttributes {
+ uint32_t vsync_period = 0; //nanoseconds
+ uint32_t xres = 0;
+ uint32_t yres = 0;
+ float xdpi = 0.0f;
+ float ydpi = 0.0f;
+ int panel_type = DISPLAY_PORT_DEFAULT;
+ bool is_yuv = false;
+};
+
+struct DisplayHDRCapabilities {
+ std::vector<int32_t> supported_hdr_types;
+ float max_luminance = 0.0f;
+ float max_avg_luminance = 0.0f;
+ float min_luminance = 0.0f;
+};
+
+//=============================================================================
+// The functions below run in the client pocess and wherever necessary
+// do a binder call to HWC to get/set data.
+
+int isExternalConnected();
+int setSecondayDisplayStatus(int dpy, uint32_t status);
+int configureDynRefeshRate(uint32_t op, uint32_t refreshRate);
+int getConfigCount(int dpy);
+int getActiveConfig(int dpy);
+int setActiveConfig(int dpy, uint32_t config);
+DisplayAttributes getDisplayAttributes(uint32_t configIndex, int dpy);
+int setPanelBrightness(uint32_t level);
+uint32_t getPanelBrightness();
+int minHdcpEncryptionLevelChanged(int dpy, uint32_t min_enc_level);
+int refreshScreen();
+int controlPartialUpdate(int dpy, bool enable);
+int toggleScreenUpdate(uint32_t on);
+int setIdleTimeout(uint32_t value);
+int getHDRCapabilities(int dpy, DisplayHDRCapabilities *caps);
+int setCameraLaunchStatus(uint32_t on);
+bool displayBWTransactionPending();
+
+} // namespace display
+
+#endif // __DISPLAY_CONFIG_H__
diff --git a/sdm845/libdrmutils/Android.mk b/msm8909/libdrmutils/Android.mk
similarity index 100%
rename from sdm845/libdrmutils/Android.mk
rename to msm8909/libdrmutils/Android.mk
diff --git a/sdm845/libdrmutils/drm_interface.h b/msm8909/libdrmutils/drm_interface.h
similarity index 87%
rename from sdm845/libdrmutils/drm_interface.h
rename to msm8909/libdrmutils/drm_interface.h
index 71767e7..4c37e8c 100644
--- a/sdm845/libdrmutils/drm_interface.h
+++ b/msm8909/libdrmutils/drm_interface.h
@@ -39,9 +39,6 @@
#include "xf86drmMode.h"
namespace sde_drm {
-
-typedef std::map<std::pair<uint32_t, uint64_t>, float> CompRatioMap;
-
/*
* Drm Atomic Operation Codes
*/
@@ -144,24 +141,6 @@
*/
CRTC_SET_OUTPUT_FENCE_OFFSET,
/*
- * Op: Sets overall SDE core clock
- * Arg: uint32_t - CRTC ID
- * uint32_t - core_clk
- */
- CRTC_SET_CORE_CLK,
- /*
- * Op: Sets overall SDE core average bandwidth
- * Arg: uint32_t - CRTC ID
- * uint32_t - core_ab
- */
- CRTC_SET_CORE_AB,
- /*
- * Op: Sets overall SDE core instantaneous bandwidth
- * Arg: uint32_t - CRTC ID
- * uint32_t - core_ib
- */
- CRTC_SET_CORE_IB,
- /*
* Op: Returns release fence for this frame. Should be called after Commit() on
* DRMAtomicReqInterface.
* Arg: uint32_t - CRTC ID
@@ -175,13 +154,6 @@
*/
CRTC_SET_POST_PROC,
/*
- * Op: Sets CRTC ROIs.
- * Arg: uint32_t - CRTC ID
- * uint32_t - number of ROIs
- * DRMRect * - Array of CRTC ROIs
- */
- CRTC_SET_ROI,
- /*
* Op: Returns retire fence for this commit. Should be called after Commit() on
* DRMAtomicReqInterface.
* Arg: uint32_t - Connector ID
@@ -200,35 +172,14 @@
* uint32_t - Framebuffer ID
*/
CONNECTOR_SET_OUTPUT_FB_ID,
- /*
- * Op: Sets power mode for connector.
- * Arg: uint32_t - Connector ID
- * uint32_t - Power Mode
- */
- CONNECTOR_SET_POWER_MODE,
- /*
- * Op: Sets panel ROIs.
- * Arg: uint32_t - Connector ID
- * uint32_t - number of ROIs
- * DRMRect * - Array of Connector ROIs
- */
- CONNECTOR_SET_ROI,
};
enum struct DRMRotation {
FLIP_H = 0x1,
FLIP_V = 0x2,
- ROT_180 = FLIP_H | FLIP_V,
ROT_90 = 0x4,
};
-enum struct DRMPowerMode {
- ON,
- DOZE,
- DOZE_SUSPEND,
- OFF,
-};
-
enum struct DRMBlendType {
UNDEFINED = 0,
OPAQUE = 1,
@@ -275,21 +226,6 @@
uint32_t max_blend_stages;
QSEEDVersion qseed_version;
SmartDMARevision smart_dma_rev;
- float ib_fudge_factor;
- float clk_fudge_factor;
- uint32_t dest_scale_prefill_lines;
- uint32_t undersized_prefill_lines;
- uint32_t macrotile_prefill_lines;
- uint32_t nv12_prefill_lines;
- uint32_t linear_prefill_lines;
- uint32_t downscale_prefill_lines;
- uint32_t extra_prefill_lines;
- uint32_t amortized_threshold;
- uint64_t max_bandwidth_low;
- uint64_t max_bandwidth_high;
- uint32_t max_sde_clk;
- CompRatioMap comp_ratio_rt_map;
- CompRatioMap comp_ratio_nrt_map;
};
enum struct DRMPlaneType {
@@ -314,7 +250,6 @@
uint32_t max_downscale;
uint32_t max_horizontal_deci;
uint32_t max_vertical_deci;
- uint64_t max_pipe_bandwidth;
};
// All DRM Planes as map<Plane_id , plane_type_info> listed from highest to lowest priority
@@ -350,16 +285,6 @@
std::vector<std::pair<uint32_t, uint64_t>> formats_supported;
// Valid only if type is DRM_MODE_CONNECTOR_VIRTUAL
uint32_t max_linewidth;
- // Valid only if mode is command
- int num_roi;
- int xstart;
- int ystart;
- int walign;
- int halign;
- int wmin;
- int hmin;
- bool roi_merge;
- DRMRotation panel_orientation;
};
/* Identifier token for a display */
@@ -476,7 +401,7 @@
* Will query post propcessing feature info of a CRTC.
* [output]: DRMPPFeatureInfo: CRTC post processing feature info
*/
- virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo &info) = 0;
+ virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo &info) = 0;
/*
* Register a logical display to receive a token.
* Each display pipeline in DRM is identified by its CRTC and Connector(s).
diff --git a/sdm845/libdrmutils/drm_lib_loader.cpp b/msm8909/libdrmutils/drm_lib_loader.cpp
similarity index 100%
rename from sdm845/libdrmutils/drm_lib_loader.cpp
rename to msm8909/libdrmutils/drm_lib_loader.cpp
diff --git a/sdm845/libdrmutils/drm_lib_loader.h b/msm8909/libdrmutils/drm_lib_loader.h
similarity index 100%
rename from sdm845/libdrmutils/drm_lib_loader.h
rename to msm8909/libdrmutils/drm_lib_loader.h
diff --git a/sdm845/libdrmutils/drm_logger.h b/msm8909/libdrmutils/drm_logger.h
similarity index 100%
rename from sdm845/libdrmutils/drm_logger.h
rename to msm8909/libdrmutils/drm_logger.h
diff --git a/sdm845/libdrmutils/drm_master.cpp b/msm8909/libdrmutils/drm_master.cpp
similarity index 100%
rename from sdm845/libdrmutils/drm_master.cpp
rename to msm8909/libdrmutils/drm_master.cpp
diff --git a/sdm845/libdrmutils/drm_master.h b/msm8909/libdrmutils/drm_master.h
similarity index 100%
rename from sdm845/libdrmutils/drm_master.h
rename to msm8909/libdrmutils/drm_master.h
diff --git a/sdm845/libdrmutils/drm_res_mgr.cpp b/msm8909/libdrmutils/drm_res_mgr.cpp
similarity index 100%
rename from sdm845/libdrmutils/drm_res_mgr.cpp
rename to msm8909/libdrmutils/drm_res_mgr.cpp
diff --git a/sdm845/libdrmutils/drm_res_mgr.h b/msm8909/libdrmutils/drm_res_mgr.h
similarity index 100%
rename from sdm845/libdrmutils/drm_res_mgr.h
rename to msm8909/libdrmutils/drm_res_mgr.h
diff --git a/msm8909/libgralloc/Android.mk b/msm8909/libgralloc/Android.mk
index b6e3a8d..86c0f04 100644
--- a/msm8909/libgralloc/Android.mk
+++ b/msm8909/libgralloc/Android.mk
@@ -18,18 +18,20 @@
include $(CLEAR_VARS)
LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) libmemalloc libqdMetaData
-LOCAL_SHARED_LIBRARIES += libqdutils libGLESv1_CM
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\"
-LOCAL_CLANG := $(common_clang_flags)
+LOCAL_HEADER_LIBRARIES := display_headers
+LOCAL_SHARED_LIBRARIES := $(common_libs) libmemalloc libqdMetaData libqdutils
+ifneq ($(TARGET_IS_HEADLESS), true)
+LOCAL_SHARED_LIBRARIES += libGLESv1_CM
+endif
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
LOCAL_SRC_FILES := gpu.cpp gralloc.cpp framebuffer.cpp mapper.cpp
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
-LOCAL_COPY_HEADERS := gralloc_priv.h gr.h
+LOCAL_COPY_HEADERS := gralloc_priv.h gr.h adreno_utils.h
include $(BUILD_SHARED_LIBRARY)
@@ -37,11 +39,12 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libmemalloc
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
+LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) libqdutils libdl
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdmemalloc\"
-LOCAL_CLANG := $(common_clang_flags)
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdmemalloc\" -Wno-sign-conversion
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
LOCAL_SRC_FILES := ionalloc.cpp alloc_controller.cpp
LOCAL_COPY_HEADERS := alloc_controller.h memalloc.h
diff --git a/sdm845/libgralloc/Makefile.am b/msm8909/libgralloc/Makefile.am
similarity index 100%
rename from sdm845/libgralloc/Makefile.am
rename to msm8909/libgralloc/Makefile.am
diff --git a/sdm845/libgralloc/adreno_utils.h b/msm8909/libgralloc/adreno_utils.h
similarity index 100%
rename from sdm845/libgralloc/adreno_utils.h
rename to msm8909/libgralloc/adreno_utils.h
diff --git a/msm8909/libgralloc/alloc_controller.cpp b/msm8909/libgralloc/alloc_controller.cpp
index c7ba7c9..d2a522e 100644
--- a/msm8909/libgralloc/alloc_controller.cpp
+++ b/msm8909/libgralloc/alloc_controller.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011 - 2017, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,74 +30,92 @@
#include <cutils/log.h>
#include <fcntl.h>
#include <dlfcn.h>
+#include <media/msm_media_info.h>
+#include <qdMetaData.h>
+#include <utils/Singleton.h>
+#include <utils/Mutex.h>
+#include <algorithm>
+
#include "gralloc_priv.h"
#include "alloc_controller.h"
#include "memalloc.h"
#include "ionalloc.h"
#include "gr.h"
-#include "comptype.h"
-#include "mdp_version.h"
-
-#ifdef VENUS_COLOR_FORMAT
-#include <media/msm_media_info.h>
-#else
-#define VENUS_Y_STRIDE(args...) 0
-#define VENUS_Y_SCANLINES(args...) 0
-#define VENUS_BUFFER_SIZE(args...) 0
-#endif
+#include "qd_utils.h"
#define ASTC_BLOCK_SIZE 16
+#ifndef ION_FLAG_CP_PIXEL
+#define ION_FLAG_CP_PIXEL 0
+#endif
+
+#ifndef ION_FLAG_ALLOW_NON_CONTIG
+#define ION_FLAG_ALLOW_NON_CONTIG 0
+#endif
+
+#ifndef ION_FLAG_CP_CAMERA_PREVIEW
+#define ION_FLAG_CP_CAMERA_PREVIEW 0
+#endif
+
+#ifdef MASTER_SIDE_CP
+#define CP_HEAP_ID ION_SECURE_HEAP_ID
+#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
+#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
+#define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA)
+#define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW)
+#else // SLAVE_SIDE_CP
+#define CP_HEAP_ID ION_CP_MM_HEAP_ID
+#define SD_HEAP_ID CP_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
+#define ION_SD_FLAGS ION_SECURE
+#define ION_SC_FLAGS ION_SECURE
+#define ION_SC_PREVIEW_FLAGS ION_SECURE
+#endif
+
+#ifndef COLOR_FMT_P010_UBWC
+#define COLOR_FMT_P010_UBWC 9
+#endif
+
using namespace gralloc;
using namespace qdutils;
+using namespace android;
ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
+ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo);
+
+static void getYuvUBwcWidthHeight(int, int, int, int&, int&);
+static unsigned int getUBwcSize(int, int, int, const int, const int);
//Common functions
-static bool canFallback(int usage, bool triedSystem)
-{
- // Fallback to system heap when alloc fails unless
- // 1. Composition type is MDP
- // 2. Alloc from system heap was already tried
- // 3. The heap type is requsted explicitly
- // 4. The heap type is protected
- // 5. The buffer is meant for external display only
-
- if(QCCompositionType::getInstance().getCompositionType() &
- COMPOSITION_TYPE_MDP)
- return false;
- if(triedSystem)
- return false;
- if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
- return false;
- if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
- return false;
- //Return true by default
- return true;
-}
/* The default policy is to return cached buffers unless the client explicity
* sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
* read or written in software. Any combination with a _RARELY_ flag will be
* treated as uncached. */
static bool useUncached(const int& usage) {
- if((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
- ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ==
- GRALLOC_USAGE_SW_WRITE_RARELY) or
- ((usage & GRALLOC_USAGE_SW_READ_MASK) ==
- GRALLOC_USAGE_SW_READ_RARELY))
+ if ((usage & GRALLOC_USAGE_PROTECTED) or
+ (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
+ ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
+ ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY))
return true;
return false;
}
-//-------------- AdrenoMemInfo-----------------------//
+//------------- MDPCapabilityInfo-----------------------//
+MDPCapabilityInfo :: MDPCapabilityInfo() {
+ qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
+ qdutils::querySDEInfo(HAS_WB_UBWC, &isWBUBWCSupported);
+}
+
+//------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo::AdrenoMemInfo()
{
LINK_adreno_compute_aligned_width_and_height = NULL;
LINK_adreno_compute_padding = NULL;
- LINK_adreno_isMacroTilingSupportedByGpu = NULL;
LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
+ LINK_adreno_isUBWCSupportedByGpu = NULL;
LINK_adreno_get_gpu_pixel_alignment = NULL;
libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
@@ -106,14 +124,24 @@
::dlsym(libadreno_utils, "compute_aligned_width_and_height");
*(void **)&LINK_adreno_compute_padding =
::dlsym(libadreno_utils, "compute_surface_padding");
- *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
- ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
*(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
::dlsym(libadreno_utils,
"compute_compressedfmt_aligned_width_and_height");
+ *(void **)&LINK_adreno_isUBWCSupportedByGpu =
+ ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
*(void **)&LINK_adreno_get_gpu_pixel_alignment =
::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
}
+
+ // Check if the overriding property debug.gralloc.gfx_ubwc_disable
+ // that disables UBWC allocations for the graphics stack is set
+ gfx_ubwc_disable = 0;
+ char property[PROPERTY_VALUE_MAX];
+ property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
+ if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
+ !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
+ gfx_ubwc_disable = 1;
+ }
}
AdrenoMemInfo::~AdrenoMemInfo()
@@ -123,78 +151,115 @@
}
}
-int AdrenoMemInfo::isMacroTilingSupportedByGPU()
-{
- if ((libadreno_utils)) {
- if(LINK_adreno_isMacroTilingSupportedByGpu) {
- return LINK_adreno_isMacroTilingSupportedByGpu();
+void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
+ int& aligned_h) {
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+ if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+ int w = metadata->bufferDim.sliceWidth;
+ int h = metadata->bufferDim.sliceHeight;
+ int f = hnd->format;
+ int usage = 0;
+
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+ usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
}
+
+ getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h);
+ } else {
+ aligned_w = hnd->width;
+ aligned_h = hnd->height;
}
- return 0;
+
}
+void AdrenoMemInfo::getUnalignedWidthAndHeight(const private_handle_t *hnd, int& unaligned_w,
+ int& unaligned_h) {
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+ if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+ unaligned_w = metadata->bufferDim.sliceWidth;
+ unaligned_h = metadata->bufferDim.sliceHeight;
+ } else {
+ unaligned_w = hnd->unaligned_width;
+ unaligned_h = hnd->unaligned_height;
+ }
+}
+
+bool isUncompressedRgbFormat(int format)
+{
+ bool is_rgb_format = false;
+
+ switch (format)
+ {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGB_888:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_BGR_565:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ case HAL_PIXEL_FORMAT_R_8:
+ case HAL_PIXEL_FORMAT_RG_88:
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ case HAL_PIXEL_FORMAT_BGR_888:
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ case HAL_PIXEL_FORMAT_ARGB_2101010:
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ case HAL_PIXEL_FORMAT_XRGB_2101010:
+ case HAL_PIXEL_FORMAT_BGRA_1010102:
+ case HAL_PIXEL_FORMAT_ABGR_2101010:
+ case HAL_PIXEL_FORMAT_BGRX_1010102:
+ case HAL_PIXEL_FORMAT_XBGR_2101010: // Intentional fallthrough
+ is_rgb_format = true;
+ break;
+ default:
+ break;
+ }
+
+ return is_rgb_format;
+}
void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
- int tile_enabled, int& aligned_w, int& aligned_h)
+ int usage, int& aligned_w, int& aligned_h)
{
- aligned_w = width;
- aligned_h = height;
+ bool ubwc_enabled = isUBwcEnabled(format, usage);
+
// Currently surface padding is only computed for RGB* surfaces.
- if (format <= HAL_PIXEL_FORMAT_BGRA_8888) {
- aligned_w = ALIGN(width, 32);
- aligned_h = ALIGN(height, 32);
-
- int bpp = 4;
- switch(format)
- {
- case HAL_PIXEL_FORMAT_RGBA_FP16:
- bpp = 8;
- break;
- case HAL_PIXEL_FORMAT_RGB_888:
- bpp = 3;
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- bpp = 2;
- break;
- default: break;
- }
- if (libadreno_utils) {
- int raster_mode = 0; // Adreno unknown raster mode.
- int padding_threshold = 512; // Threshold for padding surfaces.
- // the function below computes aligned width and aligned height
- // based on linear or macro tile mode selected.
- if(LINK_adreno_compute_aligned_width_and_height) {
- LINK_adreno_compute_aligned_width_and_height(width,
- height, bpp, tile_enabled,
- raster_mode, padding_threshold,
- &aligned_w, &aligned_h);
-
- } else if(LINK_adreno_compute_padding) {
- int surface_tile_height = 1; // Linear surface
- aligned_w = LINK_adreno_compute_padding(width, bpp,
- surface_tile_height, raster_mode,
- padding_threshold);
- ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
- __FUNCTION__);
- } else {
- ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
- "compute_aligned_width_and_height not found", __FUNCTION__);
- }
- }
+ if (isUncompressedRgbFormat(format) == true) {
+ int tileEnabled = ubwc_enabled;
+ getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h);
+ } else if (ubwc_enabled) {
+ getYuvUBwcWidthHeight(width, height, format, aligned_w, aligned_h);
} else {
+ aligned_w = width;
+ aligned_h = height;
int alignment = 32;
switch (format)
{
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
if (LINK_adreno_get_gpu_pixel_alignment) {
- alignment = LINK_adreno_get_gpu_pixel_alignment();
+ alignment = LINK_adreno_get_gpu_pixel_alignment();
}
aligned_w = ALIGN(width, alignment);
break;
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
aligned_w = ALIGN(width, alignment);
break;
+ case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
+ case HAL_PIXEL_FORMAT_Y8:
+ aligned_w = ALIGN(width, 16);
+ break;
+ case HAL_PIXEL_FORMAT_RAW12:
+ aligned_w = ALIGN(width * 12 / 8, 8);
+ break;
+ case HAL_PIXEL_FORMAT_RAW10:
+ aligned_w = ALIGN(width * 10 / 8, 8);
+ break;
+ case HAL_PIXEL_FORMAT_RAW8:
+ aligned_w = ALIGN(width, 8);
+ break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
aligned_w = ALIGN(width, 128);
break;
@@ -203,6 +268,8 @@
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ case HAL_PIXEL_FORMAT_CbYCrY_422_I:
aligned_w = ALIGN(width, 16);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
@@ -210,7 +277,12 @@
aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width);
+ aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height);
+ break;
case HAL_PIXEL_FORMAT_BLOB:
+ case HAL_PIXEL_FORMAT_RAW_OPAQUE:
break;
case HAL_PIXEL_FORMAT_NV21_ZSL:
aligned_w = ALIGN(width, 64);
@@ -253,7 +325,6 @@
LINK_adreno_compute_compressedfmt_aligned_width_and_height(
width, height, format, 0,raster_mode, padding_threshold,
&aligned_w, &aligned_h, &bytesPerPixel);
-
} else {
ALOGW("%s: Warning!! Symbols" \
" compute_compressedfmt_aligned_width_and_height" \
@@ -265,6 +336,106 @@
}
}
+void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
+ int tile_enabled, int& aligned_w, int& aligned_h)
+{
+ aligned_w = ALIGN(width, 32);
+ aligned_h = ALIGN(height, 32);
+
+ // Don't add any additional padding if debug.gralloc.map_fb_memory
+ // is enabled
+ char property[PROPERTY_VALUE_MAX];
+ if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+ (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+ (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+ return;
+ }
+
+ int bpp = 4;
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_RGB_888:
+ bpp = 3;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_BGR_565:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ bpp = 2;
+ break;
+ default: break;
+ }
+
+ if (libadreno_utils) {
+ int raster_mode = 0; // Adreno unknown raster mode.
+ int padding_threshold = 512; // Threshold for padding surfaces.
+ // the function below computes aligned width and aligned height
+ // based on linear or macro tile mode selected.
+ if(LINK_adreno_compute_aligned_width_and_height) {
+ LINK_adreno_compute_aligned_width_and_height(width,
+ height, bpp, tile_enabled,
+ raster_mode, padding_threshold,
+ &aligned_w, &aligned_h);
+
+ } else if(LINK_adreno_compute_padding) {
+ int surface_tile_height = 1; // Linear surface
+ aligned_w = LINK_adreno_compute_padding(width, bpp,
+ surface_tile_height, raster_mode,
+ padding_threshold);
+ ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
+ __FUNCTION__);
+ } else {
+ ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
+ "compute_aligned_width_and_height not found", __FUNCTION__);
+ }
+ }
+}
+
+int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
+{
+ if (!gfx_ubwc_disable && libadreno_utils) {
+ if (LINK_adreno_isUBWCSupportedByGpu) {
+ ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
+ return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
+ }
+ }
+ return 0;
+}
+
+ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
+{
+ switch (hal_format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return ADRENO_PIXELFORMAT_R8G8B8A8;
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ return ADRENO_PIXELFORMAT_R8G8B8X8;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return ADRENO_PIXELFORMAT_B5G6R5;
+ case HAL_PIXEL_FORMAT_BGR_565:
+ return ADRENO_PIXELFORMAT_R5G6B5;
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ return ADRENO_PIXELFORMAT_NV12;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ return ADRENO_PIXELFORMAT_NV12_EXT;
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ return ADRENO_PIXELFORMAT_TP10;
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+ return ADRENO_PIXELFORMAT_P010;
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
+ case HAL_PIXEL_FORMAT_ABGR_2101010:
+ return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
+ default:
+ ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
+ break;
+ }
+ return ADRENO_PIXELFORMAT_UNKNOWN;
+}
+
//-------------- IAllocController-----------------------//
IAllocController* IAllocController::sController = NULL;
IAllocController* IAllocController::getInstance(void)
@@ -280,6 +451,10 @@
IonController::IonController()
{
allocateIonMem();
+
+ char property[PROPERTY_VALUE_MAX];
+ property_get("video.disable.ubwc", property, "0");
+ mDisableUBWCForEncode = atoi(property);
}
void IonController::allocateIonMem()
@@ -290,68 +465,59 @@
int IonController::allocate(alloc_data& data, int usage)
{
int ionFlags = 0;
+ int ionHeapId = 0;
int ret;
data.uncached = useUncached(usage);
data.allocType = 0;
- if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
- ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
-
- if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
- ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
-
- if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
- ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
-
if(usage & GRALLOC_USAGE_PROTECTED) {
- if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
- ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
- ionFlags |= ION_SECURE;
+ if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+ ionHeapId = ION_HEAP(SD_HEAP_ID);
+ /*
+ * There is currently no flag in ION for Secure Display
+ * VM. Please add it to the define once available.
+ */
+ ionFlags |= ION_SD_FLAGS;
+ } else if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
+ ionHeapId = ION_HEAP(SD_HEAP_ID);
+ ionFlags |= (usage & GRALLOC_USAGE_HW_COMPOSER) ? ION_SC_PREVIEW_FLAGS : ION_SC_FLAGS;
} else {
- // for targets/OEMs which do not need HW level protection
- // do not set ion secure flag & MM heap. Fallback to IOMMU heap.
- ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
+ ionHeapId = ION_HEAP(CP_HEAP_ID);
+ ionFlags |= ION_CP_FLAGS;
}
} else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
//MM Heap is exclusively a secure heap.
//If it is used for non secure cases, fallback to IOMMU heap
ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
cannot be used as an insecure heap!\
- trying to use IOMMU instead !!");
- ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
+ trying to use system heap instead !!");
+ ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
}
if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
- ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
+ ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID);
if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
- ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
+ ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID);
if(ionFlags & ION_SECURE)
data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
- // if no flags are set, default to
- // SF + IOMMU heaps, so that bypass can work
- // we can fall back to system heap if
- // we run out.
- if(!ionFlags)
- ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
+ // if no ion heap flags are set, default to system heap
+ if(!ionHeapId)
+ ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID);
+ //At this point we should have the right heap set, there is no fallback
data.flags = ionFlags;
+ data.heapId = ionHeapId;
ret = mIonAlloc->alloc_buffer(data);
- // Fallback
- if(ret < 0 && canFallback(usage,
- (ionFlags & ION_SYSTEM_HEAP_ID)))
- {
- ALOGW("Falling back to system heap");
- data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
- ret = mIonAlloc->alloc_buffer(data);
- }
-
if(ret >= 0 ) {
data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
+ } else {
+ ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x",
+ __FUNCTION__, ionHeapId, ionFlags);
}
return ret;
@@ -369,61 +535,50 @@
return memalloc;
}
-bool isMacroTileEnabled(int format, int usage)
-{
- bool tileEnabled = false;
-
- // Check whether GPU & MDSS supports MacroTiling feature
- if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
- qdutils::MDPVersion::getInstance().supportsMacroTile())
- {
- // check the format
- switch(format)
- {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGBX_8888:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- case HAL_PIXEL_FORMAT_RGB_565:
- {
- tileEnabled = true;
- // check the usage flags
- if (usage & (GRALLOC_USAGE_SW_READ_MASK |
- GRALLOC_USAGE_SW_WRITE_MASK)) {
- // Application intends to use CPU for rendering
- tileEnabled = false;
- }
- break;
- }
- default:
- break;
- }
- }
- return tileEnabled;
-}
-
// helper function
-unsigned int getSize(int format, int width, int height, const int alignedw,
- const int alignedh) {
- unsigned int size = 0;
+unsigned int getSize(int format, int width, int height, int usage,
+ const int alignedw, const int alignedh) {
+ if (isUBwcEnabled(format, usage)) {
+ return getUBwcSize(width, height, format, alignedw, alignedh);
+ }
+
+ unsigned int size = 0;
switch (format) {
- case HAL_PIXEL_FORMAT_RGBA_FP16:
- size = alignedw * alignedh * 8;
- break;
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGBA_1010102:
+ case HAL_PIXEL_FORMAT_ARGB_2101010:
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ case HAL_PIXEL_FORMAT_XRGB_2101010:
+ case HAL_PIXEL_FORMAT_BGRA_1010102:
+ case HAL_PIXEL_FORMAT_ABGR_2101010:
+ case HAL_PIXEL_FORMAT_BGRX_1010102:
+ case HAL_PIXEL_FORMAT_XBGR_2101010:
size = alignedw * alignedh * 4;
break;
case HAL_PIXEL_FORMAT_RGB_888:
size = alignedw * alignedh * 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_BGR_565:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
size = alignedw * alignedh * 2;
break;
-
+ case HAL_PIXEL_FORMAT_RAW12:
+ size = ALIGN(alignedw * alignedh, 4096);
+ break;
+ case HAL_PIXEL_FORMAT_RAW10:
+ size = ALIGN(alignedw * alignedh, 4096);
+ break;
+ case HAL_PIXEL_FORMAT_RAW8:
+ case HAL_PIXEL_FORMAT_Y8:
+ size = alignedw * alignedh;
+ break;
// adreno formats
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
size = ALIGN(alignedw*alignedh, 4096);
@@ -449,10 +604,14 @@
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, 4096);
+ break;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
+ case HAL_PIXEL_FORMAT_CbYCrY_422_I:
if(width & 1) {
ALOGE("width is odd for the YUV422_SP format");
return 0;
@@ -463,7 +622,11 @@
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
+ break;
case HAL_PIXEL_FORMAT_BLOB:
+ case HAL_PIXEL_FORMAT_RAW_OPAQUE:
if(height != 1) {
ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
must have height==1 ", __FUNCTION__);
@@ -519,11 +682,11 @@
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
height,
format,
- false,
+ 0,
alignedw,
alignedh);
- size = getSize(format, width, height, alignedw, alignedh);
+ size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
return size;
}
@@ -533,91 +696,166 @@
int usage, int& alignedw, int &alignedh)
{
unsigned int size;
- int tileEnabled = isMacroTileEnabled(format, usage);
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
height,
format,
- tileEnabled,
+ usage,
alignedw,
alignedh);
- size = getSize(format, width, height, alignedw, alignedh);
+ size = getSize(format, width, height, usage, alignedw, alignedh);
return size;
}
-
-void getBufferAttributes(int width, int height, int format, int usage,
- int& alignedw, int &alignedh, int& tileEnabled, unsigned int& size)
+void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int height,
+ int color_format, struct android_ycbcr* ycbcr)
{
- tileEnabled = isMacroTileEnabled(format, usage);
+ // UBWC buffer has these 4 planes in the following sequence:
+ // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
+ unsigned int y_meta_stride, y_meta_height, y_meta_size;
+ unsigned int y_stride, y_height, y_size;
+ unsigned int c_meta_stride, c_meta_height, c_meta_size;
+ unsigned int alignment = 4096;
- AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
- height,
- format,
- tileEnabled,
- alignedw,
- alignedh);
- size = getSize(format, width, height, alignedw, alignedh);
+ y_meta_stride = VENUS_Y_META_STRIDE(color_format, width);
+ y_meta_height = VENUS_Y_META_SCANLINES(color_format, height);
+ y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
+
+ y_stride = VENUS_Y_STRIDE(color_format, width);
+ y_height = VENUS_Y_SCANLINES(color_format, height);
+ y_size = ALIGN((y_stride * y_height), alignment);
+
+ c_meta_stride = VENUS_UV_META_STRIDE(color_format, width);
+ c_meta_height = VENUS_UV_META_SCANLINES(color_format, height);
+ c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
+
+ ycbcr->y = (void*)(base + y_meta_size);
+ ycbcr->cb = (void*)(base + y_meta_size + y_size + c_meta_size);
+ ycbcr->cr = (void*)(base + y_meta_size + y_size +
+ c_meta_size + 1);
+ ycbcr->ystride = y_stride;
+ ycbcr->cstride = VENUS_UV_STRIDE(color_format, width);
+}
+
+void getYuvSPPlaneInfo(uint64_t base, int width, int height, int bpp,
+ struct android_ycbcr* ycbcr)
+{
+ unsigned int ystride, cstride;
+
+ ystride = cstride = width * bpp;
+ ycbcr->y = (void*)base;
+ ycbcr->cb = (void*)(base + ystride * height);
+ ycbcr->cr = (void*)(base + ystride * height + 1);
+ ycbcr->ystride = ystride;
+ ycbcr->cstride = cstride;
+ ycbcr->chroma_step = 2 * bpp;
}
int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
{
int err = 0;
+ int width = hnd->width;
+ int height = hnd->height;
+ int format = hnd->format;
+
unsigned int ystride, cstride;
+
memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+
+ // Check if UBWC buffer has been rendered in linear format.
+ if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+ format = metadata->linearFormat;
+ }
+
+ // Check metadata if the geometry has been updated.
+ if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+ int usage = 0;
+
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+ usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ }
+
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
+ metadata->bufferDim.sliceHeight, format, usage, width, height);
+ }
// Get the chroma offsets from the handle width/height. We take advantage
// of the fact the width _is_ the stride
- switch (hnd->format) {
+ switch (format) {
//Semiplanar
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
- ystride = cstride = hnd->width;
- ycbcr->y = (void*)hnd->base;
- ycbcr->cb = (void*)(hnd->base + ystride * hnd->height);
- ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1);
- ycbcr->ystride = ystride;
- ycbcr->cstride = cstride;
+ getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ getYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ getYuvUbwcSPPlaneInfo(hnd->base, width, height,
+ COLOR_FMT_NV12_UBWC, ycbcr);
ycbcr->chroma_step = 2;
break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ getYuvUbwcSPPlaneInfo(hnd->base, width, height,
+ COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
+ ycbcr->chroma_step = 3;
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+ getYuvUbwcSPPlaneInfo(hnd->base, width, height,
+ COLOR_FMT_P010_UBWC, ycbcr);
+ ycbcr->chroma_step = 4;
+ break;
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV21_ZSL:
- ystride = cstride = hnd->width;
- ycbcr->y = (void*)hnd->base;
- ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
- ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
- ycbcr->ystride = ystride;
- ycbcr->cstride = cstride;
- ycbcr->chroma_step = 2;
+ case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
+ case HAL_PIXEL_FORMAT_RAW12:
+ case HAL_PIXEL_FORMAT_RAW10:
+ case HAL_PIXEL_FORMAT_RAW8:
+ case HAL_PIXEL_FORMAT_Y8:
+ getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
+ std::swap(ycbcr->cb, ycbcr->cr);
break;
//Planar
case HAL_PIXEL_FORMAT_YV12:
- ystride = hnd->width;
- cstride = ALIGN(hnd->width/2, 16);
+ ystride = width;
+ cstride = ALIGN(width/2, 16);
ycbcr->y = (void*)hnd->base;
- ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
- ycbcr->cb = (void*)(hnd->base + ystride * hnd->height +
- cstride * hnd->height/2);
+ ycbcr->cr = (void*)(hnd->base + ystride * height);
+ ycbcr->cb = (void*)(hnd->base + ystride * height +
+ cstride * height/2);
ycbcr->ystride = ystride;
ycbcr->cstride = cstride;
ycbcr->chroma_step = 1;
-
+ break;
+ case HAL_PIXEL_FORMAT_CbYCrY_422_I:
+ ystride = width * 2;
+ cstride = 0;
+ ycbcr->y = (void*)hnd->base;
+ ycbcr->cr = NULL;
+ ycbcr->cb = NULL;
+ ycbcr->ystride = ystride;
+ ycbcr->cstride = 0;
+ ycbcr->chroma_step = 0;
break;
//Unsupported formats
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
default:
- ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
- hnd->format);
+ ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
err = -EINVAL;
}
return err;
@@ -651,9 +889,13 @@
return -ENOMEM;
}
+ if(isUBwcEnabled(format, usage)) {
+ data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ }
+
private_handle_t* hnd = new private_handle_t(data.fd, data.size,
data.allocType, 0, format,
- alignedw, alignedh);
+ alignedw, alignedh, -1, 0, 0, w, h);
hnd->base = (uint64_t) data.base;
hnd->offset = data.offset;
hnd->gpuaddr = 0;
@@ -673,3 +915,309 @@
delete hnd;
}
+
+// UBWC helper functions
+static bool isUBwcFormat(int format)
+{
+ // Explicitly defined UBWC formats
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool isUBwcSupported(int format)
+{
+ if (MDPCapabilityInfo::getInstance().isUBwcSupportedByMDP()) {
+ // Existing HAL formats with UBWC support
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_BGR_565:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ return true;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+bool isUBwcEnabled(int format, int usage)
+{
+ // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
+ if (isUBwcFormat(format))
+ return true;
+
+ if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
+ gralloc::IAllocController::getInstance()->isDisableUBWCForEncoder()) {
+ return false;
+ }
+
+ // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
+ // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
+ // usage flag and MDP supports the format.
+ if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) {
+ bool enable = true;
+ // Query GPU for UBWC only if buffer is intended to be used by GPU.
+ if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) {
+ enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format);
+ }
+ // Allow UBWC, only if CPU usage flags are not set
+ if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK |
+ GRALLOC_USAGE_SW_WRITE_MASK))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static void getYuvUBwcWidthHeight(int width, int height, int format,
+ int& aligned_w, int& aligned_h)
+{
+ switch (format)
+ {
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
+ aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ // The macro returns the stride which is 4/3 times the width, hence * 3/4
+ aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
+ aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+ // The macro returns the stride which is 2 times the width, hence / 2
+ aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
+ aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
+ break;
+ default:
+ ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+ aligned_w = 0;
+ aligned_h = 0;
+ break;
+ }
+}
+
+static void getRgbUBwcBlockSize(int bpp, int& block_width, int& block_height)
+{
+ block_width = 0;
+ block_height = 0;
+
+ switch(bpp)
+ {
+ case 2:
+ case 4:
+ block_width = 16;
+ block_height = 4;
+ break;
+ case 8:
+ block_width = 8;
+ block_height = 4;
+ break;
+ case 16:
+ block_width = 4;
+ block_height = 4;
+ break;
+ default:
+ ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+ break;
+ }
+}
+
+static unsigned int getRgbUBwcMetaBufferSize(int width, int height, int bpp)
+{
+ unsigned int size = 0;
+ int meta_width, meta_height;
+ int block_width, block_height;
+
+ getRgbUBwcBlockSize(bpp, block_width, block_height);
+
+ if (!block_width || !block_height) {
+ ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+ return size;
+ }
+
+ // Align meta buffer height to 16 blocks
+ meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
+
+ // Align meta buffer width to 64 blocks
+ meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
+
+ // Align meta buffer size to 4K
+ size = ALIGN((meta_width * meta_height), 4096);
+ return size;
+}
+
+static unsigned int getUBwcSize(int width, int height, int format,
+ const int alignedw, const int alignedh) {
+
+ unsigned int size = 0;
+ switch (format) {
+ case HAL_PIXEL_FORMAT_BGR_565:
+ size = alignedw * alignedh * 2;
+ size += getRgbUBwcMetaBufferSize(width, height, 2);
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ size = alignedw * alignedh * 4;
+ size += getRgbUBwcMetaBufferSize(width, height, 4);
+ break;
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+ size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
+ break;
+ default:
+ ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+ break;
+ }
+ return size;
+}
+
+int getRgbDataAddress(private_handle_t* hnd, void** rgb_data)
+{
+ int err = 0;
+
+ // This api is for RGB* formats
+ if (!isUncompressedRgbFormat(hnd->format)) {
+ return -EINVAL;
+ }
+
+ // linear buffer
+ if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
+ *rgb_data = (void*)hnd->base;
+ return err;
+ }
+
+ // Ubwc buffers
+ unsigned int meta_size = 0;
+ switch (hnd->format) {
+ case HAL_PIXEL_FORMAT_BGR_565:
+ meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 2);
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 4);
+ break;
+ default:
+ ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
+ err = -EINVAL;
+ break;
+ }
+
+ *rgb_data = (void*)(hnd->base + meta_size);
+ return err;
+}
+
+int getBufferLayout(private_handle_t *hnd, uint32_t stride[4],
+ uint32_t offset[4], uint32_t *num_planes) {
+ if (!hnd || !stride || !offset || !num_planes) {
+ return -EINVAL;
+ }
+
+ struct android_ycbcr yuvInfo = {};
+ *num_planes = 1;
+ stride[0] = 0;
+
+ switch (hnd->format) {
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_BGR_565:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ stride[0] = hnd->width * 2;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ stride[0] = hnd->width * 3;
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ case HAL_PIXEL_FORMAT_ARGB_2101010:
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ case HAL_PIXEL_FORMAT_XRGB_2101010:
+ case HAL_PIXEL_FORMAT_BGRA_1010102:
+ case HAL_PIXEL_FORMAT_ABGR_2101010:
+ case HAL_PIXEL_FORMAT_BGRX_1010102:
+ case HAL_PIXEL_FORMAT_XBGR_2101010:
+ stride[0] = hnd->width * 4;
+ break;
+ }
+
+ // Format is RGB
+ if (stride[0]) {
+ return 0;
+ }
+
+ (*num_planes)++;
+ int ret = getYUVPlaneInfo(hnd, &yuvInfo);
+ if (ret < 0) {
+ ALOGE("%s failed", __FUNCTION__);
+ return ret;
+ }
+
+ stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
+ offset[0] = static_cast<uint32_t>(
+ reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
+ stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
+ switch (hnd->format) {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+ offset[1] = static_cast<uint32_t>(
+ reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ offset[1] = static_cast<uint32_t>(
+ reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
+ break;
+ case HAL_PIXEL_FORMAT_YV12:
+ offset[1] = static_cast<uint32_t>(
+ reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
+ stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
+ offset[2] = static_cast<uint32_t>(
+ reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
+ (*num_planes)++;
+ break;
+ default:
+ ALOGW("%s: Unsupported format %s", __FUNCTION__,
+ qdutils::GetHALPixelFormatString(hnd->format));
+ ret = -EINVAL;
+ }
+
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+ std::fill(offset, offset + 4, 0);
+ }
+
+ return 0;
+}
diff --git a/msm8909/libgralloc/alloc_controller.h b/msm8909/libgralloc/alloc_controller.h
index f0b8ed9..45977e2 100644
--- a/msm8909/libgralloc/alloc_controller.h
+++ b/msm8909/libgralloc/alloc_controller.h
@@ -29,6 +29,17 @@
#ifndef GRALLOC_ALLOCCONTROLLER_H
#define GRALLOC_ALLOCCONTROLLER_H
+#define SZ_2M 0x200000
+#define SZ_1M 0x100000
+#define SZ_4K 0x1000
+
+/* TODO: Move this to the common makefile */
+#ifdef MASTER_SIDE_CP
+#define SECURE_ALIGN SZ_4K
+#else
+#define SECURE_ALIGN SZ_1M
+#endif
+
namespace gralloc {
struct alloc_data;
@@ -45,6 +56,8 @@
virtual IMemAlloc* getAllocator(int flags) = 0;
+ virtual bool isDisableUBWCForEncoder() = 0;
+
virtual ~IAllocController() {};
static IAllocController* getInstance(void);
@@ -61,10 +74,15 @@
virtual IMemAlloc* getAllocator(int flags);
+ virtual bool isDisableUBWCForEncoder() {
+ return mDisableUBWCForEncode;
+ }
+
IonController();
private:
IonAlloc* mIonAlloc;
+ bool mDisableUBWCForEncode;
void allocateIonMem();
};
diff --git a/msm8909/libgralloc/framebuffer.cpp b/msm8909/libgralloc/framebuffer.cpp
index b0a9a1e..dd4842f 100644
--- a/msm8909/libgralloc/framebuffer.cpp
+++ b/msm8909/libgralloc/framebuffer.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2014,2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2014 The Linux Foundation. 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.
@@ -34,7 +34,9 @@
#include <linux/fb.h>
#include <linux/msm_mdp.h>
+#ifndef TARGET_HEADLESS
#include <GLES/gl.h>
+#endif
#include "gralloc_priv.h"
#include "fb_priv.h"
@@ -57,7 +59,6 @@
static int fb_setSwapInterval(struct framebuffer_device_t* dev,
int interval)
{
-#ifdef DEBUG_SWAPINTERVAL
//XXX: Get the value here and implement along with
//single vsync in HWC
char pval[PROPERTY_VALUE_MAX];
@@ -65,7 +66,6 @@
int property_interval = atoi(pval);
if (property_interval >= 0)
interval = property_interval;
-#endif
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
@@ -101,7 +101,9 @@
if(!dev) {
return -1;
}
+#ifndef TARGET_HEADLESS
glFinish();
+#endif
return 0;
}
diff --git a/msm8909/libgralloc/gpu.cpp b/msm8909/libgralloc/gpu.cpp
index b95077f..c57ff90 100644
--- a/msm8909/libgralloc/gpu.cpp
+++ b/msm8909/libgralloc/gpu.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014,2017 The Linux Foundation. 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.
@@ -20,17 +20,17 @@
#include <fcntl.h>
#include <cutils/properties.h>
#include <sys/mman.h>
+#include <linux/msm_ion.h>
+#include <qdMetaData.h>
+#include <algorithm>
#include "gr.h"
#include "gpu.h"
#include "memalloc.h"
#include "alloc_controller.h"
-#include <qdMetaData.h>
using namespace gralloc;
-#define SZ_1M 0x100000
-
gpu_context_t::gpu_context_t(const private_module_t* module,
IAllocController* alloc_ctrl ) :
mAllocCtrl(alloc_ctrl)
@@ -54,6 +54,16 @@
{
int err = 0;
int flags = 0;
+ int alignedw = 0;
+ int alignedh = 0;
+
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height,
+ format,
+ usage,
+ alignedw,
+ alignedh);
+
size = roundUpToPageSize(size);
alloc_data data;
data.offset = 0;
@@ -64,14 +74,16 @@
else
data.align = getpagesize();
- /* force 1MB alignment selectively for secure buffers, MDP5 onwards */
-#ifdef MDSS_TARGET
- if ((usage & GRALLOC_USAGE_PROTECTED) &&
- (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)) {
- data.align = ALIGN((int) data.align, SZ_1M);
+ if (usage & GRALLOC_USAGE_PROTECTED) {
+ if ((usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) ||
+ (usage & GRALLOC_USAGE_HW_CAMERA_MASK)) {
+ /* The alignment here reflects qsee mmu V7L/V8L requirement */
+ data.align = SZ_2M;
+ } else {
+ data.align = SECURE_ALIGN;
+ }
size = ALIGN(size, data.align);
}
-#endif
data.size = size;
data.pHandle = (uintptr_t) pHandle;
@@ -86,7 +98,7 @@
eData.size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
eData.pHandle = data.pHandle;
eData.align = getpagesize();
- int eDataUsage = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
+ int eDataUsage = 0;
int eDataErr = mAllocCtrl->allocate(eData, eDataUsage);
ALOGE_IF(eDataErr, "gralloc failed for eDataErr=%s",
strerror(-eDataErr));
@@ -94,36 +106,11 @@
if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) {
flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
}
+
if (usage & GRALLOC_USAGE_PRIVATE_INTERNAL_ONLY) {
flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
}
- ColorSpace_t colorSpace = ITU_R_601;
- flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
- if (bufferType == BUFFER_TYPE_VIDEO) {
- if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
-#ifndef MDSS_TARGET
- colorSpace = ITU_R_601_FR;
- flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
-#else
- // Per the camera spec ITU 709 format should be set only for
- // video encoding.
- // It should be set to ITU 601 full range format for any other
- // camera buffer
- //
- if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
- if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
- flags |= private_handle_t::PRIV_FLAGS_ITU_R_709;
- colorSpace = ITU_R_709;
- } else {
- flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
- colorSpace = ITU_R_601_FR;
- }
- }
-#endif
- }
- }
-
if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) {
flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
}
@@ -148,8 +135,8 @@
flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
}
- if(isMacroTileEnabled(format, usage)) {
- flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
+ if (isUBwcEnabled(format, usage)) {
+ flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
}
if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
@@ -163,6 +150,10 @@
flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
}
+ if(usage & GRALLOC_USAGE_HW_COMPOSER) {
+ flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
+ }
+
if(false == data.uncached) {
flags |= private_handle_t::PRIV_FLAGS_CACHED;
}
@@ -170,19 +161,18 @@
flags |= data.allocType;
uint64_t eBaseAddr = (uint64_t)(eData.base) + eData.offset;
private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
- bufferType, format, width, height, eData.fd, eData.offset,
- eBaseAddr);
+ bufferType, format, alignedw, alignedh,
+ eData.fd, eData.offset, eBaseAddr, width, height);
hnd->offset = data.offset;
hnd->base = (uint64_t)(data.base) + data.offset;
hnd->gpuaddr = 0;
+ ColorSpace_t colorSpace = ITU_R_601;
setMetaData(hnd, UPDATE_COLOR_SPACE, (void*) &colorSpace);
-
*pHandle = hnd;
}
ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
-
return err;
}
@@ -191,12 +181,9 @@
{
*bufferType = BUFFER_TYPE_VIDEO;
- if (inputFormat <= HAL_PIXEL_FORMAT_BGRA_8888) {
+ if (isUncompressedRgbFormat(inputFormat) == TRUE) {
// RGB formats
*bufferType = BUFFER_TYPE_UI;
- } else if ((inputFormat == HAL_PIXEL_FORMAT_R_8) ||
- (inputFormat == HAL_PIXEL_FORMAT_RG_88)) {
- *bufferType = BUFFER_TYPE_UI;
}
}
@@ -205,10 +192,7 @@
{
private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
- // we don't support framebuffer allocations with graphics heap flags
- if (usage & GRALLOC_HEAP_MASK) {
- return -EINVAL;
- }
+ // This allocation will only happen when gralloc is in fb mode
if (m->framebuffer == NULL) {
ALOGE("%s: Invalid framebuffer", __FUNCTION__);
@@ -287,22 +271,54 @@
//the usage bits, gralloc assigns a format.
if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
- if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
- grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
- else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
+ if (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC)
+ grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+ else if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
+ if(MDPCapabilityInfo::getInstance().isWBUBWCSupportedByMDP() &&
+ !IAllocController::getInstance()->isDisableUBWCForEncoder() &&
+ usage & GRALLOC_USAGE_HW_COMPOSER)
+ grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+ else
+ grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
+ } else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
== GRALLOC_USAGE_HW_CAMERA_ZSL)
grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21 ZSL
else if(usage & GRALLOC_USAGE_HW_CAMERA_READ)
grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
- else if(usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
- grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
- else if(usage & GRALLOC_USAGE_HW_COMPOSER)
+ else if(usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
+ if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21
+ } else {
+ grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; //NV12 preview
+ }
+ } else if(usage & GRALLOC_USAGE_HW_COMPOSER)
//XXX: If we still haven't set a format, default to RGBA8888
grallocFormat = HAL_PIXEL_FORMAT_RGBA_8888;
- //If no other usage flags are detected, default the
- //flexible YUV format to NV21.
- else if(format == HAL_PIXEL_FORMAT_YCbCr_420_888)
- grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+ else if(format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ //If no other usage flags are detected, default the
+ //flexible YUV format to NV21_ZSL
+ grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL;
+ }
+ }
+
+ bool useFbMem = false;
+ char property[PROPERTY_VALUE_MAX];
+ char isUBWC[PROPERTY_VALUE_MAX];
+ if (usage & GRALLOC_USAGE_HW_FB) {
+ if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+ (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+ (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+ useFbMem = true;
+ } else {
+ usage &= ~GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ if (property_get("debug.gralloc.enable_fb_ubwc", isUBWC, NULL) > 0){
+ if ((!strncmp(isUBWC, "1", PROPERTY_VALUE_MAX)) ||
+ (!strncasecmp(isUBWC, "true", PROPERTY_VALUE_MAX))) {
+ // Allocate UBWC aligned framebuffer
+ usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ }
+ }
+ }
}
getGrallocInformationFromFormat(grallocFormat, &bufferType);
@@ -314,8 +330,12 @@
size = (bufferSize >= size)? bufferSize : size;
int err = 0;
- err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
- grallocFormat, alignedw, alignedh);
+ if(useFbMem) {
+ err = gralloc_alloc_framebuffer(usage, pHandle);
+ } else {
+ err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
+ grallocFormat, w, h);
+ }
if (err < 0) {
return err;
@@ -348,6 +368,7 @@
if (err)
return err;
}
+
delete hnd;
return 0;
}
diff --git a/msm8909/libgralloc/gpu.h b/msm8909/libgralloc/gpu.h
index 82d49a1..2248d30 100644
--- a/msm8909/libgralloc/gpu.h
+++ b/msm8909/libgralloc/gpu.h
@@ -23,7 +23,7 @@
#include <stdlib.h>
#include <string.h>
-#include <log/log.h>
+#include <cutils/log.h>
#include "gralloc_priv.h"
#include "fb_priv.h"
diff --git a/msm8909/libgralloc/gr.h b/msm8909/libgralloc/gr.h
index 1f902a5..dad4a38 100644
--- a/msm8909/libgralloc/gr.h
+++ b/msm8909/libgralloc/gr.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011 - 2017, The Linux Foundation. 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.
@@ -24,9 +24,11 @@
#include <hardware/gralloc.h>
#include <pthread.h>
#include <errno.h>
+#include <unistd.h>
#include <cutils/native_handle.h>
#include <utils/Singleton.h>
+#include "adreno_utils.h"
/*****************************************************************************/
@@ -34,7 +36,7 @@
struct private_handle_t;
inline unsigned int roundUpToPageSize(unsigned int x) {
- return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
+ return (x + (getpagesize()-1)) & ~(getpagesize()-1);
}
template <class Type>
@@ -52,15 +54,6 @@
unsigned int getBufferSizeAndDimensions(int width, int height, int format,
int& alignedw, int &alignedh);
-
-// Attributes include aligned width, aligned height, tileEnabled and size of the buffer
-void getBufferAttributes(int width, int height, int format, int usage,
- int& alignedw, int &alignedh,
- int& tileEnabled, unsigned int &size);
-
-
-bool isMacroTileEnabled(int format, int usage);
-
int decideBufferHandlingMechanism(int format, const char *compositionUsed,
int hasBlitEngine, int *needConversion,
int *useBufferDirectly);
@@ -70,7 +63,17 @@
int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage);
void free_buffer(private_handle_t *hnd);
int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr);
+int getRgbDataAddress(private_handle_t* pHnd, void** rgb_data);
+// To query if UBWC is enabled, based on format and usage flags
+bool isUBwcEnabled(int format, int usage);
+
+// Function to check if the format is an RGB format
+bool isUncompressedRgbFormat(int format);
+
+// Returns number of planes, stride and offset of each plane for a given w,h,f
+int getBufferLayout(private_handle_t *hnd, uint32_t stride[4],
+ uint32_t offset[4], uint32_t *num_planes);
/*****************************************************************************/
class Locker {
@@ -106,23 +109,54 @@
~AdrenoMemInfo();
/*
+ * Function to compute aligned width and aligned height based on
+ * width, height, format and usage flags.
+ *
+ * @return aligned width, aligned height
+ */
+ void getAlignedWidthAndHeight(int width, int height, int format,
+ int usage, int& aligned_w, int& aligned_h);
+
+ /*
+ * Function to compute aligned width and aligned height based on
+ * private handle
+ *
+ * @return aligned width, aligned height
+ */
+ void getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w, int& aligned_h);
+
+ /*
* Function to compute the adreno aligned width and aligned height
* based on the width and format.
*
* @return aligned width, aligned height
*/
- void getAlignedWidthAndHeight(int width, int height, int format,
+ void getGpuAlignedWidthHeight(int width, int height, int format,
int tileEnabled, int& alignedw, int &alignedh);
/*
- * Function to return whether GPU support MacroTile feature
+ * Function to compute unaligned width and unaligned height based on
+ * private handle
*
- * @return >0 : supported
- * 0 : not supported
+ * @return unaligned width, unaligned height
*/
- int isMacroTilingSupportedByGPU();
+ void getUnalignedWidthAndHeight(const private_handle_t *hnd, int& unaligned_w,
+ int& unaligned_h);
+ /*
+ * Function to query whether GPU supports UBWC for given HAL format
+ * @return > 0 : supported
+ * 0 : not supported
+ */
+ int isUBWCSupportedByGPU(int format);
+
+ /*
+ * Function to get the corresponding Adreno format for given HAL format
+ */
+ ADRENOPIXELFORMAT getGpuPixelFormat(int hal_format);
private:
+ // Overriding flag to disable UBWC alloc for graphics stack
+ int gfx_ubwc_disable;
// Pointer to the padding library.
void *libadreno_utils;
@@ -141,8 +175,6 @@
int *aligned_w,
int *aligned_h);
- int (*LINK_adreno_isMacroTilingSupportedByGpu) (void);
-
void(*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
int width,
int height,
@@ -154,6 +186,33 @@
int *aligned_h,
int *bpp);
+ int (*LINK_adreno_isUBWCSupportedByGpu) (ADRENOPIXELFORMAT format);
+
unsigned int (*LINK_adreno_get_gpu_pixel_alignment) ();
};
+
+
+class MDPCapabilityInfo : public android::Singleton <MDPCapabilityInfo>
+{
+ int isUBwcSupported = 0;
+ int isWBUBWCSupported = 0;
+
+ public:
+ MDPCapabilityInfo();
+ /*
+ * Function to return whether MDP supports UBWC feature
+ *
+ * @return 1 : supported
+ * 0 : not supported
+ */
+ int isUBwcSupportedByMDP() { return isUBwcSupported; }
+ /*
+ * Function to return whether MDP WB block outputs UBWC format
+ *
+ * @return 1 : supported
+ * 0 : not supported
+ */
+ int isWBUBWCSupportedByMDP() { return isWBUBWCSupported; }
+};
+
#endif /* GR_H_ */
diff --git a/msm8909/libgralloc/gralloc.cpp b/msm8909/libgralloc/gralloc.cpp
index 79e2e9c..237b8a8 100644
--- a/msm8909/libgralloc/gralloc.cpp
+++ b/msm8909/libgralloc/gralloc.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008, The Android Open Source Project
- * Copyright (c) 2011-2012,2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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.
diff --git a/msm8909/libgralloc/gralloc_priv.h b/msm8909/libgralloc/gralloc_priv.h
deleted file mode 100644
index 4452b5a..0000000
--- a/msm8909/libgralloc/gralloc_priv.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2014, The Linux Foundation. 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 GRALLOC_PRIV_H_
-#define GRALLOC_PRIV_H_
-
-#include <stdint.h>
-#include <limits.h>
-#include <sys/cdefs.h>
-#include <hardware/gralloc.h>
-#include <pthread.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <cutils/native_handle.h>
-
-#include <cutils/log.h>
-
-#define ROUND_UP_PAGESIZE(x) ( (((unsigned long)(x)) + PAGE_SIZE-1) & \
- (~(PAGE_SIZE-1)) )
-
-enum {
- /* gralloc usage bits indicating the type
- * of allocation that should be used */
-
- /* SYSTEM heap comes from kernel vmalloc,
- * can never be uncached, is not secured*/
- GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP = GRALLOC_USAGE_PRIVATE_0,
- /* SF heap is used for application buffers, is not secured */
- GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP = GRALLOC_USAGE_PRIVATE_1,
- /* IOMMU heap comes from manually allocated pages,
- * can be cached/uncached, is not secured */
- GRALLOC_USAGE_PRIVATE_IOMMU_HEAP = GRALLOC_USAGE_PRIVATE_2,
- /* MM heap is a carveout heap for video, can be secured*/
- GRALLOC_USAGE_PRIVATE_MM_HEAP = GRALLOC_USAGE_PRIVATE_3,
- /* ADSP heap is a carveout heap, is not secured*/
- GRALLOC_USAGE_PRIVATE_ADSP_HEAP = 0x01000000,
-
- /* Set this for allocating uncached memory (using O_DSYNC)
- * cannot be used with noncontiguous heaps */
- GRALLOC_USAGE_PRIVATE_UNCACHED = 0x02000000,
-
- /* Buffer content should be displayed on an primary display only */
- GRALLOC_USAGE_PRIVATE_INTERNAL_ONLY = 0x04000000,
-
- /* Buffer content should be displayed on an external display only */
- GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY = 0x08000000,
-
- /* This flag is set for WFD usecase */
- GRALLOC_USAGE_PRIVATE_WFD = 0x00200000,
-
- /* CAMERA heap is a carveout heap for camera, is not secured*/
- GRALLOC_USAGE_PRIVATE_CAMERA_HEAP = 0x00400000,
-
- /* This flag is used for SECURE display usecase */
- GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY = 0x00800000,
-};
-
-enum {
- /* Gralloc perform enums
- */
- GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 1,
- // This will be deprecated from latest graphics drivers. This is kept
- // for those backward compatibility i.e., newer Display HAL + older graphics
- // libraries
- GRALLOC_MODULE_PERFORM_GET_STRIDE,
- GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE,
- GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE,
- GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES,
- GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE,
- GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO,
-};
-
-#define GRALLOC_HEAP_MASK (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
- GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP |\
- GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |\
- GRALLOC_USAGE_PRIVATE_MM_HEAP |\
- GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
-
-#define INTERLACE_MASK 0x80
-#define S3D_FORMAT_MASK 0xFF000
-/*****************************************************************************/
-enum {
- /* OEM specific HAL formats */
- HAL_PIXEL_FORMAT_RGBA_5551 = 6,
- HAL_PIXEL_FORMAT_RGBA_4444 = 7,
- HAL_PIXEL_FORMAT_NV12_ENCODEABLE = 0x102,
- HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS = 0x7FA30C04,
- HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED = 0x7FA30C03,
- HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x109,
- HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x7FA30C01,
- HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x10B,
- HAL_PIXEL_FORMAT_R_8 = 0x10D,
- HAL_PIXEL_FORMAT_RG_88 = 0x10E,
- HAL_PIXEL_FORMAT_YCbCr_444_SP = 0x10F,
- HAL_PIXEL_FORMAT_YCrCb_444_SP = 0x110,
- HAL_PIXEL_FORMAT_YCrCb_422_I = 0x111,
- HAL_PIXEL_FORMAT_BGRX_8888 = 0x112,
- HAL_PIXEL_FORMAT_NV21_ZSL = 0x113,
- HAL_PIXEL_FORMAT_INTERLACE = 0x180,
- //v4l2_fourcc('Y', 'U', 'Y', 'L'). 24 bpp YUYV 4:2:2 10 bit per component
- HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT = 0x4C595559,
- //v4l2_fourcc('Y', 'B', 'W', 'C'). 10 bit per component. This compressed
- //format reduces the memory access bandwidth
- HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED = 0x43574259,
-
- //Khronos ASTC formats
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC,
- HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC,
- HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD,
-};
-
-/* possible formats for 3D content*/
-enum {
- HAL_NO_3D = 0x0000,
- HAL_3D_IN_SIDE_BY_SIDE_L_R = 0x10000,
- HAL_3D_IN_TOP_BOTTOM = 0x20000,
- HAL_3D_IN_INTERLEAVE = 0x40000,
- HAL_3D_IN_SIDE_BY_SIDE_R_L = 0x80000,
- HAL_3D_OUT_SIDE_BY_SIDE = 0x1000,
- HAL_3D_OUT_TOP_BOTTOM = 0x2000,
- HAL_3D_OUT_INTERLEAVE = 0x4000,
- HAL_3D_OUT_MONOSCOPIC = 0x8000
-};
-
-enum {
- BUFFER_TYPE_UI = 0,
- BUFFER_TYPE_VIDEO
-};
-
-/*****************************************************************************/
-
-#ifdef __cplusplus
-struct private_handle_t : public native_handle {
-#else
- struct private_handle_t {
- native_handle_t nativeHandle;
-#endif
- enum {
- PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
- PRIV_FLAGS_USES_PMEM = 0x00000002,
- PRIV_FLAGS_USES_PMEM_ADSP = 0x00000004,
- PRIV_FLAGS_USES_ION = 0x00000008,
- PRIV_FLAGS_USES_ASHMEM = 0x00000010,
- PRIV_FLAGS_NEEDS_FLUSH = 0x00000020,
- PRIV_FLAGS_INTERNAL_ONLY = 0x00000040,
- PRIV_FLAGS_NON_CPU_WRITER = 0x00000080,
- PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
- PRIV_FLAGS_CACHED = 0x00000200,
- PRIV_FLAGS_SECURE_BUFFER = 0x00000400,
- // For explicit synchronization
- PRIV_FLAGS_UNSYNCHRONIZED = 0x00000800,
- // Not mapped in userspace
- PRIV_FLAGS_NOT_MAPPED = 0x00001000,
- // Display on external only
- PRIV_FLAGS_EXTERNAL_ONLY = 0x00002000,
- PRIV_FLAGS_VIDEO_ENCODER = 0x00010000,
- PRIV_FLAGS_CAMERA_WRITE = 0x00020000,
- PRIV_FLAGS_CAMERA_READ = 0x00040000,
- PRIV_FLAGS_HW_COMPOSER = 0x00080000,
- PRIV_FLAGS_HW_TEXTURE = 0x00100000,
- PRIV_FLAGS_ITU_R_601 = 0x00200000,
- PRIV_FLAGS_ITU_R_601_FR = 0x00400000,
- PRIV_FLAGS_ITU_R_709 = 0x00800000,
- PRIV_FLAGS_SECURE_DISPLAY = 0x01000000,
- // Buffer is rendered in Tile Format
- PRIV_FLAGS_TILE_RENDERED = 0x02000000,
- // Buffer rendered using CPU/SW renderer
- PRIV_FLAGS_CPU_RENDERED = 0x04000000
- };
-
- // file-descriptors
- int fd;
- int fd_metadata; // fd for the meta-data
- // ints
- int magic;
- int flags;
- unsigned int size;
- unsigned int offset;
- int bufferType;
- uint64_t base __attribute__((aligned(8)));
- unsigned int offset_metadata;
- // The gpu address mapped into the mmu.
- uint64_t gpuaddr __attribute__((aligned(8)));
- int format;
- int width;
- int height;
- uint64_t base_metadata __attribute__((aligned(8)));
-
-#ifdef __cplusplus
- static const int sNumFds = 2;
- static inline int sNumInts() {
- return ((sizeof(private_handle_t) - sizeof(native_handle_t)) /
- sizeof(int)) - sNumFds;
- }
- static const int sMagic = 'gmsm';
-
- private_handle_t(int fd, unsigned int size, int flags, int bufferType,
- int format, int width, int height, int eFd = -1,
- unsigned int eOffset = 0, uint64_t eBase = 0) :
- fd(fd), fd_metadata(eFd), magic(sMagic),
- flags(flags), size(size), offset(0), bufferType(bufferType),
- base(0), offset_metadata(eOffset), gpuaddr(0),
- format(format), width(width), height(height),
- base_metadata(eBase)
- {
- version = (int) sizeof(native_handle);
- numInts = sNumInts();
- numFds = sNumFds;
- }
- ~private_handle_t() {
- base_metadata = 0;
- magic = 0;
- fd_metadata = 0;
- }
-
- bool usesPhysicallyContiguousMemory() {
- return (flags & PRIV_FLAGS_USES_PMEM) != 0;
- }
-
- static int validate(const native_handle* h) {
- const private_handle_t* hnd = (const private_handle_t*)h;
- if (!h || h->version != sizeof(native_handle) ||
- h->numInts != sNumInts() || h->numFds != sNumFds ||
- hnd->magic != sMagic)
- {
- ALOGE("Invalid gralloc handle (at %p): "
- "ver(%d/%zu) ints(%d/%d) fds(%d/%d)"
- "magic(%c%c%c%c/%c%c%c%c)",
- h,
- h ? h->version : -1, sizeof(native_handle),
- h ? h->numInts : -1, sNumInts(),
- h ? h->numFds : -1, sNumFds,
- hnd ? (((hnd->magic >> 24) & 0xFF)?
- ((hnd->magic >> 24) & 0xFF) : '-') : '?',
- hnd ? (((hnd->magic >> 16) & 0xFF)?
- ((hnd->magic >> 16) & 0xFF) : '-') : '?',
- hnd ? (((hnd->magic >> 8) & 0xFF)?
- ((hnd->magic >> 8) & 0xFF) : '-') : '?',
- hnd ? (((hnd->magic >> 0) & 0xFF)?
- ((hnd->magic >> 0) & 0xFF) : '-') : '?',
- (sMagic >> 24) & 0xFF,
- (sMagic >> 16) & 0xFF,
- (sMagic >> 8) & 0xFF,
- (sMagic >> 0) & 0xFF);
- return -EINVAL;
- }
- return 0;
- }
-
- static private_handle_t* dynamicCast(const native_handle* in) {
- if (validate(in) == 0) {
- return (private_handle_t*) in;
- }
- return NULL;
- }
-#endif
- };
-
-#endif /* GRALLOC_PRIV_H_ */
diff --git a/msm8909/libgralloc/ionalloc.cpp b/msm8909/libgralloc/ionalloc.cpp
index 23e225d..329e30f 100644
--- a/msm8909/libgralloc/ionalloc.cpp
+++ b/msm8909/libgralloc/ionalloc.cpp
@@ -36,6 +36,7 @@
#include <cutils/log.h>
#include <errno.h>
#include <utils/Trace.h>
+#include <cutils/trace.h>
#include "gralloc_priv.h"
#include "ionalloc.h"
@@ -76,13 +77,9 @@
ionAllocData.len = data.size;
ionAllocData.align = data.align;
- ionAllocData.heap_id_mask = data.flags & ~ION_SECURE;
- ionAllocData.flags = data.uncached ? 0 : ION_FLAG_CACHED;
- // ToDo: replace usage of alloc data structure with
- // ionallocdata structure.
- if (data.flags & ION_SECURE)
- ionAllocData.flags |= ION_SECURE;
-
+ ionAllocData.heap_id_mask = data.heapId;
+ ionAllocData.flags = data.flags;
+ ionAllocData.flags |= data.uncached ? 0 : ION_FLAG_CACHED;
err = open_device();
if (err)
return err;
diff --git a/msm8909/libgralloc/mapper.cpp b/msm8909/libgralloc/mapper.cpp
index 99d309c..e9830e2 100644
--- a/msm8909/libgralloc/mapper.cpp
+++ b/msm8909/libgralloc/mapper.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, The Linux Foundation. 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.
@@ -55,6 +55,27 @@
return memalloc;
}
+static int gralloc_map_metadata(buffer_handle_t handle) {
+ private_handle_t* hnd = (private_handle_t*)handle;
+ hnd->base_metadata = 0;
+ IMemAlloc* memalloc = getAllocator(hnd->flags) ;
+ void *mappedAddress = MAP_FAILED;
+ unsigned int size = 0;
+ if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
+ mappedAddress = MAP_FAILED;
+ size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ int ret = memalloc->map_buffer(&mappedAddress, size,
+ hnd->offset_metadata, hnd->fd_metadata);
+ if(ret || mappedAddress == MAP_FAILED) {
+ ALOGE("Could not mmap metadata for handle %p, fd=%d (%s)",
+ hnd, hnd->fd_metadata, strerror(errno));
+ return -errno;
+ }
+ hnd->base_metadata = uint64_t(mappedAddress);
+ }
+ return 0;
+}
+
static int gralloc_map(gralloc_module_t const* module,
buffer_handle_t handle)
{
@@ -66,8 +87,10 @@
unsigned int size = 0;
int err = 0;
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
- void *mappedAddress;
- // Dont map FRAMEBUFFER and SECURE_BUFFERS
+ void *mappedAddress = MAP_FAILED;
+ hnd->base = 0;
+
+ // Dont map framebuffer and secure buffers
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
!(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
size = hnd->size;
@@ -76,60 +99,62 @@
if(err || mappedAddress == MAP_FAILED) {
ALOGE("Could not mmap handle %p, fd=%d (%s)",
handle, hnd->fd, strerror(errno));
- hnd->base = 0;
return -errno;
}
- hnd->base = uint64_t(mappedAddress) + hnd->offset;
+ hnd->base = uint64_t(mappedAddress);
+ } else {
+ // Cannot map secure buffers or framebuffers, but still need to map
+ // metadata for secure buffers.
+ // If mapping a secure buffers fails, the framework needs to get
+ // an error code.
+ err = -EACCES;
}
- //Allow mapping of metadata for all buffers and SECURE_BUFFER
- if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
- mappedAddress = MAP_FAILED;
- size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
- err = memalloc->map_buffer(&mappedAddress, size,
- hnd->offset_metadata, hnd->fd_metadata);
- if(err || mappedAddress == MAP_FAILED) {
- ALOGE("Could not mmap handle %p, fd=%d (%s)",
- handle, hnd->fd_metadata, strerror(errno));
- hnd->base_metadata = 0;
- return -errno;
- }
- hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
+ //Allow mapping of metadata for all buffers including secure ones, but not
+ //of framebuffer
+ int metadata_err = gralloc_map_metadata(handle);
+ if (!err) {
+ err = metadata_err;
}
- return 0;
+ return err;
}
static int gralloc_unmap(gralloc_module_t const* module,
buffer_handle_t handle)
{
ATRACE_CALL();
+ int err = -EINVAL;
if(!module)
- return -EINVAL;
+ return err;
private_handle_t* hnd = (private_handle_t*)handle;
- if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
- int err = -EINVAL;
- void* base = (void*)hnd->base;
- unsigned int size = hnd->size;
- IMemAlloc* memalloc = getAllocator(hnd->flags) ;
- if(memalloc != NULL) {
- err = memalloc->unmap_buffer(base, size, hnd->offset);
- if (err) {
- ALOGE("Could not unmap memory at address %p", (void*)base);
- }
- base = (void*)hnd->base_metadata;
- size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
- err = memalloc->unmap_buffer(base, size, hnd->offset_metadata);
- if (err) {
- ALOGE("Could not unmap memory at address %p", (void*)base);
- }
+ IMemAlloc* memalloc = getAllocator(hnd->flags) ;
+ if(!memalloc)
+ return err;
+
+ if(hnd->base) {
+ err = memalloc->unmap_buffer((void*)hnd->base, hnd->size, hnd->offset);
+ if (err) {
+ ALOGE("Could not unmap memory at address %p, %s", (void*) hnd->base,
+ strerror(errno));
+ return -errno;
}
+ hnd->base = 0;
}
- /* need to initialize the pointer to NULL otherwise unmapping for that
- * buffer happens twice which leads to crash */
- hnd->base = 0;
- hnd->base_metadata = 0;
+
+ if(hnd->base_metadata) {
+ unsigned int size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ err = memalloc->unmap_buffer((void*)hnd->base_metadata,
+ size, hnd->offset_metadata);
+ if (err) {
+ ALOGE("Could not unmap memory at address %p, %s",
+ (void*) hnd->base_metadata, strerror(errno));
+ return -errno;
+ }
+ hnd->base_metadata = 0;
+ }
+
return 0;
}
@@ -146,25 +171,11 @@
if (!module || private_handle_t::validate(handle) < 0)
return -EINVAL;
- // In this implementation, we don't need to do anything here
-
- /* NOTE: we need to initialize the buffer as not mapped/not locked
- * because it shouldn't when this function is called the first time
- * in a new process. Ideally these flags shouldn't be part of the
- * handle, but instead maintained in the kernel or at least
- * out-of-line
- */
-
- private_handle_t* hnd = (private_handle_t*)handle;
- hnd->base = 0;
- hnd->base_metadata = 0;
- int err = gralloc_map(module, handle);
- if (err) {
- ALOGE("%s: gralloc_map failed", __FUNCTION__);
- return err;
- }
-
- return 0;
+ int err = gralloc_map(module, handle);
+ /* Do not fail register_buffer for secure buffers*/
+ if (err == -EACCES)
+ err = 0;
+ return err;
}
int gralloc_unregister_buffer(gralloc_module_t const* module,
@@ -178,16 +189,9 @@
* If the buffer has been mapped during a lock operation, it's time
* to un-map it. It's an error to be here with a locked buffer.
* NOTE: the framebuffer is handled differently and is never unmapped.
+ * Also base and base_metadata are reset.
*/
-
- private_handle_t* hnd = (private_handle_t*)handle;
-
- if (hnd->base != 0) {
- gralloc_unmap(module, handle);
- }
- hnd->base = 0;
- hnd->base_metadata = 0;
- return 0;
+ return gralloc_unmap(module, handle);
}
int terminateBuffer(gralloc_module_t const* module,
@@ -200,23 +204,10 @@
/*
* If the buffer has been mapped during a lock operation, it's time
* to un-map it. It's an error to be here with a locked buffer.
+ * NOTE: the framebuffer is handled differently and is never unmapped.
+ * Also base and base_metadata are reset.
*/
-
- if (hnd->base != 0) {
- // this buffer was mapped, unmap it now
- if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
- private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
- private_handle_t::PRIV_FLAGS_USES_ASHMEM |
- private_handle_t::PRIV_FLAGS_USES_ION)) {
- gralloc_unmap(module, hnd);
- } else {
- ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x",
- hnd->flags);
- gralloc_unmap(module, hnd);
- }
- }
-
- return 0;
+ return gralloc_unmap(module, hnd);
}
static int gralloc_map_and_invalidate (gralloc_module_t const* module,
@@ -327,6 +318,7 @@
int width = va_arg(args, int);
int height = va_arg(args, int);
int format = va_arg(args, int);
+ int alignedw = 0, alignedh = 0;
native_handle_t** handle = va_arg(args, native_handle_t**);
private_handle_t* hnd = (private_handle_t*)native_handle_create(
@@ -339,8 +331,12 @@
hnd->offset = offset;
hnd->base = uint64_t(base) + offset;
hnd->gpuaddr = 0;
- hnd->width = width;
- hnd->height = height;
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height, format, 0, alignedw, alignedh);
+ hnd->width = alignedw;
+ hnd->height = alignedh;
+ hnd->unaligned_width = width;
+ hnd->unaligned_height = height;
hnd->format = format;
*handle = (native_handle_t *)hnd;
res = 0;
@@ -355,45 +351,40 @@
int *stride = va_arg(args, int *);
int alignedw = 0, alignedh = 0;
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
- 0, format, false, alignedw, alignedh);
+ 0, format, 0, alignedw, alignedh);
*stride = alignedw;
res = 0;
} break;
case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
{
- private_handle_t* hnd = va_arg(args, private_handle_t*);
+ const private_handle_t* hnd = va_arg(args, private_handle_t*);
int *stride = va_arg(args, int *);
if (private_handle_t::validate(hnd)) {
- va_end(args);
return res;
}
- MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
- if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
- *stride = metadata->bufferDim.sliceWidth;
- } else {
- *stride = hnd->width;
- }
+
+ int alignedw = 0, alignedh = 0;
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(hnd, alignedw, alignedh);
+ *stride = alignedw;
+
res = 0;
} break;
case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE:
{
- private_handle_t* hnd = va_arg(args, private_handle_t*);
+ const private_handle_t* hnd = va_arg(args, private_handle_t*);
int *stride = va_arg(args, int *);
int *height = va_arg(args, int *);
if (private_handle_t::validate(hnd)) {
- va_end(args);
return res;
}
- MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
- if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
- *stride = metadata->bufferDim.sliceWidth;
- *height = metadata->bufferDim.sliceHeight;
- } else {
- *stride = hnd->width;
- *height = hnd->height;
- }
+
+ int alignedw = 0, alignedh = 0;
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(hnd, alignedw, alignedh);
+ *stride = alignedw;
+ *height = alignedh;
+
res = 0;
} break;
@@ -406,10 +397,9 @@
int *alignedWidth = va_arg(args, int *);
int *alignedHeight = va_arg(args, int *);
int *tileEnabled = va_arg(args,int *);
- *tileEnabled = isMacroTileEnabled(format, usage);
+ *tileEnabled = isUBwcEnabled(format, usage);
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
- height, format, *tileEnabled, *alignedWidth,
- *alignedHeight);
+ height, format, usage, *alignedWidth, *alignedHeight);
res = 0;
} break;
@@ -418,15 +408,38 @@
private_handle_t* hnd = va_arg(args, private_handle_t*);
int *color_space = va_arg(args, int *);
if (private_handle_t::validate(hnd)) {
- va_end(args);
return res;
}
MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
- if(metadata && metadata->operation & UPDATE_COLOR_SPACE) {
+ if (!metadata) {
+ break;
+#ifdef USE_COLOR_METADATA
+ } else if (metadata->operation & COLOR_METADATA) {
+ ColorMetaData *colorMetadata = &metadata->color;
+ res = 0;
+ switch (colorMetadata->colorPrimaries) {
+ case ColorPrimaries_BT709_5:
+ *color_space = HAL_CSC_ITU_R_709;
+ break;
+ case ColorPrimaries_BT601_6_525:
+ *color_space = ((colorMetadata->range) ?
+ HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
+ break;
+ case ColorPrimaries_BT2020:
+ *color_space = (colorMetadata->range) ?
+ HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
+ break;
+ default:
+ res = -EINVAL;
+ break;
+ }
+#endif
+ } else if(metadata->operation & UPDATE_COLOR_SPACE) {
*color_space = metadata->colorSpace;
res = 0;
}
} break;
+
case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO:
{
private_handle_t* hnd = va_arg(args, private_handle_t*);
@@ -436,6 +449,72 @@
}
} break;
+ case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO:
+ {
+ private_handle_t* hnd = va_arg(args, private_handle_t*);
+ int *map_secure_buffer = va_arg(args, int *);
+ if (private_handle_t::validate(hnd)) {
+ return res;
+ }
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+ if(metadata && metadata->operation & MAP_SECURE_BUFFER) {
+ *map_secure_buffer = metadata->mapSecureBuffer;
+ res = 0;
+ } else {
+ *map_secure_buffer = 0;
+ }
+ } break;
+
+ case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG:
+ {
+ private_handle_t* hnd = va_arg(args, private_handle_t*);
+ int *flag = va_arg(args, int *);
+ if (private_handle_t::validate(hnd)) {
+ return res;
+ }
+ *flag = hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+ if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+ *flag = 0;
+ }
+ res = 0;
+ } break;
+
+ case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS:
+ {
+ private_handle_t* hnd = va_arg(args, private_handle_t*);
+ void** rgb_data = va_arg(args, void**);
+ if (!private_handle_t::validate(hnd)) {
+ res = getRgbDataAddress(hnd, rgb_data);
+ }
+ } break;
+
+ case GRALLOC_MODULE_PERFORM_GET_IGC:
+ {
+ private_handle_t* hnd = va_arg(args, private_handle_t*);
+ uint32_t *igc = va_arg(args, uint32_t *);
+ if (!private_handle_t::validate(hnd) && igc) {
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+ if (metadata && (metadata->operation & SET_IGC)) {
+ *igc = metadata->igc;
+ res = 0;
+ }
+ }
+ } break;
+
+ case GRALLOC_MODULE_PERFORM_SET_IGC:
+ res = 0;
+ break;
+
+ case GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE:
+ {
+ private_handle_t* hnd = va_arg(args, private_handle_t*);
+ uint32_t *enable = va_arg(args, uint32_t*);
+ if (!private_handle_t::validate(hnd)) {
+ setMetaData(hnd, SET_SINGLE_BUFFER_MODE, enable);
+ res = 0;
+ }
+ } break;
default:
break;
}
diff --git a/msm8909/libgralloc/memalloc.h b/msm8909/libgralloc/memalloc.h
index 2bc1ddf..598d983 100644
--- a/msm8909/libgralloc/memalloc.h
+++ b/msm8909/libgralloc/memalloc.h
@@ -49,6 +49,7 @@
uintptr_t pHandle;
bool uncached;
unsigned int flags;
+ unsigned int heapId;
int allocType;
};
diff --git a/msm8909/libhdmi/Android.mk b/msm8909/libhdmi/Android.mk
deleted file mode 100644
index b75bf40..0000000
--- a/msm8909/libhdmi/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libhdmi
-LOCAL_MODULE_TAGS := optional
-LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay libqdutils
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhdmi\" -Wno-float-conversion
-LOCAL_CLANG := true
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-
-ifeq ($(TARGET_SUPPORTS_WEARABLES),true)
-LOCAL_SRC_FILES := hdmi_stub.cpp
-else
-LOCAL_SRC_FILES := hdmi.cpp
-endif
-include $(BUILD_SHARED_LIBRARY)
diff --git a/msm8909/libhdmi/hdmi.cpp b/msm8909/libhdmi/hdmi.cpp
deleted file mode 100644
index c20efbf..0000000
--- a/msm8909/libhdmi/hdmi.cpp
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, 2016, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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.
- */
-
-#define DEBUG 0
-#include <fcntl.h>
-#include <linux/msm_mdp.h>
-#include <video/msm_hdmi_modes.h>
-#include <linux/fb.h>
-#include <sys/ioctl.h>
-#include <cutils/properties.h>
-#include "hwc_utils.h"
-#include "hdmi.h"
-#include "overlayUtils.h"
-#include "overlay.h"
-#include "qd_utils.h"
-
-using namespace android;
-using namespace qdutils;
-
-namespace qhwc {
-#define UNKNOWN_STRING "unknown"
-#define SPD_NAME_LENGTH 16
-
-/* The array gEDIDData contains a list of modes currently
- * supported by HDMI and display, and modes that are not
- * supported i.e. interlaced modes.
-
- * In order to add support for a new mode, the mode must be
- * appended to the end of the array.
- *
- * Each new entry must contain the following:
- * -Mode: a video format defined in msm_hdmi_modes.h
- * -Width: x resolution for the mode
- * -Height: y resolution for the mode
- * -FPS: the frame rate for the mode
- * -Mode Order: the priority for the new mode that is used when determining
- * the best mode when the HDMI display is connected.
- */
-EDIDData gEDIDData [] = {
- EDIDData(HDMI_VFRMT_1440x480i60_4_3, 1440, 480, 60, 1),
- EDIDData(HDMI_VFRMT_1440x480i60_16_9, 1440, 480, 60, 2),
- EDIDData(HDMI_VFRMT_1440x576i50_4_3, 1440, 576, 50, 3),
- EDIDData(HDMI_VFRMT_1440x576i50_16_9, 1440, 576, 50, 4),
- EDIDData(HDMI_VFRMT_1920x1080i60_16_9, 1920, 1080, 60, 5),
- EDIDData(HDMI_VFRMT_640x480p60_4_3, 640, 480, 60, 6),
- EDIDData(HDMI_VFRMT_720x480p60_4_3, 720, 480, 60, 7),
- EDIDData(HDMI_VFRMT_720x480p60_16_9, 720, 480, 60, 8),
- EDIDData(HDMI_VFRMT_720x576p50_4_3, 720, 576, 50, 9),
- EDIDData(HDMI_VFRMT_720x576p50_16_9, 720, 576, 50, 10),
- EDIDData(HDMI_VFRMT_800x600p60_4_3, 800, 600, 60, 11),
- EDIDData(HDMI_VFRMT_848x480p60_16_9, 848, 480, 60, 12),
- EDIDData(HDMI_VFRMT_1024x768p60_4_3, 1024, 768, 60, 13),
- EDIDData(HDMI_VFRMT_1280x1024p60_5_4, 1280, 1024, 60, 14),
- EDIDData(HDMI_VFRMT_1280x720p50_16_9, 1280, 720, 50, 15),
- EDIDData(HDMI_VFRMT_1280x720p60_16_9, 1280, 720, 60, 16),
- EDIDData(HDMI_VFRMT_1280x800p60_16_10, 1280, 800, 60, 17),
- EDIDData(HDMI_VFRMT_1280x960p60_4_3, 1280, 960, 60, 18),
- EDIDData(HDMI_VFRMT_1360x768p60_16_9, 1360, 768, 60, 19),
- EDIDData(HDMI_VFRMT_1366x768p60_16_10, 1366, 768, 60, 20),
- EDIDData(HDMI_VFRMT_1440x900p60_16_10, 1440, 900, 60, 21),
- EDIDData(HDMI_VFRMT_1400x1050p60_4_3, 1400, 1050, 60, 22),
- EDIDData(HDMI_VFRMT_1680x1050p60_16_10, 1680, 1050, 60, 23),
- EDIDData(HDMI_VFRMT_1600x1200p60_4_3, 1600, 1200, 60, 24),
- EDIDData(HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, 24, 25),
- EDIDData(HDMI_VFRMT_1920x1080p25_16_9, 1920, 1080, 25, 26),
- EDIDData(HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, 30, 27),
- EDIDData(HDMI_VFRMT_1920x1080p50_16_9, 1920, 1080, 50, 28),
- EDIDData(HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, 60, 29),
- EDIDData(HDMI_VFRMT_1920x1200p60_16_10, 1920, 1200, 60, 30),
- EDIDData(HDMI_VFRMT_2560x1600p60_16_9, 2560, 1600, 60, 31),
- EDIDData(HDMI_VFRMT_3840x2160p24_16_9, 3840, 2160, 24, 32),
- EDIDData(HDMI_VFRMT_3840x2160p25_16_9, 3840, 2160, 25, 33),
- EDIDData(HDMI_VFRMT_3840x2160p30_16_9, 3840, 2160, 30, 34),
- EDIDData(HDMI_EVFRMT_4096x2160p24_16_9, 4096, 2160, 24, 35),
-};
-
-// Number of modes in gEDIDData
-const int gEDIDCount = (sizeof(gEDIDData)/sizeof(gEDIDData)[0]);
-
-int HDMIDisplay::configure() {
- if(!openFrameBuffer()) {
- ALOGE("%s: Failed to open FB: %d", __FUNCTION__, mFbNum);
- return -1;
- }
- readCEUnderscanInfo();
- readResolution();
- // TODO: Move this to activate
- /* Used for changing the resolution
- * getUserMode will get the preferred
- * mode set thru adb shell */
- mCurrentMode = getUserMode();
- if (mCurrentMode == -1) {
- //Get the best mode and set
- mCurrentMode = getBestMode();
- }
- setAttributes();
- // set system property
- property_set("hw.hdmiON", "1");
-
- // Read the system property to determine if downscale feature is enabled.
- char value[PROPERTY_VALUE_MAX];
- mMDPDownscaleEnabled = false;
- if(property_get("sys.hwc.mdp_downscale_enabled", value, "false")
- && !strcmp(value, "true")) {
- mMDPDownscaleEnabled = true;
- }
- return 0;
-}
-
-void HDMIDisplay::getAttributes(uint32_t& width, uint32_t& height) {
- uint32_t fps = 0;
- getAttrForMode(width, height, fps);
-}
-
-int HDMIDisplay::teardown() {
- closeFrameBuffer();
- resetInfo();
- // unset system property
- property_set("hw.hdmiON", "0");
- return 0;
-}
-
-HDMIDisplay::HDMIDisplay():mFd(-1),
- mCurrentMode(-1), mModeCount(0), mPrimaryWidth(0), mPrimaryHeight(0),
- mUnderscanSupported(false)
-{
- memset(&mVInfo, 0, sizeof(mVInfo));
-
- mDisplayId = HWC_DISPLAY_EXTERNAL;
- // Update the display if HDMI is connected as primary
- if (isHDMIPrimaryDisplay()) {
- mDisplayId = HWC_DISPLAY_PRIMARY;
- }
-
- mFbNum = overlay::Overlay::getInstance()->getFbForDpy(mDisplayId);
- // disable HPD at start, it will be enabled later
- // when the display powers on
- // This helps for framework reboot or adb shell stop/start
- writeHPDOption(0);
-
- // for HDMI - retreive all the modes supported by the driver
- if(mFbNum != -1) {
- supported_video_mode_lut =
- new msm_hdmi_mode_timing_info[HDMI_VFRMT_MAX];
- // Populate the mode table for supported modes
- MSM_HDMI_MODES_INIT_TIMINGS(supported_video_mode_lut);
- MSM_HDMI_MODES_SET_SUPP_TIMINGS(supported_video_mode_lut,
- MSM_HDMI_MODES_ALL);
- // Update the Source Product Information
- // Vendor Name
- setSPDInfo("vendor_name", "ro.product.manufacturer");
- // Product Description
- setSPDInfo("product_description", "ro.product.name");
- }
-
- ALOGD_IF(DEBUG, "%s mDisplayId(%d) mFbNum(%d)",
- __FUNCTION__, mDisplayId, mFbNum);
-}
-/* gets the product manufacturer and product name and writes it
- * to the sysfs node, so that the driver can get that information
- * Used to show QCOM 8974 instead of Input 1 for example
- */
-void HDMIDisplay::setSPDInfo(const char* node, const char* property) {
- char info[PROPERTY_VALUE_MAX];
- ssize_t err = -1;
- int spdFile = openDeviceNode(node, O_RDWR);
- if (spdFile >= 0) {
- memset(info, 0, sizeof(info));
- property_get(property, info, UNKNOWN_STRING);
- ALOGD_IF(DEBUG, "In %s: %s = %s",
- __FUNCTION__, property, info);
- if (strncmp(info, UNKNOWN_STRING, SPD_NAME_LENGTH)) {
- err = write(spdFile, info, strlen(info));
- if (err <= 0) {
- ALOGE("%s: file write failed for '%s'"
- "err no = %d", __FUNCTION__, node, errno);
- }
- } else {
- ALOGD_IF(DEBUG, "%s: property_get failed for SPD %s",
- __FUNCTION__, node);
- }
- close(spdFile);
- }
-}
-
-void HDMIDisplay::setHPD(uint32_t value) {
- ALOGD_IF(DEBUG,"HPD enabled=%d", value);
- writeHPDOption(value);
-}
-
-void HDMIDisplay::setActionSafeDimension(int w, int h) {
- ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
- char actionsafeWidth[PROPERTY_VALUE_MAX];
- char actionsafeHeight[PROPERTY_VALUE_MAX];
- snprintf(actionsafeWidth, sizeof(actionsafeWidth), "%d", w);
- property_set("persist.sys.actionsafe.width", actionsafeWidth);
- snprintf(actionsafeHeight, sizeof(actionsafeHeight), "%d", h);
- property_set("persist.sys.actionsafe.height", actionsafeHeight);
-}
-
-int HDMIDisplay::getModeCount() const {
- ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount);
- return mModeCount;
-}
-
-void HDMIDisplay::readCEUnderscanInfo()
-{
- int hdmiScanInfoFile = -1;
- ssize_t len = -1;
- char scanInfo[17];
- char *ce_info_str = NULL;
- char *save_ptr;
- const char token[] = ", \n";
- int ce_info = -1;
-
- memset(scanInfo, 0, sizeof(scanInfo));
- hdmiScanInfoFile = openDeviceNode("scan_info", O_RDONLY);
- if (hdmiScanInfoFile < 0) {
- return;
- } else {
- len = read(hdmiScanInfoFile, scanInfo, sizeof(scanInfo)-1);
- ALOGD("%s: Scan Info string: %s length = %zu",
- __FUNCTION__, scanInfo, len);
- if (len <= 0) {
- close(hdmiScanInfoFile);
- ALOGE("%s: Scan Info file empty", __FUNCTION__);
- return;
- }
- scanInfo[len] = '\0'; /* null terminate the string */
- close(hdmiScanInfoFile);
- }
-
- /*
- * The scan_info contains the three fields
- * PT - preferred video format
- * IT - video format
- * CE video format - containing the underscan support information
- */
-
- /* PT */
- ce_info_str = strtok_r(scanInfo, token, &save_ptr);
- if (ce_info_str) {
- /* IT */
- ce_info_str = strtok_r(NULL, token, &save_ptr);
- if (ce_info_str) {
- /* CE */
- ce_info_str = strtok_r(NULL, token, &save_ptr);
- if (ce_info_str)
- ce_info = atoi(ce_info_str);
- }
- }
-
- if (ce_info_str) {
- // ce_info contains the underscan information
- if (ce_info == HDMI_SCAN_ALWAYS_UNDERSCANED ||
- ce_info == HDMI_SCAN_BOTH_SUPPORTED)
- // if TV supported underscan, then driver will always underscan
- // hence no need to apply action safe rectangle
- mUnderscanSupported = true;
- } else {
- ALOGE("%s: scan_info string error", __FUNCTION__);
- }
-
- // Store underscan support info in a system property
- const char* prop = (mUnderscanSupported) ? "1" : "0";
- property_set("hw.underscan_supported", prop);
- return;
-}
-
-HDMIDisplay::~HDMIDisplay()
-{
- delete [] supported_video_mode_lut;
- closeFrameBuffer();
-}
-
-/*
- * sets the fb_var_screeninfo from the hdmi_mode_timing_info
- */
-void setDisplayTiming(struct fb_var_screeninfo &info,
- const msm_hdmi_mode_timing_info* mode)
-{
- info.reserved[0] = 0;
- info.reserved[1] = 0;
- info.reserved[2] = 0;
-#ifndef FB_METADATA_VIDEO_INFO_CODE_SUPPORT
- info.reserved[3] = (info.reserved[3] & 0xFFFF) |
- (mode->video_format << 16);
-#endif
- info.xoffset = 0;
- info.yoffset = 0;
- info.xres = mode->active_h;
- info.yres = mode->active_v;
-
- info.pixclock = (mode->pixel_freq)*1000;
- info.vmode = mode->interlaced ?
- FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
-
- info.right_margin = mode->front_porch_h;
- info.hsync_len = mode->pulse_width_h;
- info.left_margin = mode->back_porch_h;
- info.lower_margin = mode->front_porch_v;
- info.vsync_len = mode->pulse_width_v;
- info.upper_margin = mode->back_porch_v;
-}
-
-int HDMIDisplay::parseResolution(char* edidStr)
-{
- char delim = ',';
- int count = 0;
- char *start, *end;
- // EDIDs are string delimited by ','
- // Ex: 16,4,5,3,32,34,1
- // Parse this string to get mode(int)
- start = (char*) edidStr;
- end = &delim;
- while(*end == delim) {
- mEDIDModes[count] = (int) strtol(start, &end, 10);
- start = end+1;
- count++;
- }
- ALOGD_IF(DEBUG, "In %s: count = %d", __FUNCTION__, count);
- for (int i = 0; i < count; i++)
- ALOGD_IF(DEBUG, "Mode[%d] = %d", i, mEDIDModes[i]);
- return count;
-}
-
-bool HDMIDisplay::readResolution()
-{
- ssize_t len = -1;
- char edidStr[128] = {'\0'};
-
- int hdmiEDIDFile = openDeviceNode("edid_modes", O_RDONLY);
- if (hdmiEDIDFile < 0) {
- return false;
- } else {
- len = read(hdmiEDIDFile, edidStr, sizeof(edidStr)-1);
- ALOGD_IF(DEBUG, "%s: EDID string: %s length = %zu",
- __FUNCTION__, edidStr, len);
- if (len <= 0) {
- ALOGE("%s: edid_modes file empty", __FUNCTION__);
- edidStr[0] = '\0';
- }
- else {
- while (len > 1 && isspace(edidStr[len-1])) {
- --len;
- }
- edidStr[len] = '\0';
- }
- close(hdmiEDIDFile);
- }
- if(len > 0) {
- // Get EDID modes from the EDID strings
- mModeCount = parseResolution(edidStr);
- ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__,
- mModeCount);
- }
-
- return (len > 0);
-}
-
-bool HDMIDisplay::openFrameBuffer()
-{
- if (mFd == -1) {
- char strDevPath[MAX_SYSFS_FILE_PATH];
- snprintf(strDevPath, MAX_SYSFS_FILE_PATH, "/dev/graphics/fb%d", mFbNum);
- mFd = open(strDevPath, O_RDWR);
- if (mFd < 0)
- ALOGE("%s: %s is not available", __FUNCTION__, strDevPath);
- }
- return (mFd > 0);
-}
-
-bool HDMIDisplay::closeFrameBuffer()
-{
- int ret = 0;
- if(mFd >= 0) {
- ret = close(mFd);
- mFd = -1;
- }
- return (ret == 0);
-}
-
-// clears the vinfo, edid, best modes
-void HDMIDisplay::resetInfo()
-{
- memset(&mVInfo, 0, sizeof(mVInfo));
- memset(mEDIDModes, 0, sizeof(mEDIDModes));
- mModeCount = 0;
- mCurrentMode = -1;
- mUnderscanSupported = false;
- mXres = 0;
- mYres = 0;
- mVsyncPeriod = 0;
- mMDPScalingMode = false;
- // Reset the underscan supported system property
- const char* prop = "0";
- property_set("hw.underscan_supported", prop);
-}
-
-int HDMIDisplay::getModeOrder(int mode)
-{
- for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
- if (gEDIDData[dataIndex].mMode == mode) {
- return gEDIDData[dataIndex].mModeOrder;
- }
- }
- ALOGE("%s Mode not found: %d", __FUNCTION__, mode);
- return -1;
-}
-
-/// Returns the user mode set(if any) using adb shell
-int HDMIDisplay::getUserMode() {
- /* Based on the property set the resolution */
- char property_value[PROPERTY_VALUE_MAX];
- property_get("hw.hdmi.resolution", property_value, "-1");
- int mode = atoi(property_value);
- // We dont support interlaced modes
- if(isValidMode(mode) && !isInterlacedMode(mode)) {
- ALOGD_IF(DEBUG, "%s: setting the HDMI mode = %d", __FUNCTION__, mode);
- return mode;
- }
- return -1;
-}
-
-// Get the best mode for the current HD TV
-int HDMIDisplay::getBestMode() {
- int bestOrder = 0;
- int bestMode = HDMI_VFRMT_640x480p60_4_3;
- // for all the edid read, get the best mode
- for(int i = 0; i < mModeCount; i++) {
- int mode = mEDIDModes[i];
- int order = getModeOrder(mode);
- if (order > bestOrder) {
- bestOrder = order;
- bestMode = mode;
- }
- }
- return bestMode;
-}
-
-inline bool HDMIDisplay::isValidMode(int ID)
-{
- bool valid = false;
- for (int i = 0; i < mModeCount; i++) {
- if(ID == mEDIDModes[i]) {
- valid = true;
- break;
- }
- }
- return valid;
-}
-
-// returns true if the mode(ID) is interlaced mode format
-bool HDMIDisplay::isInterlacedMode(int ID) {
- bool interlaced = false;
- switch(ID) {
- case HDMI_VFRMT_1440x480i60_4_3:
- case HDMI_VFRMT_1440x480i60_16_9:
- case HDMI_VFRMT_1440x576i50_4_3:
- case HDMI_VFRMT_1440x576i50_16_9:
- case HDMI_VFRMT_1920x1080i60_16_9:
- interlaced = true;
- break;
- default:
- interlaced = false;
- break;
- }
- return interlaced;
-}
-
-// Does a put_vscreen info on the HDMI interface which will update
-// the configuration (resolution, timing info) to match mCurrentMode
-void HDMIDisplay::activateDisplay()
-{
- int ret = 0;
- ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
- if(ret < 0) {
- ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
- strerror(errno));
- }
- ALOGD_IF(DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d),"
- "(%d,%d,%d) %dMHz>", __FUNCTION__,
- mVInfo.reserved[3], mVInfo.xres, mVInfo.yres,
- mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
- mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
- mVInfo.pixclock/1000/1000);
-
- const struct msm_hdmi_mode_timing_info *mode =
- &supported_video_mode_lut[0];
- for (unsigned int i = 0; i < HDMI_VFRMT_MAX; ++i) {
- const struct msm_hdmi_mode_timing_info *cur =
- &supported_video_mode_lut[i];
- if (cur->video_format == (uint32_t)mCurrentMode) {
- mode = cur;
- break;
- }
- }
- setDisplayTiming(mVInfo, mode);
- ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d"
- "(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, mCurrentMode,
- mode->video_format, mVInfo.xres, mVInfo.yres,
- mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
- mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
- mVInfo.pixclock/1000/1000);
-#ifdef FB_METADATA_VIDEO_INFO_CODE_SUPPORT
- struct msmfb_metadata metadata;
- memset(&metadata, 0 , sizeof(metadata));
- metadata.op = metadata_op_vic;
- metadata.data.video_info_code = mode->video_format;
- if (ioctl(mFd, MSMFB_METADATA_SET, &metadata) == -1) {
- ALOGD("In %s: MSMFB_METADATA_SET failed Err Str = %s",
- __FUNCTION__, strerror(errno));
- }
-#endif
- mVInfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
- ret = ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo);
- if(ret < 0) {
- ALOGD("In %s: FBIOPUT_VSCREENINFO failed Err Str = %s",
- __FUNCTION__, strerror(errno));
- }
-}
-
-bool HDMIDisplay::writeHPDOption(int userOption) const
-{
- bool ret = true;
- if(mFbNum != -1) {
- int hdmiHPDFile = openDeviceNode("hpd", O_RDWR);
- if (hdmiHPDFile >= 0) {
- ssize_t err = -1;
- ALOGD_IF(DEBUG, "%s: option = %d",
- __FUNCTION__, userOption);
- if(userOption)
- err = write(hdmiHPDFile, "1", 2);
- else
- err = write(hdmiHPDFile, "0" , 2);
- if (err <= 0) {
- ALOGE("%s: file write failed 'hpd'", __FUNCTION__);
- ret = false;
- }
- close(hdmiHPDFile);
- }
- }
- return ret;
-}
-
-
-void HDMIDisplay::setAttributes() {
- uint32_t fps = 0;
- // Always set dpyAttr res to mVInfo res
- getAttrForMode(mXres, mYres, fps);
- mMDPScalingMode = false;
-
- if(overlay::Overlay::getInstance()->isUIScalingOnExternalSupported()
- && mMDPDownscaleEnabled) {
- // if primary resolution is more than the hdmi resolution
- // configure dpy attr to primary resolution and set MDP
- // scaling mode
- // Restrict this upto 1080p resolution max, if target does not
- // support source split feature.
- uint32_t primaryArea = mPrimaryWidth * mPrimaryHeight;
- if(((primaryArea) > (mXres * mYres)) &&
- (((primaryArea) <= SUPPORTED_DOWNSCALE_AREA) ||
- qdutils::MDPVersion::getInstance().isSrcSplit())) {
- // tmpW and tmpH will hold the primary dimensions before we
- // update the aspect ratio if necessary.
- int tmpW = mPrimaryWidth;
- int tmpH = mPrimaryHeight;
- // HDMI is always in landscape, so always assign the higher
- // dimension to hdmi's xres
- if(mPrimaryHeight > mPrimaryWidth) {
- tmpW = mPrimaryHeight;
- tmpH = mPrimaryWidth;
- }
- // The aspect ratios of the external and primary displays
- // can be different. As a result, directly assigning primary
- // resolution could lead to an incorrect final image.
- // We get around this by calculating a new resolution by
- // keeping aspect ratio intact.
- hwc_rect r = {0, 0, 0, 0};
- qdutils::getAspectRatioPosition(tmpW, tmpH, mXres, mYres, r);
- uint32_t newExtW = r.right - r.left;
- uint32_t newExtH = r.bottom - r.top;
- uint32_t alignedExtW;
- uint32_t alignedExtH;
- // On 8994 and below targets MDP supports only 4X downscaling,
- // Restricting selected external resolution to be exactly 4X
- // greater resolution than actual external resolution
- uint32_t maxMDPDownScale =
- qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
- if((mXres * mYres * maxMDPDownScale) < (newExtW * newExtH)) {
- float upScaleFactor = (float)maxMDPDownScale / 2.0f;
- newExtW = (int)((float)mXres * upScaleFactor);
- newExtH = (int)((float)mYres * upScaleFactor);
- }
- // Align it down so that the new aligned resolution does not
- // exceed the maxMDPDownscale factor
- alignedExtW = overlay::utils::aligndown(newExtW, 4);
- alignedExtH = overlay::utils::aligndown(newExtH, 4);
- mXres = alignedExtW;
- mYres = alignedExtH;
- // Set External Display MDP Downscale mode indicator
- mMDPScalingMode = true;
- }
- }
- ALOGD_IF(DEBUG_MDPDOWNSCALE, "Selected external resolution [%d X %d] "
- "maxMDPDownScale %d mMDPScalingMode %d srcSplitEnabled %d "
- "MDPDownscale feature %d",
- mXres, mYres,
- qdutils::MDPVersion::getInstance().getMaxMDPDownscale(),
- mMDPScalingMode, qdutils::MDPVersion::getInstance().isSrcSplit(),
- mMDPDownscaleEnabled);
- mVsyncPeriod = (int) 1000000000l / fps;
- ALOGD_IF(DEBUG, "%s xres=%d, yres=%d", __FUNCTION__, mXres, mYres);
-}
-
-void HDMIDisplay::getAttrForMode(uint32_t& width, uint32_t& height,
- uint32_t& fps) {
- for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
- if (gEDIDData[dataIndex].mMode == mCurrentMode) {
- width = gEDIDData[dataIndex].mWidth;
- height = gEDIDData[dataIndex].mHeight;
- fps = gEDIDData[dataIndex].mFps;
- return;
- }
- }
- ALOGE("%s Unable to get attributes for %d", __FUNCTION__, mCurrentMode);
-}
-
-/* returns the fd related to the node specified*/
-int HDMIDisplay::openDeviceNode(const char* node, int fileMode) const {
- char sysFsFilePath[MAX_SYSFS_FILE_PATH];
- memset(sysFsFilePath, 0, sizeof(sysFsFilePath));
- snprintf(sysFsFilePath , sizeof(sysFsFilePath),
- "/sys/devices/virtual/graphics/fb%d/%s",
- mFbNum, node);
-
- int fd = open(sysFsFilePath, fileMode, 0);
-
- if (fd < 0) {
- ALOGE("%s: file '%s' not found : ret = %d err str: %s",
- __FUNCTION__, sysFsFilePath, fd, strerror(errno));
- }
- return fd;
-}
-
-bool HDMIDisplay::isHDMIPrimaryDisplay() {
- int hdmiNode = qdutils::getHDMINode();
- return (hdmiNode == HWC_DISPLAY_PRIMARY);
-}
-
-int HDMIDisplay::getConnectedState() {
- int ret = -1;
- int mFbNum = qdutils::getHDMINode();
- int connectedNode = openDeviceNode("connected", O_RDONLY);
- if(connectedNode >= 0) {
- char opStr[4];
- ssize_t bytesRead = read(connectedNode, opStr, sizeof(opStr) - 1);
- if(bytesRead > 0) {
- opStr[bytesRead] = '\0';
- ret = atoi(opStr);
- ALOGD_IF(DEBUG, "%s: Read %d from connected", __FUNCTION__, ret);
- } else if(bytesRead == 0) {
- ALOGE("%s: HDMI connected node empty", __FUNCTION__);
- } else {
- ALOGE("%s: Read from HDMI connected node failed with error %s",
- __FUNCTION__, strerror(errno));
- }
- close(connectedNode);
- } else {
- ALOGD("%s: /sys/class/graphics/fb%d/connected could not be opened : %s",
- __FUNCTION__, mFbNum, strerror(errno));
- }
- return ret;
-}
-
-void HDMIDisplay::setPrimaryAttributes(uint32_t primaryWidth,
- uint32_t primaryHeight) {
- mPrimaryHeight = primaryHeight;
- mPrimaryWidth = primaryWidth;
-}
-
-};
diff --git a/msm8909/libhdmi/hdmi.h b/msm8909/libhdmi/hdmi.h
deleted file mode 100644
index 605d9be..0000000
--- a/msm8909/libhdmi/hdmi.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 HWC_HDMI_DISPLAY_H
-#define HWC_HDMI_DISPLAY_H
-
-#include <linux/fb.h>
-
-struct msm_hdmi_mode_timing_info;
-
-namespace qhwc {
-
-//Type of scanning of EDID(Video Capability Data Block)
-enum hdmi_scansupport_type {
- HDMI_SCAN_NOT_SUPPORTED = 0,
- HDMI_SCAN_ALWAYS_OVERSCANED = 1,
- HDMI_SCAN_ALWAYS_UNDERSCANED = 2,
- HDMI_SCAN_BOTH_SUPPORTED = 3
-};
-
-// Structure to store EDID related data
-struct EDIDData {
- int mMode, mWidth, mHeight, mFps;
- // Predetermined ordering for each mode
- int mModeOrder;
- EDIDData(int mode, int width, int height, int fps, int order)
- : mMode(mode), mWidth(width), mHeight(height), mFps(fps), mModeOrder(order)
- { }
-};
-
-class HDMIDisplay
-{
-public:
- HDMIDisplay();
- ~HDMIDisplay();
- void setHPD(uint32_t startEnd);
- void setActionSafeDimension(int w, int h);
- bool isCEUnderscanSupported() { return mUnderscanSupported; }
- int configure();
- void getAttributes(uint32_t& width, uint32_t& height);
- int teardown();
- uint32_t getWidth() const { return mXres; };
- uint32_t getHeight() const { return mYres; };
- uint32_t getVsyncPeriod() const { return mVsyncPeriod; };
- int getFd() const { return mFd; };
- bool getMDPScalingMode() const { return mMDPScalingMode; }
- void activateDisplay();
- /* Returns true if HDMI is the PRIMARY display device*/
- bool isHDMIPrimaryDisplay();
- int getConnectedState();
- /* when HDMI is an EXTERNAL display, PRIMARY display attributes are needed
- for scaling mode */
- void setPrimaryAttributes(uint32_t primaryWidth, uint32_t primaryHeight);
-
-private:
- int getModeCount() const;
- void setSPDInfo(const char* node, const char* property);
- void readCEUnderscanInfo();
- bool readResolution();
- int parseResolution(char* edidMode);
- bool openFrameBuffer();
- bool closeFrameBuffer();
- bool writeHPDOption(int userOption) const;
- bool isValidMode(int mode);
- int getModeOrder(int mode);
- int getUserMode();
- int getBestMode();
- bool isInterlacedMode(int mode);
- void resetInfo();
- void setAttributes();
- void getAttrForMode(uint32_t& width, uint32_t& height, uint32_t& fps);
- int openDeviceNode(const char* node, int fileMode) const;
-
- int mFd;
- int mFbNum;
- int mCurrentMode;
- int mEDIDModes[64];
- int mModeCount;
- fb_var_screeninfo mVInfo;
- // Holds all the HDMI modes and timing info supported by driver
- msm_hdmi_mode_timing_info* supported_video_mode_lut;
- uint32_t mXres, mYres, mVsyncPeriod, mPrimaryWidth, mPrimaryHeight;
- bool mMDPScalingMode;
- bool mUnderscanSupported;
- // Downscale feature switch, set via system property
- // sys.hwc.mdp_downscale_enabled
- bool mMDPDownscaleEnabled;
- int mDisplayId;
-};
-
-}; //qhwc
-// ---------------------------------------------------------------------------
-#endif //HWC_HDMI_DISPLAY_H
diff --git a/msm8909/libhdmi/hdmi_stub.cpp b/msm8909/libhdmi/hdmi_stub.cpp
deleted file mode 100644
index 9ba9b60..0000000
--- a/msm8909/libhdmi/hdmi_stub.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "hwc_utils.h"
-#include "hdmi.h"
-
-namespace qhwc {
-
-HDMIDisplay::HDMIDisplay() : mFd(-1), mCurrentMode(-1), mModeCount(0),
- mPrimaryWidth(0), mPrimaryHeight(0), mUnderscanSupported(false) {
- ALOGV("%s stub", __FUNCTION__);
-}
-
-HDMIDisplay::~HDMIDisplay() {
- ALOGV("%s stub", __FUNCTION__);
-}
-
-void HDMIDisplay::setHPD(uint32_t value) {
- ALOGV("%s stub", __FUNCTION__);
- (void) value;
-}
-
-bool HDMIDisplay::isHDMIPrimaryDisplay() {
- ALOGV("%s stub", __FUNCTION__);
- return false;
-}
-
-int HDMIDisplay::getConnectedState() {
- ALOGV("%s stub", __FUNCTION__);
- return -1;
-}
-
-void HDMIDisplay::activateDisplay() {
- ALOGV("%s stub", __FUNCTION__);
-}
-
-void HDMIDisplay::getAttributes(uint32_t& width, uint32_t& height) {
- ALOGV("%s stub", __FUNCTION__);
- width = height = 0;
-}
-
-int HDMIDisplay::configure() {
- ALOGV("%s stub", __FUNCTION__);
- return -1;
-}
-
-int HDMIDisplay::teardown() {
- ALOGV("%s stub", __FUNCTION__);
- return 0;
-}
-
-void HDMIDisplay::setPrimaryAttributes(uint32_t primaryWidth,
- uint32_t primaryHeight) {
- ALOGV("%s stub", __FUNCTION__);
- (void) primaryWidth;
- (void) primaryHeight;
-}
-
-};
diff --git a/msm8909/libhwcomposer/Android.mk b/msm8909/libhwcomposer/Android.mk
deleted file mode 100644
index f6c2973..0000000
--- a/msm8909/libhwcomposer/Android.mk
+++ /dev/null
@@ -1,71 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_TAGS := optional
-LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes) \
- $(TOP)/external/skia/include/core \
- $(TOP)/external/skia/include/images
-
-ifeq ($(strip $(TARGET_USES_QCOM_DISPLAY_PP)),true)
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qdcm/inc \
- $(TARGET_OUT_HEADERS)/common/inc \
- $(TARGET_OUT_HEADERS)/pp/inc
-endif
-
-LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL liboverlay \
- libhdmi libqdutils libhardware_legacy \
- libdl libmemalloc libqservice libsync \
- libbinder libmedia
-
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhwcomposer\" -Wno-absolute-value \
- -Wno-float-conversion
-
-LOCAL_CLANG := true
-
-ifeq ($(TARGET_USES_QCOM_BSP),true)
-LOCAL_SHARED_LIBRARIES += libskia
-ifeq ($(GET_FRAMEBUFFER_FORMAT_FROM_HWC),true)
- LOCAL_CFLAGS += -DGET_FRAMEBUFFER_FORMAT_FROM_HWC
-endif
-endif #TARGET_USES_QCOM_BSP
-
-#Enable Dynamic FPS if PHASE_OFFSET is not set
-ifeq ($(VSYNC_EVENT_PHASE_OFFSET_NS),)
- LOCAL_CFLAGS += -DDYNAMIC_FPS
-endif
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := hwc.cpp \
- hwc_utils.cpp \
- hwc_uevents.cpp \
- hwc_vsync.cpp \
- hwc_fbupdate.cpp \
- hwc_mdpcomp.cpp \
- hwc_copybit.cpp \
- hwc_qclient.cpp \
- hwc_dump_layers.cpp \
- hwc_ad.cpp \
- hwc_virtual.cpp
-
-TARGET_MIGRATE_QDCM_LIST := msm8909
-TARGET_MIGRATE_QDCM := $(call is-board-platform-in-list,$(TARGET_MIGRATE_QDCM_LIST))
-
-ifeq ($(TARGET_MIGRATE_QDCM), true)
-ifeq ($(strip $(TARGET_USES_QCOM_DISPLAY_PP)),true)
-LOCAL_SRC_FILES += hwc_qdcm.cpp
-else
-LOCAL_SRC_FILES += hwc_qdcm_legacy.cpp
-endif
-else
-LOCAL_SRC_FILES += hwc_qdcm_legacy.cpp
-endif
-
-ifeq ($(TARGET_SUPPORTS_ANDROID_WEAR), true)
- LOCAL_CFLAGS += -DSUPPORT_BLIT_TO_FB
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/msm8909/libhwcomposer/hwc.cpp b/msm8909/libhwcomposer/hwc.cpp
deleted file mode 100644
index c6a7e0a..0000000
--- a/msm8909/libhwcomposer/hwc.cpp
+++ /dev/null
@@ -1,977 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2016, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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.
- */
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-#include <fcntl.h>
-#include <errno.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <EGL/egl.h>
-#include <utils/Trace.h>
-#include <sys/ioctl.h>
-#include <overlay.h>
-#include <overlayRotator.h>
-#include <overlayWriteback.h>
-#include <mdp_version.h>
-#include "hwc_utils.h"
-#include "hwc_fbupdate.h"
-#include "hwc_mdpcomp.h"
-#include "hwc_dump_layers.h"
-#include "hdmi.h"
-#include "hwc_copybit.h"
-#include "hwc_ad.h"
-#include "profiler.h"
-#include "hwc_virtual.h"
-#include "hwc_qdcm.h"
-
-using namespace qhwc;
-using namespace overlay;
-using namespace qQdcm;
-
-#define VSYNC_DEBUG 0
-#define POWER_MODE_DEBUG 1
-
-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
-};
-
-static void reset_panel(struct hwc_composer_device_1* dev);
-
-hwc_module_t HAL_MODULE_INFO_SYM = {
- .common = {
- .tag = HARDWARE_MODULE_TAG,
- .version_major = 2,
- .version_minor = 0,
- .id = HWC_HARDWARE_MODULE_ID,
- .name = "Qualcomm Hardware Composer Module",
- .author = "CodeAurora Forum",
- .methods = &hwc_module_methods,
- .dso = 0,
- .reserved = {0},
- }
-};
-
-/*
- * Save callback functions registered to HWC
- */
-static void hwc_registerProcs(struct hwc_composer_device_1* dev,
- hwc_procs_t const* procs)
-{
- ALOGI("%s", __FUNCTION__);
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- if(!ctx) {
- ALOGE("%s: Invalid context", __FUNCTION__);
- return;
- }
- ctx->proc = procs;
-
- // Now that we have the functions needed, kick off
- // the uevent & vsync threads
- init_uevent_thread(ctx);
- init_vsync_thread(ctx);
-}
-
-static void setPaddingRound(hwc_context_t *ctx, int numDisplays,
- hwc_display_contents_1_t** displays) {
- ctx->isPaddingRound = false;
- for(int i = 0; i < numDisplays; i++) {
- hwc_display_contents_1_t *list = displays[i];
- if (LIKELY(list && list->numHwLayers > 0)) {
- if((ctx->mPrevHwLayerCount[i] == 1 or
- ctx->mPrevHwLayerCount[i] == 0) and
- (list->numHwLayers > 1)) {
- /* If the previous cycle for dpy 'i' has 0 AppLayers and the
- * current cycle has atleast 1 AppLayer, padding round needs
- * to be invoked in current cycle on all the active displays
- * to free up the resources.
- */
- ctx->isPaddingRound = true;
- }
- ctx->mPrevHwLayerCount[i] = (int)list->numHwLayers;
- } else {
- ctx->mPrevHwLayerCount[i] = 0;
- }
- }
-}
-
-/* Based on certain conditions, isPaddingRound will be set
- * to make this function self-contained */
-static void setDMAState(hwc_context_t *ctx, int numDisplays,
- hwc_display_contents_1_t** displays) {
-
- if(ctx->mRotMgr->getNumActiveSessions() == 0)
- Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
-
- for(int dpy = 0; dpy < numDisplays; dpy++) {
- hwc_display_contents_1_t *list = displays[dpy];
- if (LIKELY(list && list->numHwLayers > 0)) {
- for(size_t layerIndex = 0; layerIndex < list->numHwLayers;
- layerIndex++) {
- if(list->hwLayers[layerIndex].compositionType !=
- HWC_FRAMEBUFFER_TARGET)
- {
- hwc_layer_1_t const* layer = &list->hwLayers[layerIndex];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
-
- /* If a layer requires rotation, set the DMA state
- * to BLOCK_MODE */
-
- if (canUseRotator(ctx, dpy) &&
- (has90Transform(layer) || getRotDownscale(ctx, layer))
- && isRotationDoable(ctx, hnd)) {
- if(not (ctx->mOverlay->isDMAMultiplexingSupported() &&
- dpy)) {
- if(ctx->mOverlay->isPipeTypeAttached(
- overlay::utils::OV_MDP_PIPE_DMA))
- ctx->isPaddingRound = true;
- }
- Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
- }
- }
- }
- if(dpy) {
- /* Uncomment the below code for testing purpose.
- Assuming the orientation value is in terms of HAL_TRANSFORM,
- this needs mapping to HAL, if its in different convention */
-
- /* char value[PROPERTY_VALUE_MAX];
- property_get("sys.ext_orientation", value, "0");
- ctx->mExtOrientation = atoi(value);*/
-
- if(ctx->mExtOrientation || ctx->mBufferMirrorMode) {
- if(ctx->mOverlay->isPipeTypeAttached(
- overlay::utils::OV_MDP_PIPE_DMA)) {
- ctx->isPaddingRound = true;
- }
- Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
- }
- }
- }
- }
-}
-
-static void setNumActiveDisplays(hwc_context_t *ctx, int numDisplays,
- hwc_display_contents_1_t** displays) {
-
- ctx->numActiveDisplays = 0;
- for(int i = 0; i < numDisplays; i++) {
- hwc_display_contents_1_t *list = displays[i];
- if (LIKELY(list && list->numHwLayers > 0)) {
- /* For display devices like SSD and screenrecord, we cannot
- * rely on isActive and connected attributes of dpyAttr to
- * determine if the displaydevice is active. Hence in case if
- * the layer-list is non-null and numHwLayers > 0, we assume
- * the display device to be active.
- */
- ctx->numActiveDisplays += 1;
- }
- }
-}
-
-static bool validDisplay(int disp) {
- switch(disp) {
- case HWC_DISPLAY_PRIMARY:
- case HWC_DISPLAY_EXTERNAL:
- case HWC_DISPLAY_VIRTUAL:
- return true;
- break;
- default:
- return false;
- }
-}
-
-static void reset(hwc_context_t *ctx, int numDisplays,
- hwc_display_contents_1_t** displays) {
-
-
- for(int i = 0; i < numDisplays; i++) {
- hwc_display_contents_1_t *list = displays[i];
- // XXX:SurfaceFlinger no longer guarantees that this
- // value is reset on every prepare. However, for the layer
- // cache we need to reset it.
- // We can probably rethink that later on
- if (LIKELY(list && list->numHwLayers > 0)) {
- for(size_t j = 0; j < list->numHwLayers; j++) {
- if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
- list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
- }
-
- }
-
- if(ctx->mMDPComp[i])
- ctx->mMDPComp[i]->reset();
- if(ctx->mFBUpdate[i])
- ctx->mFBUpdate[i]->reset();
- if(ctx->mCopyBit[i])
- ctx->mCopyBit[i]->reset();
- if(ctx->mLayerRotMap[i])
- ctx->mLayerRotMap[i]->reset();
- }
-
- ctx->mAD->reset();
-
-}
-
-static void scaleDisplayFrame(hwc_context_t *ctx, int dpy,
- hwc_display_contents_1_t *list) {
- uint32_t origXres = ctx->dpyAttr[dpy].xres;
- uint32_t origYres = ctx->dpyAttr[dpy].yres;
- uint32_t newXres = ctx->dpyAttr[dpy].xres_new;
- uint32_t newYres = ctx->dpyAttr[dpy].yres_new;
- float xresRatio = (float)origXres / (float)newXres;
- float yresRatio = (float)origYres / (float)newYres;
- for (size_t i = 0; i < list->numHwLayers; i++) {
- hwc_layer_1_t *layer = &list->hwLayers[i];
- hwc_rect_t& displayFrame = layer->displayFrame;
- uint32_t layerWidth = displayFrame.right - displayFrame.left;
- uint32_t layerHeight = displayFrame.bottom - displayFrame.top;
- displayFrame.left = (int)(xresRatio * (float)displayFrame.left);
- displayFrame.top = (int)(yresRatio * (float)displayFrame.top);
- displayFrame.right = (int)((float)displayFrame.left +
- (float)layerWidth * xresRatio);
- displayFrame.bottom = (int)((float)displayFrame.top +
- (float)layerHeight * yresRatio);
- }
-}
-
-static int hwc_prepare_primary(hwc_composer_device_1 *dev,
- hwc_display_contents_1_t *list) {
- ATRACE_CALL();
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- const int dpy = HWC_DISPLAY_PRIMARY;
- bool fbComp = false;
- static int compStart = false;
- if (!ctx->mBootAnimCompleted)
- processBootAnimCompleted(ctx);
-
- if (LIKELY(list && (list->numHwLayers > 1 ||
- (ctx->mMDP.version < qdutils::MDP_V4_0 && compStart))) &&
- (ctx->dpyAttr[dpy].isActive ||
- ctx->mHDMIDisplay->isHDMIPrimaryDisplay())
- && !ctx->dpyAttr[dpy].isPause) {
- compStart = true;
-
- // When HDMI is primary we should rely on the first valid
- // draw call in order to activate the display
- if (!ctx->dpyAttr[dpy].isActive) {
- // If the cable is connected after HWC initialization and before
- // the UEvent thread is initialized then we will miss the ONLINE
- // event. We need to update the display appropriately when we get
- // the first valid frame.
- int cableConnected = ctx->mHDMIDisplay->getConnectedState();
- if ((cableConnected == 1) && !ctx->dpyAttr[dpy].connected) {
- qhwc::handle_online(ctx, dpy);
- }
- ctx->mHDMIDisplay->activateDisplay();
- ctx->dpyAttr[dpy].isActive = true;
- }
-
- if (ctx->dpyAttr[dpy].customFBSize &&
- list->flags & HWC_GEOMETRY_CHANGED)
- scaleDisplayFrame(ctx, dpy, list);
-
- reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
- setListStats(ctx, list, dpy);
-
- fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0);
-
- if (fbComp) {
- const int fbZ = 0;
- if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) {
- ctx->mOverlay->clear(dpy);
- ctx->mLayerRotMap[dpy]->clear();
- }
- }
-
- if (ctx->mMDP.version < qdutils::MDP_V4_0) {
- if(ctx->mCopyBit[dpy])
- ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
- }
- setGPUHint(ctx, list);
- }
- return 0;
-}
-
-static int hwc_prepare_external(hwc_composer_device_1 *dev,
- hwc_display_contents_1_t *list) {
- ATRACE_CALL();
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- const int dpy = HWC_DISPLAY_EXTERNAL;
-
- if (LIKELY(list && list->numHwLayers > 1) &&
- ctx->dpyAttr[dpy].isActive &&
- ctx->dpyAttr[dpy].connected) {
- reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
- if(!ctx->dpyAttr[dpy].isPause) {
- ctx->dpyAttr[dpy].isConfiguring = false;
- setListStats(ctx, list, dpy);
- if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
- const int fbZ = 0;
- if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
- {
- ctx->mOverlay->clear(dpy);
- ctx->mLayerRotMap[dpy]->clear();
- }
- }
- } else {
- /* External Display is in Pause state.
- * Mark all application layers as OVERLAY so that
- * GPU will not compose.
- */
- for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
- hwc_layer_1_t *layer = &list->hwLayers[i];
- layer->compositionType = HWC_OVERLAY;
- }
- }
- }
- return 0;
-}
-
-static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
- hwc_display_contents_1_t** displays)
-{
- int ret = 0;
- hwc_context_t* ctx = (hwc_context_t*)(dev);
-
- if (ctx->mPanelResetStatus) {
- ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__);
- reset_panel(dev);
- }
-
- //Will be unlocked at the end of set
- ctx->mDrawLock.lock();
- setPaddingRound(ctx, (int)numDisplays, displays);
- setDMAState(ctx, (int)numDisplays, displays);
- setNumActiveDisplays(ctx, (int)numDisplays, displays);
- reset(ctx, (int)numDisplays, displays);
-
- ctx->mOverlay->configBegin();
- ctx->mRotMgr->configBegin();
- overlay::Writeback::configBegin();
-
- for (int32_t dpy = ((int32_t)numDisplays-1); dpy >=0 ; dpy--) {
- hwc_display_contents_1_t *list = displays[dpy];
- resetROI(ctx, dpy);
- switch(dpy) {
- case HWC_DISPLAY_PRIMARY:
- ret = hwc_prepare_primary(dev, list);
- break;
- case HWC_DISPLAY_EXTERNAL:
- ret = hwc_prepare_external(dev, list);
- break;
- case HWC_DISPLAY_VIRTUAL:
- if(ctx->mHWCVirtual)
- ret = ctx->mHWCVirtual->prepare(dev, list);
- break;
- default:
- ret = -EINVAL;
- }
- }
-
- ctx->mOverlay->configDone();
- ctx->mRotMgr->configDone();
- overlay::Writeback::configDone();
- // If VD list is deleted, mdp overlay pipe objects and writeback object
- // are deleted as part of configDone functions.
- // Proceed with HWCVirtualVDS object deletion.
- if(ctx->mHWCVirtual)
- ctx->mHWCVirtual->destroy(ctx, numDisplays, displays);
-
- return ret;
-}
-
-static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
- int event, int enable)
-{
- ATRACE_CALL();
- int ret = 0;
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- if(!validDisplay(dpy)) {
- return -EINVAL;
- }
-
- switch(event) {
- case HWC_EVENT_VSYNC:
- if (ctx->vstate.enable == enable)
- break;
- ret = hwc_vsync_control(ctx, dpy, enable);
- if(ret == 0)
- ctx->vstate.enable = !!enable;
- ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
- (enable)?"ENABLED":"DISABLED");
- break;
-#ifdef QTI_BSP
- case HWC_EVENT_ORIENTATION:
- if(dpy == HWC_DISPLAY_PRIMARY) {
- Locker::Autolock _l(ctx->mDrawLock);
- // store the primary display orientation
- ctx->deviceOrientation = enable;
- }
- break;
-#endif
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy,
- int mode)
-{
- ATRACE_CALL();
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- int ret = 0, value = 0;
-
- Locker::Autolock _l(ctx->mDrawLock);
-
- if(!validDisplay(dpy)) {
- return -EINVAL;
- }
-
- ALOGD_IF(POWER_MODE_DEBUG, "%s: Setting mode %d on display: %d",
- __FUNCTION__, mode, dpy);
-
- switch(mode) {
- case HWC_POWER_MODE_OFF:
- // free up all the overlay pipes in use
- // when we get a blank for either display
- // makes sure that all pipes are freed
- ctx->mOverlay->configBegin();
- ctx->mOverlay->configDone();
- ctx->mRotMgr->clear();
- // If VDS is connected, do not clear WB object as it
- // will end up detaching IOMMU. This is required
- // to send black frame to WFD sink on power suspend.
- // Note: With this change, we keep the WriteBack object
- // alive on power suspend for AD use case.
- value = FB_BLANK_POWERDOWN;
- break;
- case HWC_POWER_MODE_DOZE:
- case HWC_POWER_MODE_DOZE_SUSPEND:
- value = FB_BLANK_VSYNC_SUSPEND;
- break;
- case HWC_POWER_MODE_NORMAL:
- value = FB_BLANK_UNBLANK;
- break;
- }
-
- switch(dpy) {
- case HWC_DISPLAY_PRIMARY:
- if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
- if(ctx->dpyAttr[dpy].connected) {
- // When HDMI is connected as primary we clean up resources
- // and call commit to generate a black frame on the interface.
- // However, we do not call blank since we need the timing
- // generator and HDMI core to remain turned on.
- if((mode == HWC_POWER_MODE_OFF) &&
- (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd))) {
- ALOGE("%s: display commit fail for %d", __FUNCTION__, dpy);
- ret = -1;
- }
- }
- } else {
- if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) {
- ALOGE("%s: ioctl FBIOBLANK failed for Primary with error %s"
- " value %d", __FUNCTION__, strerror(errno), value);
- return -errno;
- }
-
- if(mode == HWC_POWER_MODE_NORMAL) {
- // Enable HPD here, as during bootup POWER_MODE_NORMAL is set
- // when SF is completely initialized
- ctx->mHDMIDisplay->setHPD(1);
- }
-
- ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
- }
- //Deliberate fall through since there is no explicit power mode for
- //virtual displays.
- case HWC_DISPLAY_VIRTUAL:
- if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
- const int dpy = HWC_DISPLAY_VIRTUAL;
- if(mode == HWC_POWER_MODE_OFF and
- (not ctx->dpyAttr[dpy].isPause)) {
- if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
- ALOGE("%s: displayCommit failed for virtual", __FUNCTION__);
- ret = -1;
- }
- }
- ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
- }
- break;
- case HWC_DISPLAY_EXTERNAL:
- if(mode == HWC_POWER_MODE_OFF) {
- if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
- ALOGE("%s: displayCommit failed for external", __FUNCTION__);
- ret = -1;
- }
- }
- ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
- break;
- default:
- return -EINVAL;
- }
-
- ALOGD_IF(POWER_MODE_DEBUG, "%s: Done setting mode %d on display %d",
- __FUNCTION__, mode, dpy);
- return ret;
-}
-
-static void reset_panel(struct hwc_composer_device_1* dev)
-{
- int ret = 0;
- hwc_context_t* ctx = (hwc_context_t*)(dev);
-
- if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
- ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__);
- ctx->mPanelResetStatus = false;
- return;
- }
-
- ALOGD("%s: setting power mode off", __FUNCTION__);
- ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_OFF);
- if (ret < 0) {
- ALOGE("%s: FBIOBLANK failed to BLANK: %s", __FUNCTION__,
- strerror(errno));
- }
-
- ALOGD("%s: setting power mode normal and enabling vsync", __FUNCTION__);
- ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_NORMAL);
- if (ret < 0) {
- ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__,
- strerror(errno));
- }
- hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1);
-
- ctx->mPanelResetStatus = false;
-}
-
-
-static int hwc_query(struct hwc_composer_device_1* dev,
- int param, int* value)
-{
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- int supported = HWC_DISPLAY_PRIMARY_BIT;
-
- switch (param) {
- case HWC_BACKGROUND_LAYER_SUPPORTED:
- // Not supported for now
- value[0] = 0;
- break;
- case HWC_DISPLAY_TYPES_SUPPORTED:
- if(ctx->mMDP.hasOverlay) {
- supported |= HWC_DISPLAY_VIRTUAL_BIT;
- if(!(qdutils::MDPVersion::getInstance().is8x26() ||
- qdutils::MDPVersion::getInstance().is8x16() ||
- qdutils::MDPVersion::getInstance().is8x39()))
- supported |= HWC_DISPLAY_EXTERNAL_BIT;
- }
- value[0] = supported;
- break;
- case HWC_FORMAT_RB_SWAP:
- value[0] = 1;
- break;
- case HWC_COLOR_FILL:
- value[0] = 1;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-
-}
-
-
-static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
- ATRACE_CALL();
- int ret = 0;
- const int dpy = HWC_DISPLAY_PRIMARY;
- if (LIKELY(list) && ctx->dpyAttr[dpy].isActive
- && !ctx->dpyAttr[dpy].isPause) {
- size_t last = list->numHwLayers - 1;
- hwc_layer_1_t *fbLayer = &list->hwLayers[last];
- int fd = -1; //FenceFD from the Copybit(valid in async mode)
- bool copybitDone = false;
-
- if (ctx->mCopyBit[dpy]) {
- if (ctx->mMDP.version < qdutils::MDP_V4_0)
- copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
- else
- fd = ctx->mMDPComp[dpy]->drawOverlap(ctx, list);
- }
-
- if(list->numHwLayers > 1)
- hwc_sync(ctx, list, dpy, fd);
-
- // Dump the layers for primary
- if(ctx->mHwcDebug[dpy])
- ctx->mHwcDebug[dpy]->dumpLayers(list);
-
- if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
- ALOGE("%s: MDPComp draw failed", __FUNCTION__);
- ret = -1;
- }
-
- //TODO We dont check for SKIP flag on this layer because we need PAN
- //always. Last layer is always FB
- private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
- if(copybitDone && ((ctx->mMDP.version >= qdutils::MDP_V4_0)
-#ifdef SUPPORT_BLIT_TO_FB
- || (ctx->mMDP.version == qdutils::MDP_V3_0_5)
-#endif
- )) {
- hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
- }
-
- if(isAbcInUse(ctx) == true) {
- int index = ctx->listStats[dpy].renderBufIndexforABC;
- hwc_layer_1_t *tempLayer = &list->hwLayers[index];
- hnd = (private_handle_t *)tempLayer->handle;
- }
-
- if(hnd) {
- if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
- ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
- ret = -1;
- }
- }
-
- int lSplit = getLeftSplit(ctx, dpy);
- qhwc::ovutils::Dim lRoi = qhwc::ovutils::Dim(
- ctx->listStats[dpy].lRoi.left,
- ctx->listStats[dpy].lRoi.top,
- ctx->listStats[dpy].lRoi.right - ctx->listStats[dpy].lRoi.left,
- ctx->listStats[dpy].lRoi.bottom - ctx->listStats[dpy].lRoi.top);
-
- qhwc::ovutils::Dim rRoi = qhwc::ovutils::Dim(
- ctx->listStats[dpy].rRoi.left - lSplit,
- ctx->listStats[dpy].rRoi.top,
- ctx->listStats[dpy].rRoi.right - ctx->listStats[dpy].rRoi.left,
- ctx->listStats[dpy].rRoi.bottom - ctx->listStats[dpy].rRoi.top);
-
- if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) {
- ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
- ret = -1;
- }
-
- }
-
- closeAcquireFds(list);
- return ret;
-}
-
-static int hwc_set_external(hwc_context_t *ctx,
- hwc_display_contents_1_t* list)
-{
- ATRACE_CALL();
- int ret = 0;
-
- const int dpy = HWC_DISPLAY_EXTERNAL;
-
- if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
- ctx->dpyAttr[dpy].connected &&
- !ctx->dpyAttr[dpy].isPause) {
- size_t last = list->numHwLayers - 1;
- hwc_layer_1_t *fbLayer = &list->hwLayers[last];
- int fd = -1; //FenceFD from the Copybit(valid in async mode)
- bool copybitDone = false;
- if(ctx->mCopyBit[dpy])
- copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
-
- if(list->numHwLayers > 1)
- hwc_sync(ctx, list, dpy, fd);
-
- // Dump the layers for external
- if(ctx->mHwcDebug[dpy])
- ctx->mHwcDebug[dpy]->dumpLayers(list);
-
- if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
- ALOGE("%s: MDPComp draw failed", __FUNCTION__);
- ret = -1;
- }
-
- private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
- if(copybitDone) {
- hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
- }
-
- if(hnd) {
- if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
- ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
- ret = -1;
- }
- }
-
- if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
- ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
- ret = -1;
- }
- }
-
- closeAcquireFds(list);
- return ret;
-}
-
-static int hwc_set(hwc_composer_device_1 *dev,
- size_t numDisplays,
- hwc_display_contents_1_t** displays)
-{
- int ret = 0;
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- for (int dpy = 0; dpy < (int)numDisplays; dpy++) {
- hwc_display_contents_1_t* list = displays[dpy];
- switch(dpy) {
- case HWC_DISPLAY_PRIMARY:
- ret = hwc_set_primary(ctx, list);
- break;
- case HWC_DISPLAY_EXTERNAL:
- ret = hwc_set_external(ctx, list);
- break;
- case HWC_DISPLAY_VIRTUAL:
- if(ctx->mHWCVirtual)
- ret = ctx->mHWCVirtual->set(ctx, list);
- break;
- default:
- ret = -EINVAL;
- }
- }
- // This is only indicative of how many times SurfaceFlinger posts
- // frames to the display.
- CALC_FPS();
- MDPComp::resetIdleFallBack();
- ctx->mVideoTransFlag = false;
- //Was locked at the beginning of prepare
- ctx->mDrawLock.unlock();
- return ret;
-}
-
-int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
- uint32_t* configs, size_t* numConfigs) {
- int ret = 0;
- hwc_context_t* ctx = (hwc_context_t*)(dev);
-
- Locker::Autolock _l(ctx->mDrawLock);
-
- if(!validDisplay(disp)) {
- return -EINVAL;
- }
- //Currently we allow only 1 config, reported as config id # 0
- //This config is passed in to getDisplayAttributes. Ignored for now.
-
- switch(disp) {
- case HWC_DISPLAY_PRIMARY:
- if(*numConfigs > 0) {
- configs[0] = 0;
- *numConfigs = 1;
- }
- ret = 0; //NO_ERROR
- break;
- case HWC_DISPLAY_EXTERNAL:
- case HWC_DISPLAY_VIRTUAL:
- ret = -1; //Not connected
- if(ctx->dpyAttr[disp].connected) {
- ret = 0; //NO_ERROR
- if(*numConfigs > 0) {
- configs[0] = 0;
- *numConfigs = 1;
- }
- }
- break;
- }
- return ret;
-}
-
-int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
- uint32_t /*config*/, const uint32_t* attributes, int32_t* values) {
-
- hwc_context_t* ctx = (hwc_context_t*)(dev);
-
- Locker::Autolock _l(ctx->mDrawLock);
-
- if(!validDisplay(disp)) {
- return -EINVAL;
- }
- //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
- if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
- return -1;
- }
-
- //From HWComposer
- static const uint32_t DISPLAY_ATTRIBUTES[] = {
- HWC_DISPLAY_VSYNC_PERIOD,
- HWC_DISPLAY_WIDTH,
- HWC_DISPLAY_HEIGHT,
- HWC_DISPLAY_DPI_X,
- HWC_DISPLAY_DPI_Y,
-#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
- HWC_DISPLAY_FBFORMAT,
-#endif
- HWC_DISPLAY_NO_ATTRIBUTE,
- };
-
- const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
- sizeof(DISPLAY_ATTRIBUTES)[0]);
-
- for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
- switch (attributes[i]) {
- case HWC_DISPLAY_VSYNC_PERIOD:
- values[i] = ctx->dpyAttr[disp].vsync_period;
- break;
- case HWC_DISPLAY_WIDTH:
- if (ctx->dpyAttr[disp].customFBSize)
- values[i] = ctx->dpyAttr[disp].xres_new;
- else
- values[i] = ctx->dpyAttr[disp].xres;
-
- ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
- values[i]);
- break;
- case HWC_DISPLAY_HEIGHT:
- if (ctx->dpyAttr[disp].customFBSize)
- values[i] = ctx->dpyAttr[disp].yres_new;
- else
- values[i] = ctx->dpyAttr[disp].yres;
- ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
- values[i]);
- break;
- case HWC_DISPLAY_DPI_X:
- values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
- break;
- case HWC_DISPLAY_DPI_Y:
- values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
- break;
-#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
- case HWC_DISPLAY_FBFORMAT:
- values[i] = ctx->dpyAttr[disp].fbformat;
- break;
-#endif
- default:
- ALOGE("Unknown display attribute %d",
- attributes[i]);
- return -EINVAL;
- }
- }
- return 0;
-}
-
-void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
-{
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- Locker::Autolock _l(ctx->mDrawLock);
- android::String8 aBuf("");
- dumpsys_log(aBuf, "Qualcomm HWC state:\n");
- dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version);
- dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel);
- dumpsys_log(aBuf, " DynRefreshRate=%d\n",
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].dynRefreshRate);
- for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) {
- if(ctx->mMDPComp[dpy])
- ctx->mMDPComp[dpy]->dump(aBuf, ctx);
- }
- char ovDump[2048] = {'\0'};
- ctx->mOverlay->getDump(ovDump, 2048);
- dumpsys_log(aBuf, ovDump);
- ovDump[0] = '\0';
- ctx->mRotMgr->getDump(ovDump, 1024);
- dumpsys_log(aBuf, ovDump);
- ovDump[0] = '\0';
- if(Writeback::getDump(ovDump, 1024)) {
- dumpsys_log(aBuf, ovDump);
- ovDump[0] = '\0';
- }
- dumpsys_log(aBuf, "Copybit::isAbcInUse=%d\n\n",isAbcInUse(ctx) ? 1 : 0);
- strlcpy(buff, aBuf.string(), buff_len);
-}
-
-int hwc_getActiveConfig(struct hwc_composer_device_1* dev, int disp) {
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- Locker::Autolock _l(ctx->mDrawLock);
- if(!validDisplay(disp)) {
- return -EINVAL;
- }
-
- //Supports only the default config (0th index) for now
- return 0;
-}
-
-int hwc_setActiveConfig(struct hwc_composer_device_1* dev, int disp,
- int index) {
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- Locker::Autolock _l(ctx->mDrawLock);
- if(!validDisplay(disp)) {
- return -EINVAL;
- }
-
- //Supports only the default config (0th index) for now
- return (index == 0) ? index : -EINVAL;
-}
-
-static int hwc_device_close(struct hw_device_t *dev)
-{
- if(!dev) {
- ALOGE("%s: NULL device pointer", __FUNCTION__);
- return -1;
- }
- closeContext((hwc_context_t*)dev);
- free(dev);
-
- return 0;
-}
-
-static int hwc_device_open(const struct hw_module_t* module, const char* name,
- struct hw_device_t** device)
-{
- int status = -EINVAL;
-
- if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
- struct hwc_context_t *dev;
- dev = (hwc_context_t*)malloc(sizeof(*dev));
- if(dev == NULL)
- return status;
- memset(dev, 0, sizeof(*dev));
-
- //Initialize hwc context
- initContext(dev);
-
- //Setup HWC methods
- dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = HWC_DEVICE_API_VERSION_1_5;
- dev->device.common.module = const_cast<hw_module_t*>(module);
- dev->device.common.close = hwc_device_close;
- dev->device.prepare = hwc_prepare;
- dev->device.set = hwc_set;
- dev->device.eventControl = hwc_eventControl;
- dev->device.setPowerMode = hwc_setPowerMode;
- dev->device.query = hwc_query;
- dev->device.registerProcs = hwc_registerProcs;
- dev->device.dump = hwc_dump;
- dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
- dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
- dev->device.getActiveConfig = hwc_getActiveConfig;
- dev->device.setActiveConfig = hwc_setActiveConfig;
- *device = &dev->device.common;
- status = 0;
- }
- return status;
-}
diff --git a/msm8909/libhwcomposer/hwc_ad.cpp b/msm8909/libhwcomposer/hwc_ad.cpp
deleted file mode 100644
index 7e96d97..0000000
--- a/msm8909/libhwcomposer/hwc_ad.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
-* Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation. nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <unistd.h>
-#include <overlay.h>
-#include <overlayUtils.h>
-#include <overlayWriteback.h>
-#include <mdp_version.h>
-#include "hwc_ad.h"
-#include "hwc_utils.h"
-
-#define DEBUG 0
-using namespace overlay;
-using namespace overlay::utils;
-namespace qhwc {
-
-//Helper to write data to ad node
-static void adWrite(const int& value) {
- const int wbFbNum = Overlay::getFbForDpy(Overlay::DPY_WRITEBACK);
- char wbFbPath[256];
- snprintf (wbFbPath, sizeof(wbFbPath),
- "/sys/class/graphics/fb%d/ad", wbFbNum);
- int adFd = open(wbFbPath, O_WRONLY);
- if(adFd >= 0) {
- char opStr[4] = "";
- snprintf(opStr, sizeof(opStr), "%d", value);
- ssize_t ret = write(adFd, opStr, strlen(opStr));
- if(ret < 0) {
- ALOGE("%s: Failed to write %d with error %s",
- __func__, value, strerror(errno));
- } else if (ret == 0){
- ALOGE("%s Nothing written to ad", __func__);
- } else {
- ALOGD_IF(DEBUG, "%s: Wrote %d to ad", __func__, value);
- }
- close(adFd);
- } else {
- ALOGE("%s: Failed to open /sys/class/graphics/fb%d/ad with error %s",
- __func__, wbFbNum, strerror(errno));
- }
-}
-
-//Helper to read data from ad node
-static int adRead() {
- const int wbFbNum = Overlay::getFbForDpy(Overlay::DPY_WRITEBACK);
- int ret = -1;
- char wbFbPath[256];
- snprintf (wbFbPath, sizeof(wbFbPath),
- "/sys/class/graphics/fb%d/ad", wbFbNum);
- int adFd = open(wbFbPath, O_RDONLY);
- if(adFd >= 0) {
- char opStr[4];
- ssize_t bytesRead = read(adFd, opStr, sizeof(opStr) - 1);
- if(bytesRead > 0) {
- opStr[bytesRead] = '\0';
- //Should return -1, 0 or 1
- ret = atoi(opStr);
- ALOGD_IF(DEBUG, "%s: Read %d from ad", __func__, ret);
- } else if(bytesRead == 0) {
- ALOGE("%s: ad node empty", __func__);
- } else {
- ALOGE("%s: Read from ad node failed with error %s", __func__,
- strerror(errno));
- }
- close(adFd);
- } else {
- ALOGD("%s: /sys/class/graphics/fb%d/ad could not be opened : %s",
- __func__, wbFbNum, strerror(errno));
- }
- return ret;
-}
-
-AssertiveDisplay::AssertiveDisplay(hwc_context_t *ctx) :
- mTurnedOff(true), mFeatureEnabled(false),
- mDest(overlay::utils::OV_INVALID)
-{
- //Values in ad node:
- //-1 means feature is disabled on device
- // 0 means feature exists but turned off, will be turned on by hwc
- // 1 means feature is turned on by hwc
- // Plus, we do this feature only on split primary displays.
- // Plus, we do this feature only if ro.qcom.ad=2
-
- char property[PROPERTY_VALUE_MAX];
- const int ENABLED = 2;
- int val = 0;
-
- if(property_get("ro.qcom.ad", property, "0") > 0) {
- val = atoi(property);
- }
-
- if(adRead() >= 0 && isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY) &&
- val == ENABLED) {
- ALOGD_IF(DEBUG, "Assertive display feature supported");
- mFeatureEnabled = true;
- // If feature exists but is turned off, set mTurnedOff to true
- mTurnedOff = adRead() > 0 ? false : true;
- }
-}
-
-void AssertiveDisplay::markDoable(hwc_context_t *ctx,
- const hwc_display_contents_1_t* list) {
- mDoable = false;
- if(mFeatureEnabled &&
- !isSecondaryConnected(ctx) &&
- ctx->listStats[HWC_DISPLAY_PRIMARY].yuvCount == 1) {
- int nYuvIndex = ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndices[0];
- const hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
- if(hnd && hnd->width <= (int) mdpHw.getMaxMixerWidth()) {
- mDoable = true;
- }
- }
-}
-
-void AssertiveDisplay::turnOffAD() {
- if(mFeatureEnabled) {
- if(!mTurnedOff) {
- const int off = 0;
- adWrite(off);
- mTurnedOff = true;
- }
- }
- mDoable = false;
-}
-
-bool AssertiveDisplay::prepare(hwc_context_t *ctx,
- const hwc_rect_t& crop,
- const Whf& whf,
- const private_handle_t *hnd) {
- if(!isDoable()) {
- //Cleanup one time during this switch
- turnOffAD();
- return false;
- }
-
- Overlay::PipeSpecs pipeSpecs;
- pipeSpecs.formatClass = Overlay::FORMAT_YUV;
- pipeSpecs.dpy = overlay::Overlay::DPY_WRITEBACK;
- pipeSpecs.fb = false;
-
- ovutils::eDest dest = ctx->mOverlay->getPipe(pipeSpecs);
- if(dest == OV_INVALID) {
- ALOGE("%s failed: No VG pipe available", __func__);
- mDoable = false;
- return false;
- }
-
- overlay::Writeback *wb = overlay::Writeback::getInstance();
-
- //Set Security flag on writeback
- if(isSecureBuffer(hnd)) {
- if(!wb->setSecure(isSecureBuffer(hnd))) {
- ALOGE("Failure in setting WB secure flag for ad");
- return false;
- }
- }
-
- if(!wb->configureDpyInfo(hnd->width, hnd->height)) {
- ALOGE("%s: config display failed", __func__);
- mDoable = false;
- return false;
- }
-
- int tmpW, tmpH;
- size_t size;
- int format = ovutils::getHALFormat(wb->getOutputFormat());
- if(format < 0) {
- ALOGE("%s invalid format %d", __func__, format);
- mDoable = false;
- return false;
- }
-
- size = getBufferSizeAndDimensions(hnd->width, hnd->height,
- format, tmpW, tmpH);
-
- if(!wb->configureMemory((uint32_t)size)) {
- ALOGE("%s: config memory failed", __func__);
- mDoable = false;
- return false;
- }
-
- eMdpFlags mdpFlags = OV_MDP_FLAGS_NONE;
- if(isSecureBuffer(hnd)) {
- ovutils::setMdpFlags(mdpFlags,
- ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
- }
-
- PipeArgs parg(mdpFlags, whf, ZORDER_0,
- ROT_FLAGS_NONE);
- hwc_rect_t dst = crop; //input same as output
-
- if(configMdp(ctx->mOverlay, parg, OVERLAY_TRANSFORM_0, crop, dst, NULL,
- dest) < 0) {
- ALOGE("%s: configMdp failed", __func__);
- mDoable = false;
- return false;
- }
-
- mDest = dest;
- int wbFd = wb->getFbFd();
- if(mFeatureEnabled && wbFd >= 0 &&
- !ctx->mOverlay->validateAndSet(overlay::Overlay::DPY_WRITEBACK, wbFd))
- {
- ALOGE("%s: Failed to validate and set overlay for dpy %d"
- ,__FUNCTION__, overlay::Overlay::DPY_WRITEBACK);
- turnOffAD();
- return false;
- }
-
- // Only turn on AD if there are no errors during configuration stage
- // and if it was previously in OFF state.
- if(mFeatureEnabled && mTurnedOff) {
- //write to sysfs, one time during this switch
- const int on = 1;
- adWrite(on);
- mTurnedOff = false;
- }
-
- return true;
-}
-
-bool AssertiveDisplay::draw(hwc_context_t *ctx, int fd, uint32_t offset) {
- if(!isDoable()) {
- return false;
- }
-
- if (!ctx->mOverlay->queueBuffer(fd, offset, mDest)) {
- ALOGE("%s: queueBuffer failed", __func__);
- return false;
- }
-
- overlay::Writeback *wb = overlay::Writeback::getInstance();
- if(!wb->writeSync()) {
- return false;
- }
-
- return true;
-}
-
-int AssertiveDisplay::getDstFd() const {
- overlay::Writeback *wb = overlay::Writeback::getInstance();
- return wb->getDstFd();
-}
-
-uint32_t AssertiveDisplay::getDstOffset() const {
- overlay::Writeback *wb = overlay::Writeback::getInstance();
- return wb->getOffset();
-}
-
-}
diff --git a/msm8909/libhwcomposer/hwc_ad.h b/msm8909/libhwcomposer/hwc_ad.h
deleted file mode 100644
index 0be5f5d..0000000
--- a/msm8909/libhwcomposer/hwc_ad.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-* Copyright (c) 2013 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation. nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef HWC_AD_H
-#define HWC_AD_H
-
-#include <overlayUtils.h>
-#include <hwc_utils.h>
-
-struct hwc_context_t;
-
-namespace qhwc {
-
-class AssertiveDisplay {
-public:
- AssertiveDisplay(hwc_context_t *ctx);
- void markDoable(hwc_context_t *ctx, const hwc_display_contents_1_t* list);
- bool prepare(hwc_context_t *ctx, const hwc_rect_t& crop,
- const overlay::utils::Whf& whf,
- const private_handle_t *hnd);
- bool draw(hwc_context_t *ctx, int fd, uint32_t offset);
- //Resets a few members on each draw round
- void reset() { mDoable = false;
- mDest = overlay::utils::OV_INVALID;
- }
- bool isDoable() const { return mDoable; }
- int getDstFd() const;
- uint32_t getDstOffset() const;
-
-private:
- bool mDoable;
- bool mTurnedOff;
- //State of feature existence on certain devices and configs.
- bool mFeatureEnabled;
- overlay::utils::eDest mDest;
- void turnOffAD();
-};
-
-}
-#endif
diff --git a/msm8909/libhwcomposer/hwc_copybit.cpp b/msm8909/libhwcomposer/hwc_copybit.cpp
deleted file mode 100644
index 4b70b13..0000000
--- a/msm8909/libhwcomposer/hwc_copybit.cpp
+++ /dev/null
@@ -1,1382 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2016, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution.
- *
- * 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.
- */
-
-#define DEBUG_COPYBIT 0
-#include <copybit.h>
-#include <utils/Timers.h>
-#include <mdp_version.h>
-#include "hwc_copybit.h"
-#include "comptype.h"
-#include "gr.h"
-#include "cb_utils.h"
-#include "cb_swap_rect.h"
-#include "math.h"
-#include "sync/sync.h"
-
-using namespace qdutils;
-namespace qhwc {
-
-struct range {
- int current;
- int end;
-};
-struct region_iterator : public copybit_region_t {
-
- region_iterator(hwc_region_t region) {
- mRegion = region;
- r.end = (int)region.numRects;
- r.current = 0;
- this->next = iterate;
- }
-
-private:
- static int iterate(copybit_region_t const * self, copybit_rect_t* rect){
- if (!self || !rect) {
- ALOGE("iterate invalid parameters");
- return 0;
- }
-
- region_iterator const* me =
- static_cast<region_iterator const*>(self);
- if (me->r.current != me->r.end) {
- rect->l = me->mRegion.rects[me->r.current].left;
- rect->t = me->mRegion.rects[me->r.current].top;
- rect->r = me->mRegion.rects[me->r.current].right;
- rect->b = me->mRegion.rects[me->r.current].bottom;
- me->r.current++;
- return 1;
- }
- return 0;
- }
-
- hwc_region_t mRegion;
- mutable range r;
-};
-
-void CopyBit::reset() {
- mIsModeOn = false;
- mCopyBitDraw = false;
-}
-
-bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) {
- // return true for non-overlay targets
- if(ctx->mMDP.hasOverlay && ctx->mMDP.version >= qdutils::MDP_V4_0) {
- return false;
- }
- return true;
-}
-
-bool CopyBit::isSmartBlitPossible(const hwc_display_contents_1_t *list){
- if(list->numHwLayers > 2) {
- hwc_rect_t displayFrame0 = {0, 0, 0, 0};
- hwc_rect_t displayFrame1 = {0, 0, 0, 0};
- int layer0_transform = 0;
- int layer1_transform = 0;
- int isYuvLayer0 = 0;
- int isYuvLayer1 = 0;
- for (unsigned int i=0; i<list->numHwLayers -1; i++) {
- hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
- if (mSwapRect)
- displayFrame = getIntersection(mDirtyRect,
- list->hwLayers[i].displayFrame);
- if (isValidRect(displayFrame) && !isValidRect(displayFrame0)) {
- displayFrame0 = displayFrame;
- private_handle_t *hnd =(private_handle_t *)list->hwLayers[i].handle;
- isYuvLayer0 = isYuvBuffer(hnd);
- layer0_transform = list->hwLayers[i].transform;
- } else if(isValidRect(displayFrame)) {
- displayFrame1 = displayFrame;
- layer1_transform = list->hwLayers[i].transform;
- private_handle_t *hnd =(private_handle_t *)list->hwLayers[i].handle;
- isYuvLayer1 = isYuvBuffer(hnd);
- break;
- }
- }
- /*
- * smart blit enable only if
- * 1. Both layers should have same ROI.
- * 2. Both layers can't be video layer.
- * 3. Should not be any rotation for base RGB layer.
- * 4. In case of base layer as video, next above RGB layer
- * should not contains any rotation.
- */
- if((displayFrame0 == displayFrame1) && not (isYuvLayer1 && isYuvLayer0)) {
- if (isYuvLayer0) {
- if (not layer1_transform) {
- ALOGD_IF(DEBUG_COPYBIT,"%s:Smart Bilt Possible",__FUNCTION__);
- return true;
- }
- } else if (not layer0_transform) {
- ALOGD_IF(DEBUG_COPYBIT,"%s:Smart Bilt Possible",__FUNCTION__);
- return true;
- }
- }
- }
- return false;
-}
-
-bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx,
- hwc_display_contents_1_t *list,
- int dpy) {
- int compositionType = qdutils::QCCompositionType::
- getInstance().getCompositionType();
-
- if (compositionType & qdutils::COMPOSITION_TYPE_DYN) {
- // DYN Composition:
- // use copybit, if (TotalRGBRenderArea < threashold * FB Area)
- // this is done based on perf inputs in ICS
- // TODO: Above condition needs to be re-evaluated in JB
- int fbWidth = ctx->dpyAttr[dpy].xres;
- int fbHeight = ctx->dpyAttr[dpy].yres;
- unsigned int fbArea = (fbWidth * fbHeight);
- unsigned int renderArea = getRGBRenderingArea(ctx, list);
- ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
- __FUNCTION__, renderArea, fbArea);
- double dynThreshold = mDynThreshold;
- if(not isSmartBlitPossible(list))
- dynThreshold -= 1;
-
- if (renderArea < (dynThreshold * fbArea)) {
- return true;
- }
- } else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
- // MDP composition, use COPYBIT always
- return true;
- } else if ((compositionType & qdutils::COMPOSITION_TYPE_C2D)) {
- // C2D composition, use COPYBIT
- return true;
- }
- return false;
-}
-
-unsigned int CopyBit::getRGBRenderingArea (const hwc_context_t *ctx,
- const hwc_display_contents_1_t *list) {
- //Calculates total rendering area for RGB layers
- unsigned int renderArea = 0;
- unsigned int w=0, h=0;
- // Skipping last layer since FrameBuffer layer should not affect
- // which composition to choose
- for (unsigned int i=0; i<list->numHwLayers -1; i++) {
- private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
- if (hnd) {
- if (BUFFER_TYPE_UI == hnd->bufferType && !ctx->copybitDrop[i]) {
- getLayerResolution(&list->hwLayers[i], w, h);
- renderArea += (w*h);
- }
- }
- }
- return renderArea;
-}
-
-bool CopyBit::isLayerChanging(hwc_context_t *ctx,
- hwc_display_contents_1_t *list, int k) {
- if((mLayerCache.hnd[k] != list->hwLayers[k].handle) ||
- (mLayerCache.drop[k] != ctx->copybitDrop[k]) ||
- (mLayerCache.displayFrame[k].left !=
- list->hwLayers[k].displayFrame.left) ||
- (mLayerCache.displayFrame[k].top !=
- list->hwLayers[k].displayFrame.top) ||
- (mLayerCache.displayFrame[k].right !=
- list->hwLayers[k].displayFrame.right) ||
- (mLayerCache.displayFrame[k].bottom !=
- list->hwLayers[k].displayFrame.bottom)) {
- return 1;
- }
- return 0;
-}
-
-bool CopyBit::prepareSwapRect(hwc_context_t *ctx,
- hwc_display_contents_1_t *list,
- int dpy) {
- bool canUseSwapRect = 0;
- hwc_rect_t dirtyRect = {0, 0, 0, 0};
- hwc_rect_t displayRect = {0, 0, 0, 0};
- hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[dpy].xres,
- (int)ctx->dpyAttr[dpy].yres};
- if((mLayerCache.layerCount != ctx->listStats[dpy].numAppLayers) ||
- list->flags & HWC_GEOMETRY_CHANGED || not mSwapRectEnable) {
- mLayerCache.reset();
- mFbCache.reset();
- mLayerCache.updateCounts(ctx,list,dpy);
- mDirtyRect = displayRect;
- return 0;
- }
-
- int updatingLayerCount = 0;
- for (int k = ctx->listStats[dpy].numAppLayers-1; k >= 0 ; k--){
- //swap rect will kick in only for single updating layer
- if(isLayerChanging(ctx, list, k)) {
- updatingLayerCount ++;
- hwc_layer_1_t layer = list->hwLayers[k];
- canUseSwapRect = 1;
-#ifdef QTI_BSP
- dirtyRect = getUnion(dirtyRect, calculateDirtyRect(&layer,fullFrame));
-#else
- (void)fullFrame;
-#endif
- displayRect = getUnion(displayRect, layer.displayFrame);
- }
- }
- //since we are using more than one framebuffers,we have to
- //kick in swap rect only if we are getting continuous same
- //dirty rect for same layer at least equal of number of
- //framebuffers
-
- if (canUseSwapRect || updatingLayerCount == 0) {
- if (updatingLayerCount == 0) {
- dirtyRect.left = INVALID_DIMENSION;
- dirtyRect.top = INVALID_DIMENSION;
- dirtyRect.right = INVALID_DIMENSION;
- dirtyRect.bottom = INVALID_DIMENSION;
- canUseSwapRect = 1;
- }
-
- for (int k = ctx->listStats[dpy].numAppLayers-1; k >= 0 ; k--) {
- //disable swap rect in case of scaling and video .
- private_handle_t *hnd =(private_handle_t *)list->hwLayers[k].handle;
- if(needsScaling(&list->hwLayers[k])||( hnd && isYuvBuffer(hnd)) ||
- (list->hwLayers[k].transform & HAL_TRANSFORM_ROT_90)) {
- mFbCache.reset();
- displayRect.bottom = 0;
- displayRect.top = 0;
- displayRect.right = 0;
- displayRect.bottom = 0;
- mDirtyRect = displayRect;
- return 0;
- }
- }
-
- if(mFbCache.getUnchangedFbDRCount(dirtyRect, displayRect) <
- NUM_RENDER_BUFFERS) {
- mFbCache.insertAndUpdateFbCache(dirtyRect, displayRect);
- canUseSwapRect = 0;
- displayRect.bottom = 0;
- displayRect.top = 0;
- displayRect.right = 0;
- displayRect.bottom = 0;
- }
- } else {
- mFbCache.reset();
- canUseSwapRect = 0;
- displayRect.bottom = 0;
- displayRect.top = 0;
- displayRect.right = 0;
- displayRect.bottom = 0;
-
- }
- mDirtyRect = displayRect;
- mLayerCache.updateCounts(ctx,list,dpy);
- return canUseSwapRect;
-}
-
-bool CopyBit::prepareOverlap(hwc_context_t *ctx,
- hwc_display_contents_1_t *list) {
-
- if (ctx->mMDP.version < qdutils::MDP_V4_0) {
- ALOGE("%s: Invalid request", __FUNCTION__);
- return false;
- }
-
- if (mEngine == NULL || !(validateParams(ctx, list))) {
- ALOGE("%s: Invalid Params", __FUNCTION__);
- return false;
- }
- PtorInfo* ptorInfo = &(ctx->mPtorInfo);
-
- // Allocate render buffers if they're not allocated
- int alignW = 0, alignH = 0;
- int finalW = 0, finalH = 0;
- for (int i = 0; i < ptorInfo->count; i++) {
- int ovlapIndex = ptorInfo->layerIndex[i];
- hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame;
- // render buffer width will be the max of two layers
- // Align Widht and height to 32, Mdp would be configured
- // with Aligned overlap w/h
- finalW = max(finalW, ALIGN((overlap.right - overlap.left), 32));
- finalH += ALIGN((overlap.bottom - overlap.top), 32);
- if(finalH > ALIGN((overlap.bottom - overlap.top), 32)) {
- // Calculate the dest top, left will always be zero
- ptorInfo->displayFrame[i].top = (finalH -
- (ALIGN((overlap.bottom - overlap.top), 32)));
- }
- // calculate the right and bottom values
- ptorInfo->displayFrame[i].right = ptorInfo->displayFrame[i].left +
- (overlap.right - overlap.left);
- ptorInfo->displayFrame[i].bottom = ptorInfo->displayFrame[i].top +
- (overlap.bottom - overlap.top);
- }
-
- getBufferSizeAndDimensions(finalW, finalH, HAL_PIXEL_FORMAT_RGBA_8888,
- alignW, alignH);
-
- if ((mAlignedWidth != alignW) || (mAlignedHeight != alignH)) {
- // Overlap rect has changed, so free render buffers
- freeRenderBuffers();
- }
-
- int ret = allocRenderBuffers(alignW, alignH, HAL_PIXEL_FORMAT_RGBA_8888);
-
- if (ret < 0) {
- ALOGE("%s: Render buffer allocation failed", __FUNCTION__);
- return false;
- }
-
- mAlignedWidth = alignW;
- mAlignedHeight = alignH;
- mCurRenderBufferIndex = (mCurRenderBufferIndex + 1) % NUM_RENDER_BUFFERS;
- return true;
-}
-
-bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
- int dpy) {
-
- if(mEngine == NULL) {
- // No copybit device found - cannot use copybit
- return false;
- }
-
- if(ctx->mThermalBurstMode) {
- ALOGD_IF (DEBUG_COPYBIT, "%s:Copybit failed,"
- "Running in Thermal Burst mode",__FUNCTION__);
- return false;
- }
-
- int compositionType = qdutils::QCCompositionType::
- getInstance().getCompositionType();
-
- if ((compositionType == qdutils::COMPOSITION_TYPE_GPU) ||
- (compositionType == qdutils::COMPOSITION_TYPE_CPU)) {
- //GPU/CPU composition, don't change layer composition type
- return true;
- }
-
- if(!(validateParams(ctx, list))) {
- ALOGE("%s:Invalid Params", __FUNCTION__);
- return false;
- }
-
- if(ctx->listStats[dpy].skipCount) {
- //GPU will be anyways used
- return false;
- }
-
- if (ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS) {
- // Reached max layers supported by HWC.
- return false;
- }
-
- int last = (uint32_t)list->numHwLayers - 1;
- mDirtyRect = list->hwLayers[last].displayFrame;
- mSwapRect = prepareSwapRect(ctx, list, dpy);
- ALOGD_IF (DEBUG_COPYBIT, "%s: mSwapRect: %d mDirtyRect: [%d, %d, %d, %d]",
- __FUNCTION__, mSwapRect, mDirtyRect.left,
- mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
-
- bool useCopybitForYUV = canUseCopybitForYUV(ctx);
- bool useCopybitForRGB = canUseCopybitForRGB(ctx, list, dpy);
- LayerProp *layerProp = ctx->layerProp[dpy];
-
- // Following are MDP3 limitations for which we
- // need to fallback to GPU composition:
- // 1. Plane alpha is not supported by MDP3.
- // 2. Scaling is within range
- if (qdutils::MDPVersion::getInstance().getMDPVersion() < 400) {
- for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
- int dst_h, dst_w, src_h, src_w;
- float dx, dy;
- if(ctx->copybitDrop[i]) {
- continue;
- }
- hwc_layer_1_t *layer = (hwc_layer_1_t *) &list->hwLayers[i];
- if (layer->planeAlpha != 0xFF)
- return true;
-
- if (layer->transform) {
- ALOGD_IF (DEBUG_COPYBIT, "%s: Do GPU comp Transform : %d",
- __FUNCTION__, layer->transform);
- return true;
- }
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
-
- if (has90Transform(layer)) {
- src_h = sourceCrop.right - sourceCrop.left;
- src_w = sourceCrop.bottom - sourceCrop.top;
- } else {
- src_h = sourceCrop.bottom - sourceCrop.top;
- src_w = sourceCrop.right - sourceCrop.left;
- }
- dst_h = layer->displayFrame.bottom - layer->displayFrame.top;
- dst_w = layer->displayFrame.right - layer->displayFrame.left;
-
- if(src_w <=0 || src_h<=0 ||dst_w<=0 || dst_h<=0 ) {
- ALOGE("%s: wrong params for display screen_w=%d \
- src_crop_width=%d screen_h=%d src_crop_height=%d",
- __FUNCTION__, dst_w,src_w,dst_h,src_h);
- return false;
- }
- dx = (float)dst_w/(float)src_w;
- dy = (float)dst_h/(float)src_h;
-
- float scale_factor_max = MAX_SCALE_FACTOR;
- float scale_factor_min = MIN_SCALE_FACTOR;
-
- if (isAlphaPresent(layer)) {
- scale_factor_max = MAX_SCALE_FACTOR/4;
- scale_factor_min = MIN_SCALE_FACTOR*4;
- }
-
- if (dx > scale_factor_max || dx < scale_factor_min)
- return false;
-
- if (dy > scale_factor_max || dy < scale_factor_min)
- return false;
- }
- }
-
- //Allocate render buffers if they're not allocated
- if ((ctx->mMDP.version != qdutils::MDP_V3_0_4 &&
-#ifdef SUPPORT_BLIT_TO_FB
- ctx->mMDP.version == qdutils::MDP_V3_0_5
-#else
- ctx->mMDP.version != qdutils::MDP_V3_0_5
-#endif
- ) && (useCopybitForYUV || useCopybitForRGB)) {
- int ret = allocRenderBuffers(mAlignedWidth,
- mAlignedHeight,
- HAL_PIXEL_FORMAT_RGBA_8888);
- if (ret < 0) {
- return false;
- } else {
- mCurRenderBufferIndex = (mCurRenderBufferIndex + 1) %
- NUM_RENDER_BUFFERS;
- }
- }
-
- // We cannot mix copybit layer with layers marked to be drawn on FB
- if (!useCopybitForYUV && ctx->listStats[dpy].yuvCount)
- return true;
-
- mCopyBitDraw = false;
- if (useCopybitForRGB &&
- (useCopybitForYUV || !ctx->listStats[dpy].yuvCount)) {
- mCopyBitDraw = true;
- // numAppLayers-1, as we iterate till 0th layer index
- // Mark all layers to be drawn by copybit
- for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
- layerProp[i].mFlags |= HWC_COPYBIT;
-#ifdef QTI_BSP
- if (ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
- ctx->mMDP.version == qdutils::MDP_V3_0_5)
- list->hwLayers[i].compositionType = HWC_BLIT;
- else
-#endif
- list->hwLayers[i].compositionType = HWC_OVERLAY;
- }
- }
-
- return true;
-}
-
-int CopyBit::clear (private_handle_t* hnd, hwc_rect_t& rect)
-{
- int ret = 0;
- copybit_rect_t clear_rect = {rect.left, rect.top,
- rect.right,
- rect.bottom};
-
- copybit_image_t buf;
- buf.w = ALIGN(getWidth(hnd),32);
- buf.h = getHeight(hnd);
- buf.format = hnd->format;
- buf.base = (void *)hnd->base;
- buf.handle = (native_handle_t *)hnd;
-
- copybit_device_t *copybit = mEngine;
- ret = copybit->clear(copybit, &buf, &clear_rect);
- return ret;
-}
-
-bool CopyBit::drawUsingAppBufferComposition(hwc_context_t *ctx,
- hwc_display_contents_1_t *list,
- int dpy, int *copybitFd) {
- int layerCount = 0;
- uint32_t last = (uint32_t)list->numHwLayers - 1;
- hwc_layer_1_t *fbLayer = &list->hwLayers[last];
- private_handle_t *fbhnd = (private_handle_t *)fbLayer->handle;
-
- if(ctx->enableABC == false)
- return false;
-
- if(ctx->listStats[dpy].numAppLayers > MAX_LAYERS_FOR_ABC )
- return false;
-
- layerCount = ctx->listStats[dpy].numAppLayers;
- //bottom most layer should
- //equal to FB
- hwc_layer_1_t *tmpLayer = &list->hwLayers[0];
- private_handle_t *hnd = (private_handle_t *)tmpLayer->handle;
- if(hnd && fbhnd && (hnd->size == fbhnd->size) &&
- (hnd->width == fbhnd->width) && (hnd->height == fbhnd->height)){
- if(tmpLayer->transform ||
- (list->flags & HWC_GEOMETRY_CHANGED) ||
- (!(hnd->format == HAL_PIXEL_FORMAT_RGBA_8888 ||
- hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)) ||
- (needsScaling(tmpLayer) == true)) {
- return false;
- }else {
- ctx->listStats[dpy].renderBufIndexforABC = 0;
- }
- }
-
- if(ctx->listStats[dpy].renderBufIndexforABC == 0) {
- if(layerCount == 1)
- return true;
-
- if(layerCount == MAX_LAYERS_FOR_ABC) {
- int abcRenderBufIdx = ctx->listStats[dpy].renderBufIndexforABC;
- //enable ABC only for non intersecting layers.
- hwc_rect_t displayFrame =
- list->hwLayers[abcRenderBufIdx].displayFrame;
- for (int i = abcRenderBufIdx + 1; i < layerCount; i++) {
- hwc_rect_t tmpDisplayFrame = list->hwLayers[i].displayFrame;
- hwc_rect_t result = getIntersection(displayFrame,tmpDisplayFrame);
- if (isValidRect(result)) {
- ctx->listStats[dpy].renderBufIndexforABC = -1;
- return false;
- }
- }
- // Pass the Acquire Fence FD to driver for base layer
- private_handle_t *renderBuffer =
- (private_handle_t *)list->hwLayers[abcRenderBufIdx].handle;
- copybit_device_t *copybit = getCopyBitDevice();
- if(list->hwLayers[abcRenderBufIdx].acquireFenceFd >=0){
- copybit->set_sync(copybit,
- list->hwLayers[abcRenderBufIdx].acquireFenceFd);
- }
- for(int i = abcRenderBufIdx + 1; i < layerCount; i++){
- mSwapRect = 0;
- int retVal = drawLayerUsingCopybit(ctx,
- &(list->hwLayers[i]),renderBuffer, 0);
- if(retVal < 0) {
- ALOGE("%s : Copybit failed", __FUNCTION__);
- }
- }
- // Get Release Fence FD of copybit for the App layer(s)
- copybit->flush_get_fence(copybit, copybitFd);
- close(list->hwLayers[last].acquireFenceFd);
- list->hwLayers[last].acquireFenceFd = -1;
- return true;
- }
- }
- return false;
-}
-
-bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
- int dpy, int32_t *fd) {
- // draw layers marked for COPYBIT
- int retVal = true;
- int copybitLayerCount = 0;
- uint32_t last = 0;
- LayerProp *layerProp = ctx->layerProp[dpy];
- private_handle_t *renderBuffer;
-
- if(mCopyBitDraw == false){
- mFbCache.reset(); // there is no layer marked for copybit
- return false ;
- }
-
- if(drawUsingAppBufferComposition(ctx, list, dpy, fd)) {
- mFbCache.reset();
- return true;
- }
- //render buffer
- if (ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
-#ifdef SUPPORT_BLIT_TO_FB
- ctx->mMDP.version != qdutils::MDP_V3_0_5
-#else
- ctx->mMDP.version == qdutils::MDP_V3_0_5
-#endif
- ) {
- last = (uint32_t)list->numHwLayers - 1;
- renderBuffer = (private_handle_t *)list->hwLayers[last].handle;
- } else {
- renderBuffer = getCurrentRenderBuffer();
- }
- if (!renderBuffer) {
- ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__);
- return false;
- }
-
- if ((ctx->mMDP.version >= qdutils::MDP_V4_0)
-#ifdef SUPPORT_BLIT_TO_FB
- || (ctx->mMDP.version == qdutils::MDP_V3_0_5)
-#endif
- ) {
- //Wait for the previous frame to complete before rendering onto it
- if(mRelFd[mCurRenderBufferIndex] >=0) {
- sync_wait(mRelFd[mCurRenderBufferIndex], 1000);
- close(mRelFd[mCurRenderBufferIndex]);
- mRelFd[mCurRenderBufferIndex] = -1;
- }
- } else {
- if(list->hwLayers[last].acquireFenceFd >=0) {
- copybit_device_t *copybit = getCopyBitDevice();
- copybit->set_sync(copybit, list->hwLayers[last].acquireFenceFd);
- }
- }
-
- //if swap rect on and not getting valid dirtyRect
- //means calling only commit without any draw. Hence avoid
- //clear call as well.
- if (not mSwapRect || isValidRect(mDirtyRect)) {
- if (not CBUtils::uiClearRegion(list, ctx->mMDP.version, layerProp,
- mDirtyRect, mEngine, renderBuffer)){
- mSwapRect = 0;
- }
- }
-
- // numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag
- for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
- if(!(layerProp[i].mFlags & HWC_COPYBIT)) {
- ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__);
- continue;
- }
- if(ctx->copybitDrop[i]) {
- continue;
- }
- int ret = -1;
- if (list->hwLayers[i].acquireFenceFd != -1
- && ctx->mMDP.version >= qdutils::MDP_V4_0) {
- // Wait for acquire Fence on the App buffers.
- ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
- if(ret < 0) {
- ALOGE("%s: sync_wait error!! error no = %d err str = %s",
- __FUNCTION__, errno, strerror(errno));
- }
- close(list->hwLayers[i].acquireFenceFd);
- list->hwLayers[i].acquireFenceFd = -1;
- }
- retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
- renderBuffer, !i);
- copybitLayerCount++;
- if(retVal < 0) {
- ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
- }
- }
-
- if (copybitLayerCount) {
- copybit_device_t *copybit = getCopyBitDevice();
- // Async mode
- copybit->flush_get_fence(copybit, fd);
- if((ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
-#ifdef SUPPORT_BLIT_TO_FB
- ctx->mMDP.version != qdutils::MDP_V3_0_5
-#else
- ctx->mMDP.version == qdutils::MDP_V3_0_5
-#endif
- ) && list->hwLayers[last].acquireFenceFd >= 0) {
- close(list->hwLayers[last].acquireFenceFd);
- list->hwLayers[last].acquireFenceFd = -1;
- }
- }
- return true;
-}
-
-int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
- int fd = -1;
- PtorInfo* ptorInfo = &(ctx->mPtorInfo);
-
- if (ctx->mMDP.version < qdutils::MDP_V4_0) {
- ALOGE("%s: Invalid request", __FUNCTION__);
- return fd;
- }
-
- private_handle_t *renderBuffer = getCurrentRenderBuffer();
-
- if (!renderBuffer) {
- ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__);
- return fd;
- }
-
- //Clear the transparent or left out region on the render buffer
- LayerProp *layerProp = ctx->layerProp[0];
- hwc_rect_t clearRegion = {0, 0, 0, 0};
- CBUtils::uiClearRegion(list, ctx->mMDP.version, layerProp, clearRegion,
- mEngine, renderBuffer);
-
- int copybitLayerCount = 0;
- for(int j = 0; j < ptorInfo->count; j++) {
- int ovlapIndex = ptorInfo->layerIndex[j];
- hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame;
- if(j) {
- /**
- * It's possible that 2 PTOR layers might have overlapping.
- * In such case, remove the intersection(again if peripheral)
- * from the lower PTOR layer to avoid overlapping.
- * If intersection is not on peripheral then compromise
- * by reducing number of PTOR layers.
- **/
- int prevOvlapIndex = ptorInfo->layerIndex[0];
- hwc_rect_t prevOvlap = list->hwLayers[prevOvlapIndex].displayFrame;
- hwc_rect_t commonRect = getIntersection(prevOvlap, overlap);
- if(isValidRect(commonRect)) {
- overlap = deductRect(overlap, commonRect);
- }
- }
-
- // Draw overlapped content of layers on render buffer
- for (int i = 0; i <= ovlapIndex; i++) {
- hwc_layer_1_t *layer = &list->hwLayers[i];
- if(!isValidRect(getIntersection(layer->displayFrame,
- overlap))) {
- continue;
- }
- if ((list->hwLayers[i].acquireFenceFd != -1)) {
- // Wait for acquire fence on the App buffers.
- if(sync_wait(list->hwLayers[i].acquireFenceFd, 1000) < 0) {
- ALOGE("%s: sync_wait error!! error no = %d err str = %s",
- __FUNCTION__, errno, strerror(errno));
- }
- close(list->hwLayers[i].acquireFenceFd);
- list->hwLayers[i].acquireFenceFd = -1;
- }
- /*
- * Find the intersection of layer display frame with PTOR layer
- * with respect to screen co-ordinates
- *
- * Calculated the destination rect by transforming the overlapping
- * region of layer display frame with respect to PTOR display frame
- *
- * Transform the destination rect on to render buffer
- * */
- hwc_rect_t destRect = getIntersection(overlap, layer->displayFrame);
- destRect.left = destRect.left - overlap.left +
- ptorInfo->displayFrame[j].left;
- destRect.right = destRect.right- overlap.left +
- ptorInfo->displayFrame[j].left;
- destRect.top = destRect.top - overlap.top +
- ptorInfo->displayFrame[j].top;
- destRect.bottom = destRect.bottom - overlap.top +
- ptorInfo->displayFrame[j].top;
-
- int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer,
- overlap, destRect);
- copybitLayerCount++;
- if(retVal < 0) {
- ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
- copybitLayerCount = 0;
- }
- }
- }
-
- if (copybitLayerCount) {
- copybit_device_t *copybit = getCopyBitDevice();
- copybit->flush_get_fence(copybit, &fd);
- }
-
- ALOGD_IF(DEBUG_COPYBIT, "%s: done! copybitLayerCount = %d", __FUNCTION__,
- copybitLayerCount);
- return fd;
-}
-
-int CopyBit::drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
- private_handle_t *renderBuffer, hwc_rect_t overlap,
- hwc_rect_t destRect)
-{
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- if (!ctx) {
- ALOGE("%s: null context ", __FUNCTION__);
- return -1;
- }
-
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if (!hnd) {
- ALOGE("%s: invalid handle", __FUNCTION__);
- return -1;
- }
-
- private_handle_t *dstHandle = (private_handle_t *)renderBuffer;
- if (!dstHandle) {
- ALOGE("%s: RenderBuffer handle is NULL", __FUNCTION__);
- return -1;
- }
-
- // Set the Copybit Source
- copybit_image_t src;
- src.handle = (native_handle_t *)layer->handle;
- src.w = hnd->width;
- src.h = hnd->height;
- src.base = (void *)hnd->base;
- src.format = hnd->format;
- src.horiz_padding = 0;
- src.vert_padding = 0;
-
-
- hwc_rect_t dispFrame = layer->displayFrame;
- hwc_rect_t iRect = getIntersection(dispFrame, overlap);
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- qhwc::calculate_crop_rects(crop, dispFrame, iRect,
- layer->transform);
-
- // Copybit source rect
- copybit_rect_t srcRect = {crop.left, crop.top, crop.right,
- crop.bottom};
-
- // Copybit destination rect
- copybit_rect_t dstRect = {destRect.left, destRect.top, destRect.right,
- destRect.bottom};
-
- // Copybit dst
- copybit_image_t dst;
- dst.handle = (native_handle_t *)dstHandle;
- dst.w = ALIGN(dstHandle->width, 32);
- dst.h = dstHandle->height;
- dst.base = (void *)dstHandle->base;
- dst.format = dstHandle->format;
-
- copybit_device_t *copybit = mEngine;
-
- // Copybit region is the destRect
- hwc_rect_t regRect = {dstRect.l,dstRect.t, dstRect.r, dstRect.b};
- hwc_region_t region;
- region.numRects = 1;
- region.rects = ®Rect;
- region_iterator copybitRegion(region);
- int acquireFd = layer->acquireFenceFd;
-
- copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
- renderBuffer->width);
- copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
- renderBuffer->height);
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform);
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
- copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
- copybit->set_parameter(copybit, COPYBIT_DITHER,
- (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE :
- COPYBIT_DISABLE);
- copybit->set_sync(copybit, acquireFd);
- int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
- ©bitRegion);
-
- if (err < 0)
- ALOGE("%s: copybit stretch failed",__FUNCTION__);
-
- return err;
-}
-
-int CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
- private_handle_t *renderBuffer, bool isFG)
-{
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- int err = 0, acquireFd;
- if(!ctx) {
- ALOGE("%s: null context ", __FUNCTION__);
- return -1;
- }
-
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(!hnd) {
- if (layer->flags & HWC_COLOR_FILL) { // Color layer
- return fillColorUsingCopybit(layer, renderBuffer);
- }
- ALOGE("%s: invalid handle", __FUNCTION__);
- return -1;
- }
-
- private_handle_t *fbHandle = (private_handle_t *)renderBuffer;
- if(!fbHandle) {
- ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
- return -1;
- }
- uint32_t dynamic_fps = 0;
-#ifdef DYNAMIC_FPS
- MetaData_t *mdata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
- if (mdata && (mdata->operation & UPDATE_REFRESH_RATE)) {
- dynamic_fps = roundOff(mdata->refreshrate);
- }
-#endif
- // Set the copybit source:
- copybit_image_t src;
- src.w = getWidth(hnd);
- src.h = getHeight(hnd);
- src.format = hnd->format;
-
- // Handle R/B swap
- if ((layer->flags & HWC_FORMAT_RB_SWAP)) {
- if (src.format == HAL_PIXEL_FORMAT_RGBA_8888) {
- src.format = HAL_PIXEL_FORMAT_BGRA_8888;
- } else if (src.format == HAL_PIXEL_FORMAT_RGBX_8888) {
- src.format = HAL_PIXEL_FORMAT_BGRX_8888;
- }
- }
-
- src.base = (void *)hnd->base;
- src.handle = (native_handle_t *)layer->handle;
- src.horiz_padding = src.w - getWidth(hnd);
- // Initialize vertical padding to zero for now,
- // this needs to change to accomodate vertical stride
- // if needed in the future
- src.vert_padding = 0;
-
- int layerTransform = layer->transform ;
- // When flip and rotation(90) are present alter the flip,
- // as GPU is doing the flip and rotation in opposite order
- // to that of MDP3.0
- // For 270 degrees, we get 90 + (H+V) which is same as doing
- // flip first and then rotation (H+V) + 90
- if (qdutils::MDPVersion::getInstance().getMDPVersion() < 400) {
- if (((layer->transform& HAL_TRANSFORM_FLIP_H) ||
- (layer->transform & HAL_TRANSFORM_FLIP_V)) &&
- (layer->transform & HAL_TRANSFORM_ROT_90) &&
- !(layer->transform == HAL_TRANSFORM_ROT_270)){
- if(layer->transform & HAL_TRANSFORM_FLIP_H){
- layerTransform ^= HAL_TRANSFORM_FLIP_H;
- layerTransform |= HAL_TRANSFORM_FLIP_V;
- }
- if(layer->transform & HAL_TRANSFORM_FLIP_V){
- layerTransform ^= HAL_TRANSFORM_FLIP_V;
- layerTransform |= HAL_TRANSFORM_FLIP_H;
- }
- }
- }
- // Copybit source rect
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
- copybit_rect_t srcRect = {sourceCrop.left, sourceCrop.top,
- sourceCrop.right,
- sourceCrop.bottom};
-
- // Copybit destination rect
- hwc_rect_t displayFrame = layer->displayFrame;
- copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
- displayFrame.right,
- displayFrame.bottom};
-#ifdef QTI_BSP
- //change src and dst with dirtyRect
- if(mSwapRect) {
- hwc_rect_t result = getIntersection(displayFrame, mDirtyRect);
- if(!isValidRect(result))
- return true;
- dstRect.l = result.left;
- dstRect.t = result.top;
- dstRect.r = result.right;
- dstRect.b = result.bottom;
-
- srcRect.l += (result.left - displayFrame.left);
- srcRect.t += (result.top - displayFrame.top);
- srcRect.r -= (displayFrame.right - result.right);
- srcRect.b -= (displayFrame.bottom - result.bottom);
- }
-#endif
- // Copybit dst
- copybit_image_t dst;
- dst.w = ALIGN(fbHandle->width,32);
- dst.h = fbHandle->height;
- dst.format = fbHandle->format;
- dst.base = (void *)fbHandle->base;
- dst.handle = (native_handle_t *)fbHandle;
-
- copybit_device_t *copybit = mEngine;
-
- int32_t screen_w = displayFrame.right - displayFrame.left;
- int32_t screen_h = displayFrame.bottom - displayFrame.top;
- int32_t src_crop_width = sourceCrop.right - sourceCrop.left;
- int32_t src_crop_height = sourceCrop.bottom -sourceCrop.top;
-
- // Copybit dst
- float copybitsMaxScale =
- (float)copybit->get(copybit,COPYBIT_MAGNIFICATION_LIMIT);
- float copybitsMinScale =
- (float)copybit->get(copybit,COPYBIT_MINIFICATION_LIMIT);
-
- if (layer->transform & HWC_TRANSFORM_ROT_90) {
- //swap screen width and height
- int tmp = screen_w;
- screen_w = screen_h;
- screen_h = tmp;
- }
- private_handle_t *tmpHnd = NULL;
-
- if(screen_w <=0 || screen_h<=0 ||src_crop_width<=0 || src_crop_height<=0 ) {
- ALOGE("%s: wrong params for display screen_w=%d src_crop_width=%d \
- screen_h=%d src_crop_height=%d", __FUNCTION__, screen_w,
- src_crop_width,screen_h,src_crop_height);
- return -1;
- }
-
- float dsdx = (float)screen_w/(float)src_crop_width;
- float dtdy = (float)screen_h/(float)src_crop_height;
-
- float scaleLimitMax = copybitsMaxScale * copybitsMaxScale;
- float scaleLimitMin = copybitsMinScale * copybitsMinScale;
- if(dsdx > scaleLimitMax ||
- dtdy > scaleLimitMax ||
- dsdx < 1/scaleLimitMin ||
- dtdy < 1/scaleLimitMin) {
- ALOGW("%s: greater than max supported size dsdx=%f dtdy=%f \
- scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy,
- scaleLimitMax,1/scaleLimitMin);
- return -1;
- }
- acquireFd = layer->acquireFenceFd;
- if(dsdx > copybitsMaxScale ||
- dtdy > copybitsMaxScale ||
- dsdx < 1/copybitsMinScale ||
- dtdy < 1/copybitsMinScale){
- // The requested scale is out of the range the hardware
- // can support.
- ALOGD("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,\
- copybitsMinScale=%f,screen_w=%d,screen_h=%d \
- src_crop_width=%d src_crop_height=%d",__FUNCTION__,__LINE__,
- dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h,
- src_crop_width,src_crop_height);
-
-
- int tmp_w = src_crop_width;
- int tmp_h = src_crop_height;
-
- if (dsdx > copybitsMaxScale)
- tmp_w = (int)((float)src_crop_width*copybitsMaxScale);
- if (dtdy > copybitsMaxScale)
- tmp_h = (int)((float)src_crop_height*copybitsMaxScale);
- // ceil the tmp_w and tmp_h value to maintain proper ratio
- // b/w src and dst (should not cross the desired scale limit
- // due to float -> int )
- if (dsdx < 1/copybitsMinScale)
- tmp_w = (int)ceil((float)src_crop_width/copybitsMinScale);
- if (dtdy < 1/copybitsMinScale)
- tmp_h = (int)ceil((float)src_crop_height/copybitsMinScale);
-
- ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
-
- int usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
- int format = fbHandle->format;
-
- // We do not want copybit to generate alpha values from nothing
- if (format == HAL_PIXEL_FORMAT_RGBA_8888 &&
- src.format != HAL_PIXEL_FORMAT_RGBA_8888) {
- format = HAL_PIXEL_FORMAT_RGBX_8888;
- }
- if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, format, usage) && tmpHnd) {
- copybit_image_t tmp_dst;
- copybit_rect_t tmp_rect;
- tmp_dst.w = tmp_w;
- tmp_dst.h = tmp_h;
- tmp_dst.format = tmpHnd->format;
- tmp_dst.handle = tmpHnd;
- tmp_dst.horiz_padding = src.horiz_padding;
- tmp_dst.vert_padding = src.vert_padding;
- tmp_rect.l = 0;
- tmp_rect.t = 0;
- tmp_rect.r = tmp_dst.w;
- tmp_rect.b = tmp_dst.h;
- //create one clip region
- hwc_rect tmp_hwc_rect = {0,0,tmp_rect.r,tmp_rect.b};
- hwc_region_t tmp_hwc_reg = {1,(hwc_rect_t const*)&tmp_hwc_rect};
- region_iterator tmp_it(tmp_hwc_reg);
- copybit->set_parameter(copybit,COPYBIT_TRANSFORM,0);
- //TODO: once, we are able to read layer alpha, update this
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
- copybit->set_sync(copybit, acquireFd);
- err = copybit->stretch(copybit,&tmp_dst, &src, &tmp_rect,
- &srcRect, &tmp_it);
- if(err < 0){
- ALOGE("%s:%d::tmp copybit stretch failed",__FUNCTION__,
- __LINE__);
- if(tmpHnd)
- free_buffer(tmpHnd);
- return err;
- }
- // use release fence as aquire fd for next stretch
- if (ctx->mMDP.version < qdutils::MDP_V4_0) {
- copybit->flush_get_fence(copybit, &acquireFd);
- close(acquireFd);
- acquireFd = -1;
- }
- // copy new src and src rect crop
- src = tmp_dst;
- srcRect = tmp_rect;
- }
- }
- // Copybit region
- hwc_region_t region = layer->visibleRegionScreen;
- //Do not use visible regions in case of scaling
- if (region.numRects > 1) {
- if (needsScaling(layer)) {
- region.numRects = 1;
- region.rects = &layer->displayFrame;
- }
- }
-
- region_iterator copybitRegion(region);
-
- copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
- renderBuffer->width);
- copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
- renderBuffer->height);
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM,
- layerTransform);
- //TODO: once, we are able to read layer alpha, update this
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
- copybit->set_parameter(copybit, COPYBIT_DYNAMIC_FPS, dynamic_fps);
- copybit->set_parameter(copybit, COPYBIT_BLEND_MODE,
- layer->blending);
- copybit->set_parameter(copybit, COPYBIT_DITHER,
- (dst.format == HAL_PIXEL_FORMAT_RGB_565)?
- COPYBIT_ENABLE : COPYBIT_DISABLE);
- copybit->set_parameter(copybit, COPYBIT_FG_LAYER,
- (layer->blending == HWC_BLENDING_NONE || isFG ) ?
- COPYBIT_ENABLE : COPYBIT_DISABLE);
-
- copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
- COPYBIT_ENABLE);
- copybit->set_sync(copybit, acquireFd);
- err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
- ©bitRegion);
- copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
- COPYBIT_DISABLE);
-
- if(tmpHnd) {
- if (ctx->mMDP.version < qdutils::MDP_V4_0){
- int ret = -1, releaseFd;
- // we need to wait for the buffer before freeing
- copybit->flush_get_fence(copybit, &releaseFd);
- ret = sync_wait(releaseFd, 1000);
- if(ret < 0) {
- ALOGE("%s: sync_wait error!! error no = %d err str = %s",
- __FUNCTION__, errno, strerror(errno));
- }
- close(releaseFd);
- }
- free_buffer(tmpHnd);
- }
-
- if(err < 0)
- ALOGE("%s: copybit stretch failed",__FUNCTION__);
- return err;
-}
-
-int CopyBit::fillColorUsingCopybit(hwc_layer_1_t *layer,
- private_handle_t *renderBuffer)
-{
- if (!renderBuffer) {
- ALOGE("%s: Render Buffer is NULL", __FUNCTION__);
- return -1;
- }
-
- // Copybit dst
- copybit_image_t dst;
- dst.w = ALIGN(renderBuffer->width, 32);
- dst.h = renderBuffer->height;
- dst.format = renderBuffer->format;
- dst.base = (void *)renderBuffer->base;
- dst.handle = (native_handle_t *)renderBuffer;
-
- // Copybit dst rect
- hwc_rect_t displayFrame = layer->displayFrame;
- copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
- displayFrame.right, displayFrame.bottom};
-
- uint32_t color = layer->transform;
- copybit_device_t *copybit = mEngine;
- copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
- renderBuffer->width);
- copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
- renderBuffer->height);
- copybit->set_parameter(copybit, COPYBIT_DITHER,
- (dst.format == HAL_PIXEL_FORMAT_RGB_565) ?
- COPYBIT_ENABLE : COPYBIT_DISABLE);
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
- copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
- copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_ENABLE);
- int res = copybit->fill_color(copybit, &dst, &dstRect, color);
- copybit->set_parameter(copybit,COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_DISABLE);
- return res;
-}
-
-void CopyBit::getLayerResolution(const hwc_layer_1_t* layer,
- unsigned int& width, unsigned int& height)
-{
- hwc_rect_t result = layer->displayFrame;
- if (mSwapRect)
- result = getIntersection(mDirtyRect, result);
-
- width = result.right - result.left;
- height = result.bottom - result.top;
-}
-
-bool CopyBit::validateParams(hwc_context_t *ctx,
- const hwc_display_contents_1_t *list) {
- //Validate parameters
- if (!ctx) {
- ALOGE("%s:Invalid HWC context", __FUNCTION__);
- return false;
- } else if (!list) {
- ALOGE("%s:Invalid HWC layer list", __FUNCTION__);
- return false;
- }
- return true;
-}
-
-
-int CopyBit::allocRenderBuffers(int w, int h, int f)
-{
- int ret = 0;
- for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
- if (mRenderBuffer[i] == NULL) {
- ret = alloc_buffer(&mRenderBuffer[i],
- w, h, f,
- GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
- }
- if(ret < 0) {
- freeRenderBuffers();
- break;
- }
- }
- return ret;
-}
-
-void CopyBit::freeRenderBuffers()
-{
- for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
- if(mRenderBuffer[i]) {
- //Since we are freeing buffer close the fence if it has a valid one.
- if(mRelFd[i] >= 0) {
- close(mRelFd[i]);
- mRelFd[i] = -1;
- }
- free_buffer(mRenderBuffer[i]);
- mRenderBuffer[i] = NULL;
- }
- }
-}
-
-private_handle_t * CopyBit::getCurrentRenderBuffer() {
- return mRenderBuffer[mCurRenderBufferIndex];
-}
-
-void CopyBit::setReleaseFd(int fd) {
- if(mRelFd[mCurRenderBufferIndex] >=0)
- close(mRelFd[mCurRenderBufferIndex]);
- mRelFd[mCurRenderBufferIndex] = dup(fd);
-}
-
-void CopyBit::setReleaseFdSync(int fd) {
- if (mRelFd[mCurRenderBufferIndex] >=0) {
- int ret = -1;
- ret = sync_wait(mRelFd[mCurRenderBufferIndex], 1000);
- if (ret < 0)
- ALOGE("%s: sync_wait error! errno = %d, err str = %s",
- __FUNCTION__, errno, strerror(errno));
- close(mRelFd[mCurRenderBufferIndex]);
- }
- mRelFd[mCurRenderBufferIndex] = dup(fd);
-}
-
-struct copybit_device_t* CopyBit::getCopyBitDevice() {
- return mEngine;
-}
-
-CopyBit::CopyBit(hwc_context_t *ctx, const int& dpy) : mEngine(0),
- mIsModeOn(false), mCopyBitDraw(false), mCurRenderBufferIndex(0) {
-
- getBufferSizeAndDimensions(ctx->dpyAttr[dpy].xres,
- ctx->dpyAttr[dpy].yres,
- HAL_PIXEL_FORMAT_RGBA_8888,
- mAlignedWidth,
- mAlignedHeight);
-
- hw_module_t const *module;
- for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
- mRenderBuffer[i] = NULL;
- mRelFd[i] = -1;
- }
-
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.hwc.dynThreshold", value, "2");
- mDynThreshold = atof(value);
-
- property_get("debug.sf.swaprect", value, "0");
- mSwapRectEnable = atoi(value) ? true:false ;
- mSwapRect = 0;
- if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
- if(copybit_open(module, &mEngine) < 0) {
- ALOGE("FATAL ERROR: copybit open failed.");
- }
- } else {
- ALOGE("FATAL ERROR: copybit hw module not found");
- }
-}
-
-CopyBit::~CopyBit()
-{
- freeRenderBuffers();
- if(mEngine)
- {
- copybit_close(mEngine);
- mEngine = NULL;
- }
-}
-CopyBit::LayerCache::LayerCache() {
- reset();
-}
-void CopyBit::LayerCache::reset() {
- memset(&hnd, 0, sizeof(hnd));
- layerCount = 0;
-}
-void CopyBit::LayerCache::updateCounts(hwc_context_t *ctx,
- hwc_display_contents_1_t *list, int dpy)
-{
- layerCount = ctx->listStats[dpy].numAppLayers;
- for (int i=0; i<ctx->listStats[dpy].numAppLayers; i++){
- hnd[i] = list->hwLayers[i].handle;
- displayFrame[i] = list->hwLayers[i].displayFrame;
- drop[i] = ctx->copybitDrop[i];
- }
-}
-
-CopyBit::FbCache::FbCache() {
- reset();
-}
-void CopyBit::FbCache::reset() {
- memset(&FbdirtyRect, 0, sizeof(FbdirtyRect));
- memset(&FbdisplayRect, 0, sizeof(FbdisplayRect));
- FbIndex =0;
-}
-
-void CopyBit::FbCache::insertAndUpdateFbCache(hwc_rect_t dirtyRect,
- hwc_rect_t displayRect) {
- FbIndex = FbIndex % NUM_RENDER_BUFFERS;
- FbdirtyRect[FbIndex] = dirtyRect;
- FbdisplayRect[FbIndex] = displayRect;
- FbIndex++;
-}
-
-int CopyBit::FbCache::getUnchangedFbDRCount(hwc_rect_t dirtyRect,
- hwc_rect_t displayRect){
- int sameDirtyCount = 0;
- for (int i = 0 ; i < NUM_RENDER_BUFFERS ; i++ ){
- if( FbdirtyRect[i] == dirtyRect &&
- FbdisplayRect[i] == displayRect)
- sameDirtyCount++;
- }
- return sameDirtyCount;
-}
-
-}; //namespace qhwc
diff --git a/msm8909/libhwcomposer/hwc_copybit.h b/msm8909/libhwcomposer/hwc_copybit.h
deleted file mode 100644
index c527a4e..0000000
--- a/msm8909/libhwcomposer/hwc_copybit.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 HWC_COPYBIT_H
-#define HWC_COPYBIT_H
-#include "hwc_utils.h"
-
-#define NUM_RENDER_BUFFERS 3
-//These scaling factors are specific for MDP3. Normally scaling factor
-//is only 4, but copybit will create temp buffer to let it run through
-//twice
-#define MAX_SCALE_FACTOR 16
-#define MIN_SCALE_FACTOR 0.0625
-#define MAX_LAYERS_FOR_ABC 2
-#define INVALID_DIMENSION -1
-#define NO_UPDATING_LAYER -2
-namespace qhwc {
-
-class CopyBit {
-public:
- CopyBit(hwc_context_t *ctx, const int& dpy);
- ~CopyBit();
- // API to get copybit engine(non static)
- struct copybit_device_t *getCopyBitDevice();
- //Sets up members and prepares copybit if conditions are met
- bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
- int dpy);
- //Draws layer if the layer is set for copybit in prepare
- bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
- int dpy, int* fd);
- // resets the values
- void reset();
-
- private_handle_t * getCurrentRenderBuffer();
-
- void setReleaseFd(int fd);
-
- void setReleaseFdSync(int fd);
-
- bool prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-
- int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-
-private:
- /* cached data */
- struct LayerCache {
- int layerCount;
- buffer_handle_t hnd[MAX_NUM_APP_LAYERS];
- hwc_rect_t displayFrame[MAX_NUM_APP_LAYERS];
- bool drop[MAX_NUM_APP_LAYERS];
- /* c'tor */
- LayerCache();
- /* clear caching info*/
- void reset();
- void updateCounts(hwc_context_t *ctx, hwc_display_contents_1_t *list,
- int dpy);
- };
- /* framebuffer cache*/
- struct FbCache {
- hwc_rect_t FbdirtyRect[NUM_RENDER_BUFFERS];
- hwc_rect_t FbdisplayRect[NUM_RENDER_BUFFERS];
- int FbIndex;
- FbCache();
- void reset();
- void insertAndUpdateFbCache(hwc_rect_t dirtyRect,
- hwc_rect_t displayRect);
- int getUnchangedFbDRCount(hwc_rect_t dirtyRect,
- hwc_rect_t displayRect);
- };
-
- // holds the copybit device
- struct copybit_device_t *mEngine;
- bool drawUsingAppBufferComposition(hwc_context_t *ctx,
- hwc_display_contents_1_t *list,
- int dpy, int *fd);
- // Helper functions for copybit composition
- int drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
- private_handle_t *renderBuffer, bool isFG);
- // Helper function to draw copybit layer for PTOR comp
- int drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
- private_handle_t *renderBuffer, hwc_rect_t overlap,
- hwc_rect_t destRect);
- int fillColorUsingCopybit(hwc_layer_1_t *layer,
- private_handle_t *renderBuffer);
- bool canUseCopybitForYUV (hwc_context_t *ctx);
- bool canUseCopybitForRGB (hwc_context_t *ctx,
- hwc_display_contents_1_t *list, int dpy);
- bool validateParams (hwc_context_t *ctx,
- const hwc_display_contents_1_t *list);
- //Flags if this feature is on.
- bool mIsModeOn;
- // flag that indicates whether CopyBit composition is enabled for this cycle
- bool mCopyBitDraw;
-
- unsigned int getRGBRenderingArea (const hwc_context_t *ctx,
- const hwc_display_contents_1_t *list);
-
- void getLayerResolution(const hwc_layer_1_t* layer,
- unsigned int &width, unsigned int& height);
-
- int allocRenderBuffers(int w, int h, int f);
-
- void freeRenderBuffers();
-
- int clear (private_handle_t* hnd, hwc_rect_t& rect);
-
- private_handle_t* mRenderBuffer[NUM_RENDER_BUFFERS];
-
- // Index of the current intermediate render buffer
- int mCurRenderBufferIndex;
-
- // Release FDs of the intermediate render buffer
- int mRelFd[NUM_RENDER_BUFFERS];
-
- //Dynamic composition threshold for deciding copybit usage.
- double mDynThreshold;
- bool mSwapRectEnable;
- int mAlignedWidth;
- int mAlignedHeight;
- int mSwapRect;
- LayerCache mLayerCache;
- FbCache mFbCache;
- hwc_rect_t mDirtyRect;
- bool prepareSwapRect(hwc_context_t *ctx, hwc_display_contents_1_t *list,
- int dpy);
- bool isLayerChanging(hwc_context_t *ctx,
- hwc_display_contents_1_t *list, int k);
- bool isSmartBlitPossible(const hwc_display_contents_1_t *list);
-};
-
-}; //namespace qhwc
-
-#endif //HWC_COPYBIT_H
diff --git a/msm8909/libhwcomposer/hwc_dump_layers.cpp b/msm8909/libhwcomposer/hwc_dump_layers.cpp
deleted file mode 100644
index 7833823..0000000
--- a/msm8909/libhwcomposer/hwc_dump_layers.cpp
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright (c) 2012-2014,2016 Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LOG_TAG
-#define LOG_TAG "qsfdump"
-#endif
-#define LOG_NDEBUG 0
-#include <hwc_utils.h>
-#include <hwc_dump_layers.h>
-#include <cutils/log.h>
-#include <sys/stat.h>
-#include <comptype.h>
-#ifdef QTI_BSP
-// Ignore W(float)conversion errors for external headers
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wconversion"
-#pragma GCC diagnostic ignored "-Wfloat-conversion"
-#include <SkBitmap.h>
-#include <SkImageEncoder.h>
-#pragma GCC diagnostic pop
-#endif
-#ifdef STDC_FORMAT_MACROS
-#include <inttypes.h>
-#endif
-
-namespace qhwc {
-
-// MAX_ALLOWED_FRAMEDUMPS must be capped to (LONG_MAX - 1)
-// 60fps => 216000 frames per hour
-// Below setting of 216000 * 24 * 7 => 1 week or 168 hours of capture.
- enum {
- MAX_ALLOWED_FRAMEDUMPS = (216000 * 24 * 7)
- };
-
-bool HwcDebug::sDumpEnable = false;
-
-HwcDebug::HwcDebug(uint32_t dpy):
- mDumpCntLimRaw(0),
- mDumpCntrRaw(1),
- mDumpCntLimPng(0),
- mDumpCntrPng(1),
- mDpy(dpy) {
- char dumpPropStr[PROPERTY_VALUE_MAX];
- if(mDpy) {
- strlcpy(mDisplayName, "external", sizeof(mDisplayName));
- } else {
- strlcpy(mDisplayName, "primary", sizeof(mDisplayName));
- }
- snprintf(mDumpPropKeyDisplayType, sizeof(mDumpPropKeyDisplayType),
- "debug.sf.dump.%s", (char *)mDisplayName);
-
- if ((property_get("debug.sf.dump.enable", dumpPropStr, NULL) > 0)) {
- if(!strncmp(dumpPropStr, "true", strlen("true"))) {
- sDumpEnable = true;
- }
- }
-}
-
-void HwcDebug::dumpLayers(hwc_display_contents_1_t* list)
-{
- // Check need for dumping layers for debugging.
- if (UNLIKELY(sDumpEnable) && UNLIKELY(needToDumpLayers()) && LIKELY(list)) {
- logHwcProps(list->flags);
- for (size_t i = 0; i < list->numHwLayers; i++) {
- logLayer(i, list->hwLayers);
- dumpLayer(i, list->hwLayers);
- }
- }
-}
-
-bool HwcDebug::needToDumpLayers()
-{
- bool bDumpLayer = false;
- char dumpPropStr[PROPERTY_VALUE_MAX];
- // Enable primary dump and disable external dump by default.
- bool bDumpEnable = !mDpy;
- time_t timeNow;
- tm dumpTime;
-
- // Override the bDumpEnable based on the property value, if the property
- // is present in the build.prop file.
- if ((property_get(mDumpPropKeyDisplayType, dumpPropStr, NULL) > 0)) {
- if(!strncmp(dumpPropStr, "true", strlen("true")))
- bDumpEnable = true;
- else
- bDumpEnable = false;
- }
-
- if (false == bDumpEnable)
- return false;
-
- time(&timeNow);
- localtime_r(&timeNow, &dumpTime);
-
- if ((property_get("debug.sf.dump.png", dumpPropStr, NULL) > 0) &&
- (strncmp(dumpPropStr, mDumpPropStrPng, PROPERTY_VALUE_MAX - 1))) {
- // Strings exist & not equal implies it has changed, so trigger a dump
- strlcpy(mDumpPropStrPng, dumpPropStr, sizeof(mDumpPropStrPng));
- mDumpCntLimPng = atoi(dumpPropStr);
- if (mDumpCntLimPng > MAX_ALLOWED_FRAMEDUMPS) {
- ALOGW("Warning: Using debug.sf.dump.png %d (= max)",
- MAX_ALLOWED_FRAMEDUMPS);
- mDumpCntLimPng = MAX_ALLOWED_FRAMEDUMPS;
- }
- mDumpCntLimPng = (mDumpCntLimPng < 0) ? 0: mDumpCntLimPng;
- if (mDumpCntLimPng) {
- snprintf(mDumpDirPng, sizeof(mDumpDirPng),
- "/data/sfdump.png.%04d.%02d.%02d.%02d.%02d.%02d",
- dumpTime.tm_year + 1900, dumpTime.tm_mon + 1,
- dumpTime.tm_mday, dumpTime.tm_hour,
- dumpTime.tm_min, dumpTime.tm_sec);
- if (0 == mkdir(mDumpDirPng, 0777))
- mDumpCntrPng = 0;
- else {
- ALOGE("Error: %s. Failed to create sfdump directory: %s",
- strerror(errno), mDumpDirPng);
- mDumpCntrPng = mDumpCntLimPng + 1;
- }
- }
- }
-
- if (mDumpCntrPng <= mDumpCntLimPng)
- mDumpCntrPng++;
-
- if ((property_get("debug.sf.dump", dumpPropStr, NULL) > 0) &&
- (strncmp(dumpPropStr, mDumpPropStrRaw, PROPERTY_VALUE_MAX - 1))) {
- // Strings exist & not equal implies it has changed, so trigger a dump
- strlcpy(mDumpPropStrRaw, dumpPropStr, sizeof(mDumpPropStrRaw));
- mDumpCntLimRaw = atoi(dumpPropStr);
- if (mDumpCntLimRaw > MAX_ALLOWED_FRAMEDUMPS) {
- ALOGW("Warning: Using debug.sf.dump %d (= max)",
- MAX_ALLOWED_FRAMEDUMPS);
- mDumpCntLimRaw = MAX_ALLOWED_FRAMEDUMPS;
- }
- mDumpCntLimRaw = (mDumpCntLimRaw < 0) ? 0: mDumpCntLimRaw;
- if (mDumpCntLimRaw) {
- snprintf(mDumpDirRaw, sizeof(mDumpDirRaw),
- "/data/sfdump.raw.%04d.%02d.%02d.%02d.%02d.%02d",
- dumpTime.tm_year + 1900, dumpTime.tm_mon + 1,
- dumpTime.tm_mday, dumpTime.tm_hour,
- dumpTime.tm_min, dumpTime.tm_sec);
- if (0 == mkdir(mDumpDirRaw, 0777))
- mDumpCntrRaw = 0;
- else {
- ALOGE("Error: %s. Failed to create sfdump directory: %s",
- strerror(errno), mDumpDirRaw);
- mDumpCntrRaw = mDumpCntLimRaw + 1;
- }
- }
- }
-
- if (mDumpCntrRaw <= mDumpCntLimRaw)
- mDumpCntrRaw++;
-
- bDumpLayer = (mDumpCntLimPng || mDumpCntLimRaw)? true : false;
- return bDumpLayer;
-}
-
-void HwcDebug::logHwcProps(uint32_t listFlags)
-{
- static int hwcModuleCompType = -1;
- static int sMdpCompMaxLayers = 0;
- static String8 hwcModuleCompTypeLog("");
- if (-1 == hwcModuleCompType) {
- // One time stuff
- char mdpCompPropStr[PROPERTY_VALUE_MAX];
- if (property_get("debug.mdpcomp.maxlayer", mdpCompPropStr, NULL) > 0) {
- sMdpCompMaxLayers = atoi(mdpCompPropStr);
- }
- hwcModuleCompType =
- qdutils::QCCompositionType::getInstance().getCompositionType();
- hwcModuleCompTypeLog.appendFormat("%s%s%s%s%s%s",
- // Is hwc module composition type now a bit-field?!
- (hwcModuleCompType == qdutils::COMPOSITION_TYPE_GPU)?
- "[GPU]": "",
- (hwcModuleCompType & qdutils::COMPOSITION_TYPE_MDP)?
- "[MDP]": "",
- (hwcModuleCompType & qdutils::COMPOSITION_TYPE_C2D)?
- "[C2D]": "",
- (hwcModuleCompType & qdutils::COMPOSITION_TYPE_CPU)?
- "[CPU]": "",
- (hwcModuleCompType & qdutils::COMPOSITION_TYPE_DYN)?
- "[DYN]": "",
- (hwcModuleCompType >= (qdutils::COMPOSITION_TYPE_DYN << 1))?
- "[???]": "");
- }
- ALOGI("Display[%s] Layer[*] %s-HwcModuleCompType, %d-layer MdpComp %s",
- mDisplayName, hwcModuleCompTypeLog.string(), sMdpCompMaxLayers,
- (listFlags & HWC_GEOMETRY_CHANGED)? "[HwcList Geometry Changed]": "");
-}
-
-void HwcDebug::logLayer(size_t layerIndex, hwc_layer_1_t hwLayers[])
-{
- if (NULL == hwLayers) {
- ALOGE("Display[%s] Layer[%zu] Error. No hwc layers to log.",
- mDisplayName, layerIndex);
- return;
- }
-
- hwc_layer_1_t *layer = &hwLayers[layerIndex];
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t displayFrame = layer->displayFrame;
- size_t numHwcRects = layer->visibleRegionScreen.numRects;
- hwc_rect_t const *hwcRects = layer->visibleRegionScreen.rects;
- private_handle_t *hnd = (private_handle_t *)layer->handle;
-
- char pixFormatStr[32] = "None";
- String8 hwcVisRegsScrLog("[None]");
-
- for (size_t i = 0 ; (hwcRects && (i < numHwcRects)); i++) {
- if (0 == i)
- hwcVisRegsScrLog.clear();
- hwcVisRegsScrLog.appendFormat("[%dl, %dt, %dr, %db]",
- hwcRects[i].left, hwcRects[i].top,
- hwcRects[i].right, hwcRects[i].bottom);
- }
-
- if (hnd)
- getHalPixelFormatStr(hnd->format, pixFormatStr, sizeof(pixFormatStr));
-
- // Log Line 1
- ALOGI("Display[%s] Layer[%zu] SrcBuff[%dx%d] SrcCrop[%dl, %dt, %dr, %db] "
- "DispFrame[%dl, %dt, %dr, %db] VisRegsScr%s", mDisplayName, layerIndex,
- (hnd)? getWidth(hnd) : -1, (hnd)? getHeight(hnd) : -1,
- sourceCrop.left, sourceCrop.top,
- sourceCrop.right, sourceCrop.bottom,
- displayFrame.left, displayFrame.top,
- displayFrame.right, displayFrame.bottom,
- hwcVisRegsScrLog.string());
- // Log Line 2
- ALOGI("Display[%s] Layer[%zu] LayerCompType = %s, Format = %s, "
- "Orientation = %s, Flags = %s%s%s, Hints = %s%s%s, "
- "Blending = %s%s%s", mDisplayName, layerIndex,
- (layer->compositionType == HWC_FRAMEBUFFER)? "Framebuffer(GPU)":
- (layer->compositionType == HWC_OVERLAY)? "Overlay":
- (layer->compositionType == HWC_BACKGROUND)? "Background":"???",
- pixFormatStr,
- (layer->transform == 0)? "ROT_0":
- (layer->transform == HWC_TRANSFORM_FLIP_H)? "FLIP_H":
- (layer->transform == HWC_TRANSFORM_FLIP_V)? "FLIP_V":
- (layer->transform == HWC_TRANSFORM_ROT_90)? "ROT_90":
- "ROT_INVALID",
- (layer->flags)? "": "[None]",
- (layer->flags & HWC_SKIP_LAYER)? "[Skip layer]":"",
- (layer->flags & qhwc::HWC_MDPCOMP)? "[MDP Comp]":"",
- (layer->hints)? "":"[None]",
- (layer->hints & HWC_HINT_TRIPLE_BUFFER)? "[Triple Buffer]":"",
- (layer->hints & HWC_HINT_CLEAR_FB)? "[Clear FB]":"",
- (layer->blending == HWC_BLENDING_NONE)? "[None]":"",
- (layer->blending == HWC_BLENDING_PREMULT)? "[PreMult]":"",
- (layer->blending == HWC_BLENDING_COVERAGE)? "[Coverage]":"");
-}
-
-void HwcDebug::dumpLayer(size_t layerIndex, hwc_layer_1_t hwLayers[])
-{
- char dumpLogStrPng[128] = "";
- char dumpLogStrRaw[128] = "";
- bool needDumpPng = (mDumpCntrPng <= mDumpCntLimPng)? true:false;
- bool needDumpRaw = (mDumpCntrRaw <= mDumpCntLimRaw)? true:false;
-
- if (needDumpPng) {
- snprintf(dumpLogStrPng, sizeof(dumpLogStrPng),
- "[png-dump-frame: %03d of %03d]", mDumpCntrPng,
- mDumpCntLimPng);
- }
- if (needDumpRaw) {
- snprintf(dumpLogStrRaw, sizeof(dumpLogStrRaw),
- "[raw-dump-frame: %03d of %03d]", mDumpCntrRaw,
- mDumpCntLimRaw);
- }
-
- if (!(needDumpPng || needDumpRaw))
- return;
-
- if (NULL == hwLayers) {
- ALOGE("Display[%s] Layer[%zu] %s%s Error: No hwc layers to dump.",
- mDisplayName, layerIndex, dumpLogStrRaw, dumpLogStrPng);
- return;
- }
-
- hwc_layer_1_t *layer = &hwLayers[layerIndex];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- char pixFormatStr[32] = "None";
-
- if (NULL == hnd) {
- ALOGI("Display[%s] Layer[%zu] %s%s Skipping dump: Bufferless layer.",
- mDisplayName, layerIndex, dumpLogStrRaw, dumpLogStrPng);
- return;
- }
-
- getHalPixelFormatStr(hnd->format, pixFormatStr, sizeof(pixFormatStr));
-#ifdef QTI_BSP
- if (needDumpPng && hnd->base) {
- bool bResult = false;
- char dumpFilename[PATH_MAX];
- SkColorType colorType = kUnknown_SkColorType;
- SkAlphaType alphaType = kUnknown_SkAlphaType;
- snprintf(dumpFilename, sizeof(dumpFilename),
- "%s/sfdump%03d.layer%zu.%s.png", mDumpDirPng,
- mDumpCntrPng, layerIndex, mDisplayName);
-
- switch (hnd->format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- alphaType = kPremul_SkAlphaType;
- colorType = kRGBA_8888_SkColorType;
- break;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- alphaType = kOpaque_SkAlphaType;
- colorType = kRGBA_8888_SkColorType;
- break;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- alphaType = kPremul_SkAlphaType;
- colorType = kBGRA_8888_SkColorType;
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- alphaType = kOpaque_SkAlphaType;
- colorType = kRGB_565_SkColorType;
- break;
- default:
- break;
- }
- if (kUnknown_SkColorType != colorType) {
- SkImageInfo info = SkImageInfo::Make(getWidth(hnd), getHeight(hnd),
- colorType, alphaType);
- SkPixmap pixmap(info, (const void*)hnd->base, info.minRowBytes());
- SkFILEWStream file(dumpFilename);
- bResult = SkEncodeImage(&file, pixmap, SkEncodedImageFormat::kPNG, 100);
- ALOGI("Display[%s] Layer[%zu] %s Dump to %s: %s",
- mDisplayName, layerIndex, dumpLogStrPng,
- dumpFilename, bResult ? "Success" : "Fail");
- } else {
- ALOGI("Display[%s] Layer[%zu] %s Skipping dump: Unsupported layer"
- " format %s for png encoder",
- mDisplayName, layerIndex, dumpLogStrPng, pixFormatStr);
- }
- }
-#endif
- if (needDumpRaw && hnd->base) {
- char dumpFilename[PATH_MAX];
- bool bResult = false;
- snprintf(dumpFilename, sizeof(dumpFilename),
- "%s/sfdump%03d.layer%zu.%dx%d.%s.%s.raw",
- mDumpDirRaw, mDumpCntrRaw,
- layerIndex, getWidth(hnd), getHeight(hnd),
- pixFormatStr, mDisplayName);
- FILE* fp = fopen(dumpFilename, "w+");
- if (NULL != fp) {
- bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp);
- fclose(fp);
- }
- ALOGI("Display[%s] Layer[%zu] %s Dump to %s: %s",
- mDisplayName, layerIndex, dumpLogStrRaw,
- dumpFilename, bResult ? "Success" : "Fail");
- }
-}
-
-void HwcDebug::getHalPixelFormatStr(int format, char pixFormatStr[], size_t arraySize)
-{
- if (!pixFormatStr)
- return;
-
- switch(format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- strlcpy(pixFormatStr, "RGBA_8888", arraySize);
- break;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- strlcpy(pixFormatStr, "RGBX_8888", arraySize);
- break;
- case HAL_PIXEL_FORMAT_RGB_888:
- strlcpy(pixFormatStr, "RGB_888", arraySize);
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- strlcpy(pixFormatStr, "RGB_565", arraySize);
- break;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- strlcpy(pixFormatStr, "BGRA_8888", arraySize);
- break;
- case HAL_PIXEL_FORMAT_YV12:
- strlcpy(pixFormatStr, "YV12", arraySize);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- strlcpy(pixFormatStr, "YCbCr_422_SP_NV16", arraySize);
- break;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- strlcpy(pixFormatStr, "YCrCb_420_SP_NV21", arraySize);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- strlcpy(pixFormatStr, "YCbCr_422_I_YUY2", arraySize);
- break;
- case HAL_PIXEL_FORMAT_YCrCb_422_I:
- strlcpy(pixFormatStr, "YCrCb_422_I_YVYU", arraySize);
- break;
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- strlcpy(pixFormatStr, "NV12_ENCODEABLE", arraySize);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- strlcpy(pixFormatStr, "YCbCr_420_SP_TILED_TILE_4x2",
- arraySize);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- strlcpy(pixFormatStr, "YCbCr_420_SP", arraySize);
- break;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
- strlcpy(pixFormatStr, "YCrCb_420_SP_ADRENO", arraySize);
- break;
- case HAL_PIXEL_FORMAT_YCrCb_422_SP:
- strlcpy(pixFormatStr, "YCrCb_422_SP", arraySize);
- break;
- case HAL_PIXEL_FORMAT_R_8:
- strlcpy(pixFormatStr, "R_8", arraySize);
- break;
- case HAL_PIXEL_FORMAT_RG_88:
- strlcpy(pixFormatStr, "RG_88", arraySize);
- break;
- case HAL_PIXEL_FORMAT_INTERLACE:
- strlcpy(pixFormatStr, "INTERLACE", arraySize);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- strlcpy(pixFormatStr, "YCbCr_420_SP_VENUS", arraySize);
- break;
- default:
- snprintf(pixFormatStr, arraySize, "Unknown0x%X", format);
- break;
- }
-}
-
-} // namespace qhwc
-
diff --git a/msm8909/libhwcomposer/hwc_dump_layers.h b/msm8909/libhwcomposer/hwc_dump_layers.h
deleted file mode 100644
index 83e56c0..0000000
--- a/msm8909/libhwcomposer/hwc_dump_layers.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2012-2013,2016 Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HWC_DUMP_LAYERS_H
-#define HWC_DUMP_LAYERS_H
-
-#include <gralloc_priv.h>
-#include <comptype.h>
-#include <hardware/hwcomposer.h>
-
-namespace qhwc {
-
-class HwcDebug {
-private:
-
-// Using static variables for layer dumping since "property_set("debug.sf.dump",
-// property)" does not work.
- int mDumpCntLimRaw;
- int mDumpCntrRaw;
- char mDumpPropStrRaw[PROPERTY_VALUE_MAX];
- char mDumpDirRaw[PATH_MAX];
- int mDumpCntLimPng;
- int mDumpCntrPng;
- char mDumpPropStrPng[PROPERTY_VALUE_MAX];
- char mDumpDirPng[PATH_MAX];
- uint32_t mDpy;
- char mDisplayName[PROPERTY_VALUE_MAX];
- char mDumpPropKeyDisplayType[PROPERTY_KEY_MAX];
- static bool sDumpEnable;
-
-public:
- HwcDebug(uint32_t dpy);
- ~HwcDebug() {};
-
- /*
- * Dump layers for debugging based on "debug.sf.dump*" system property.
- * See needToDumpLayers() for usage.
- *
- * @param: list - The HWC layer-list to dump.
- *
- */
- void dumpLayers(hwc_display_contents_1_t* list);
-
-/*
- * Checks if layers need to be dumped based on system property "debug.sf.dump"
- * for raw dumps and "debug.sf.dump.png" for png dumps.
- *
- * Note: Set "debug.sf.dump.primary" or "debug.sf.dump.external" as true
- * in the device's /system/build.prop file to enable layer logging/capturing
- * feature for primary or external respectively. The feature is disabled by
- * default to avoid per-frame property_get() calls.
- *
- * To turn on layer dump, set "debug.sf.dump.enable" to true in build.prop.
- * By default debug.sf.dump.primary will be set to true for user convenience.
- *
- * To turn on layer dump for primary, do,
- * adb shell setprop debug.sf.dump.primary true
- *
- * To turn on layer dump for external, do,
- * adb shell setprop debug.sf.dump.external true
- *
- * For example, to dump 25 frames in raw format, do,
- * adb shell setprop debug.sf.dump 25
- * Layers are dumped in a time-stamped location: /data/sfdump*.
- *
- * To dump 10 frames in png format, do,
- * adb shell setprop debug.sf.dump.png 10
- * To dump another 25 or so frames in raw format, do,
- * adb shell setprop debug.sf.dump 26
- *
- * To turn off logcat logging of layer-info, set both properties to 0,
- * adb shell setprop debug.sf.dump.png 0
- * adb shell setprop debug.sf.dump 0
- *
- * @return: true if layers need to be dumped (or logcat-ed).
- */
-bool needToDumpLayers();
-
-/*
- * Log a few per-frame hwc properties into logcat.
- *
- * @param: listFlags - Flags used in hwcomposer's list.
- *
- */
-void logHwcProps(uint32_t listFlags);
-
-/*
- * Log a layer's info into logcat.
- *
- * @param: layerIndex - Index of layer being dumped.
- * @param: hwLayers - Address of hwc_layer_1_t to log and dump.
- *
- */
-void logLayer(size_t layerIndex, hwc_layer_1_t hwLayers[]);
-
-/*
- * Dumps a layer buffer into raw/png files.
- *
- * @param: layerIndex - Index of layer being dumped.
- * @param: hwLayers - Address of hwc_layer_1_t to log and dump.
- *
- */
-void dumpLayer(size_t layerIndex, hwc_layer_1_t hwLayers[]);
-
-void getHalPixelFormatStr(int format, char pixelformatstr[], size_t arraySize);
-};
-
-} // namespace qhwc
-
-#endif /* HWC_DUMP_LAYERS_H */
diff --git a/msm8909/libhwcomposer/hwc_fbupdate.cpp b/msm8909/libhwcomposer/hwc_fbupdate.cpp
deleted file mode 100644
index b003266..0000000
--- a/msm8909/libhwcomposer/hwc_fbupdate.cpp
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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.
- */
-
-#define DEBUG_FBUPDATE 0
-#include <cutils/properties.h>
-#include <gralloc_priv.h>
-#include <overlay.h>
-#include <overlayRotator.h>
-#include "hwc_fbupdate.h"
-#include "mdp_version.h"
-
-using namespace qdutils;
-using namespace overlay;
-using overlay::Rotator;
-using namespace overlay::utils;
-
-namespace qhwc {
-
-namespace ovutils = overlay::utils;
-
-IFBUpdate* IFBUpdate::getObject(hwc_context_t *ctx, const int& dpy) {
- if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
- return new FBSrcSplit(ctx, dpy);
- } else if(isDisplaySplit(ctx, dpy)) {
- return new FBUpdateSplit(ctx, dpy);
- }
- return new FBUpdateNonSplit(ctx, dpy);
-}
-
-IFBUpdate::IFBUpdate(hwc_context_t *ctx, const int& dpy) : mDpy(dpy) {
- unsigned int size = 0;
- uint32_t xres = ctx->dpyAttr[mDpy].xres;
- uint32_t yres = ctx->dpyAttr[mDpy].yres;
- if (ctx->dpyAttr[dpy].customFBSize) {
- //GPU will render and compose at new resolution
- //So need to have FB at new resolution
- xres = ctx->dpyAttr[mDpy].xres_new;
- yres = ctx->dpyAttr[mDpy].yres_new;
- }
- getBufferAttributes((int)xres, (int)yres,
- ctx->dpyAttr[mDpy].fbformat,
- 0,
- mAlignedFBWidth,
- mAlignedFBHeight,
- mTileEnabled, size);
-}
-
-void IFBUpdate::reset() {
- mModeOn = false;
- mRot = NULL;
-}
-
-bool IFBUpdate::prepareAndValidate(hwc_context_t *ctx,
- hwc_display_contents_1 *list, int fbZorder) {
- hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
- mModeOn = prepare(ctx, list, layer->displayFrame, fbZorder) &&
- ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd);
- return mModeOn;
-}
-
-//================= Low res====================================
-FBUpdateNonSplit::FBUpdateNonSplit(hwc_context_t *ctx, const int& dpy):
- IFBUpdate(ctx, dpy) {}
-
-void FBUpdateNonSplit::reset() {
- IFBUpdate::reset();
- mDest = ovutils::OV_INVALID;
-}
-
-bool FBUpdateNonSplit::preRotateExtDisplay(hwc_context_t *ctx,
- hwc_layer_1_t *layer,
- ovutils::Whf &info,
- hwc_rect_t& sourceCrop,
- ovutils::eMdpFlags& mdpFlags,
- int& rotFlags)
-{
- int extOrient = getExtOrientation(ctx);
- ovutils::eTransform orient = static_cast<ovutils::eTransform >(extOrient);
- if(mDpy && (extOrient & HWC_TRANSFORM_ROT_90)) {
- mRot = ctx->mRotMgr->getNext();
- if(mRot == NULL) return false;
- ctx->mLayerRotMap[mDpy]->add(layer, mRot);
- // Composed FB content will have black bars, if the viewFrame of the
- // external is different from {0, 0, fbWidth, fbHeight}, so intersect
- // viewFrame with sourceCrop to avoid those black bars
- sourceCrop = getIntersection(sourceCrop, ctx->mViewFrame[mDpy]);
- //Configure rotator for pre-rotation
- if(configRotator(mRot, info, sourceCrop, mdpFlags, orient, 0) < 0) {
- ALOGE("%s: configRotator Failed!", __FUNCTION__);
- mRot = NULL;
- return false;
- }
- updateSource(orient, info, sourceCrop, mRot);
- rotFlags |= ovutils::ROT_PREROTATED;
- }
- return true;
-}
-
-bool FBUpdateNonSplit::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder) {
- if(!ctx->mMDP.hasOverlay) {
- ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
- __FUNCTION__);
- return false;
- }
- mModeOn = configure(ctx, list, fbUpdatingRect, fbZorder);
- return mModeOn;
-}
-
-// Configure
-bool FBUpdateNonSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder) {
- bool ret = false;
- hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
- if (LIKELY(ctx->mOverlay)) {
- overlay::Overlay& ov = *(ctx->mOverlay);
-
- ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
- ovutils::getMdpFormat(ctx->dpyAttr[mDpy].fbformat,
- mTileEnabled));
-
- Overlay::PipeSpecs pipeSpecs;
- pipeSpecs.formatClass = Overlay::FORMAT_RGB;
- pipeSpecs.needsScaling = qhwc::needsScaling(layer);
- pipeSpecs.dpy = mDpy;
- pipeSpecs.mixer = Overlay::MIXER_DEFAULT;
- pipeSpecs.fb = true;
-
- ovutils::eDest dest = ov.getPipe(pipeSpecs);
- if(dest == ovutils::OV_INVALID) { //None available
- ALOGE("%s: No pipes available to configure fb for dpy %d",
- __FUNCTION__, mDpy);
- return false;
- }
- mDest = dest;
-
- if((mDpy && ctx->deviceOrientation) &&
- ctx->listStats[mDpy].isDisplayAnimating) {
- fbZorder = 0;
- }
-
- ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
- ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
-
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t displayFrame = layer->displayFrame;
-
- // No FB update optimization on (1) Custom FB resolution,
- // (2) External Mirror mode, (3) External orientation
- if(!ctx->dpyAttr[mDpy].customFBSize && !ctx->mBufferMirrorMode
- && !ctx->mExtOrientation) {
- sourceCrop = fbUpdatingRect;
- displayFrame = fbUpdatingRect;
- }
-
- int transform = layer->transform;
- int rotFlags = ovutils::ROT_FLAGS_NONE;
-
- ovutils::eTransform orient =
- static_cast<ovutils::eTransform>(transform);
- // use ext orientation if any
- int extOrient = getExtOrientation(ctx);
-
- // Do not use getNonWormholeRegion() function to calculate the
- // sourceCrop during animation on external display and
- // Dont do wormhole calculation when extorientation is set on External
- // Dont do wormhole calculation when scaling mode is set on External
- if(ctx->listStats[mDpy].isDisplayAnimating && mDpy) {
- sourceCrop = layer->displayFrame;
- } else if((mDpy && !extOrient
- && !ctx->dpyAttr[mDpy].mMDPScalingMode)) {
- if(ctx->mOverlay->isUIScalingOnExternalSupported() &&
- !ctx->dpyAttr[mDpy].customFBSize) {
- getNonWormholeRegion(list, sourceCrop);
- displayFrame = sourceCrop;
- }
- }
- calcExtDisplayPosition(ctx, NULL, mDpy, sourceCrop, displayFrame,
- transform, orient);
- //Store the displayFrame, will be used in getDisplayViewFrame
- ctx->dpyAttr[mDpy].mDstRect = displayFrame;
- setMdpFlags(ctx, layer, mdpFlags, 0, transform);
- // For External use rotator if there is a rotation value set
- ret = preRotateExtDisplay(ctx, layer, info,
- sourceCrop, mdpFlags, rotFlags);
- if(!ret) {
- ALOGE("%s: preRotate for external Failed!", __FUNCTION__);
- return false;
- }
- //For the mdp, since either we are pre-rotating or MDP does flips
- orient = ovutils::OVERLAY_TRANSFORM_0;
- transform = 0;
- ovutils::PipeArgs parg(mdpFlags, info, zOrder,
- static_cast<ovutils::eRotFlags>(rotFlags),
- ovutils::DEFAULT_PLANE_ALPHA,
- (ovutils::eBlending)
- getBlending(layer->blending));
- ret = true;
- if(configMdp(ctx->mOverlay, parg, orient, sourceCrop, displayFrame,
- NULL, mDest) < 0) {
- ALOGE("%s: configMdp failed for dpy %d", __FUNCTION__, mDpy);
- ret = false;
- }
- }
- return ret;
-}
-
-bool FBUpdateNonSplit::draw(hwc_context_t *ctx, private_handle_t *hnd)
-{
- if(!mModeOn) {
- return true;
- }
- bool ret = true;
- overlay::Overlay& ov = *(ctx->mOverlay);
- ovutils::eDest dest = mDest;
- int fd = hnd->fd;
- uint32_t offset = (uint32_t)hnd->offset;
- if(mRot) {
- if(!mRot->queueBuffer(fd, offset))
- return false;
- fd = mRot->getDstMemId();
- offset = mRot->getDstOffset();
- }
- if (!ov.queueBuffer(fd, offset, dest)) {
- ALOGE("%s: queueBuffer failed for FBUpdate", __FUNCTION__);
- ret = false;
- }
- return ret;
-}
-
-//================= High res====================================
-FBUpdateSplit::FBUpdateSplit(hwc_context_t *ctx, const int& dpy):
- IFBUpdate(ctx, dpy) {}
-
-void FBUpdateSplit::reset() {
- IFBUpdate::reset();
- mDestLeft = ovutils::OV_INVALID;
- mDestRight = ovutils::OV_INVALID;
- mRot = NULL;
-}
-
-bool FBUpdateSplit::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder) {
- if(!ctx->mMDP.hasOverlay) {
- ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
- __FUNCTION__);
- return false;
- }
- mModeOn = configure(ctx, list, fbUpdatingRect, fbZorder);
- ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
- return mModeOn;
-}
-
-// Configure
-bool FBUpdateSplit::configure(hwc_context_t *ctx,
- hwc_display_contents_1 *list, hwc_rect_t fbUpdatingRect, int fbZorder) {
- bool ret = false;
- hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
- if (LIKELY(ctx->mOverlay)) {
- ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
- ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
- mTileEnabled));
-
- overlay::Overlay& ov = *(ctx->mOverlay);
- ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
- ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
- ovutils::eTransform orient =
- static_cast<ovutils::eTransform>(layer->transform);
- const int hw_w = ctx->dpyAttr[mDpy].xres;
- const int hw_h = ctx->dpyAttr[mDpy].yres;
- const int lSplit = getLeftSplit(ctx, mDpy);
- mDestLeft = ovutils::OV_INVALID;
- mDestRight = ovutils::OV_INVALID;
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t displayFrame = layer->displayFrame;
-
- // No FB update optimization on (1) Custom FB resolution,
- // (2) External Mirror mode, (3) External orientation
- if(!ctx->dpyAttr[mDpy].customFBSize && !ctx->mBufferMirrorMode
- && !ctx->mExtOrientation) {
- sourceCrop = fbUpdatingRect;
- displayFrame = fbUpdatingRect;
- }
-
- int transform = layer->transform;
- // use ext orientation if any
- int extOrient = getExtOrientation(ctx);
-
- // Do not use getNonWormholeRegion() function to calculate the
- // sourceCrop during animation on external display and
- // Dont do wormhole calculation when extorientation is set on External
- // Dont do wormhole calculation when scaling mode is set on External
- if(ctx->listStats[mDpy].isDisplayAnimating && mDpy) {
- sourceCrop = layer->displayFrame;
- } else if((mDpy && !extOrient
- && !ctx->dpyAttr[mDpy].mMDPScalingMode)) {
- if(!qdutils::MDPVersion::getInstance().is8x26() &&
- !ctx->dpyAttr[mDpy].customFBSize) {
- getNonWormholeRegion(list, sourceCrop);
- displayFrame = sourceCrop;
- }
- }
-
- calcExtDisplayPosition(ctx, NULL, mDpy, sourceCrop, displayFrame,
- transform, orient);
-
- ret = true;
- Overlay::PipeSpecs pipeSpecs;
- pipeSpecs.formatClass = Overlay::FORMAT_RGB;
- pipeSpecs.needsScaling = qhwc::needsScaling(layer);
- pipeSpecs.dpy = mDpy;
- pipeSpecs.fb = true;
-
- /* Configure left pipe */
- if(displayFrame.left < lSplit) {
- pipeSpecs.mixer = Overlay::MIXER_LEFT;
- ovutils::eDest destL = ov.getPipe(pipeSpecs);
- if(destL == ovutils::OV_INVALID) { //None available
- ALOGE("%s: No pipes available to configure fb for dpy %d's left"
- " mixer", __FUNCTION__, mDpy);
- return false;
- }
-
- mDestLeft = destL;
-
- //XXX: FB layer plane alpha is currently sent as zero from
- //surfaceflinger
- ovutils::PipeArgs pargL(mdpFlags,
- info,
- zOrder,
- ovutils::ROT_FLAGS_NONE,
- ovutils::DEFAULT_PLANE_ALPHA,
- (ovutils::eBlending)
- getBlending(layer->blending));
- hwc_rect_t cropL = sourceCrop;
- hwc_rect_t dstL = displayFrame;
- hwc_rect_t scissorL = {0, 0, lSplit, hw_h };
- qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);
-
- if (configMdp(ctx->mOverlay, pargL, orient, cropL,
- dstL, NULL, destL)< 0) {
- ALOGE("%s: configMdp fails for left FB", __FUNCTION__);
- ret = false;
- }
- }
-
- /* Configure right pipe */
- if(displayFrame.right > lSplit) {
- pipeSpecs.mixer = Overlay::MIXER_RIGHT;
- ovutils::eDest destR = ov.getPipe(pipeSpecs);
- if(destR == ovutils::OV_INVALID) { //None available
- ALOGE("%s: No pipes available to configure fb for dpy %d's"
- " right mixer", __FUNCTION__, mDpy);
- return false;
- }
-
- mDestRight = destR;
- ovutils::eMdpFlags mdpFlagsR = mdpFlags;
- ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
-
- //XXX: FB layer plane alpha is currently sent as zero from
- //surfaceflinger
- ovutils::PipeArgs pargR(mdpFlagsR,
- info,
- zOrder,
- ovutils::ROT_FLAGS_NONE,
- ovutils::DEFAULT_PLANE_ALPHA,
- (ovutils::eBlending)
- getBlending(layer->blending));
-
- hwc_rect_t cropR = sourceCrop;
- hwc_rect_t dstR = displayFrame;
- hwc_rect_t scissorR = {lSplit, 0, hw_w, hw_h };
- qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);
-
- dstR.left -= lSplit;
- dstR.right -= lSplit;
-
- if (configMdp(ctx->mOverlay, pargR, orient, cropR,
- dstR, NULL, destR) < 0) {
- ALOGE("%s: configMdp fails for right FB", __FUNCTION__);
- ret = false;
- }
- }
- }
- return ret;
-}
-
-bool FBUpdateSplit::draw(hwc_context_t *ctx, private_handle_t *hnd)
-{
- if(!mModeOn) {
- return true;
- }
- bool ret = true;
- overlay::Overlay& ov = *(ctx->mOverlay);
- if(mDestLeft != ovutils::OV_INVALID) {
- if (!ov.queueBuffer(hnd->fd, (uint32_t)hnd->offset, mDestLeft)) {
- ALOGE("%s: queue failed for left of dpy = %d",
- __FUNCTION__, mDpy);
- ret = false;
- }
- }
- if(mDestRight != ovutils::OV_INVALID) {
- if (!ov.queueBuffer(hnd->fd, (uint32_t)hnd->offset, mDestRight)) {
- ALOGE("%s: queue failed for right of dpy = %d",
- __FUNCTION__, mDpy);
- ret = false;
- }
- }
- return ret;
-}
-
-//=================FBSrcSplit====================================
-FBSrcSplit::FBSrcSplit(hwc_context_t *ctx, const int& dpy):
- FBUpdateSplit(ctx, dpy) {}
-
-bool FBSrcSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder) {
- hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
- overlay::Overlay& ov = *(ctx->mOverlay);
-
- ovutils::Whf info(mAlignedFBWidth,
- mAlignedFBHeight,
- ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
- mTileEnabled));
-
- ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
- ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
-
- ovutils::PipeArgs parg(mdpFlags,
- info,
- zOrder,
- ovutils::ROT_FLAGS_NONE,
- ovutils::DEFAULT_PLANE_ALPHA,
- (ovutils::eBlending)
- getBlending(layer->blending));
-
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t displayFrame = layer->displayFrame;
-
- // No FB update optimization on (1) Custom FB resolution,
- // (2) External Mirror mode, (3) External orientation
- if(!ctx->dpyAttr[mDpy].customFBSize && !ctx->mBufferMirrorMode
- && !ctx->mExtOrientation) {
- sourceCrop = fbUpdatingRect;
- displayFrame = fbUpdatingRect;
- }
- int transform = layer->transform;
- ovutils::eTransform orient =
- static_cast<ovutils::eTransform>(transform);
-
- // use ext orientation if any
- int extOrient = getExtOrientation(ctx);
-
- // Do not use getNonWormholeRegion() function to calculate the
- // sourceCrop during animation on external display and
- // Dont do wormhole calculation when extorientation is set on External
- // Dont do wormhole calculation when scaling mode is set on External
- if(ctx->listStats[mDpy].isDisplayAnimating && mDpy) {
- sourceCrop = layer->displayFrame;
- } else if((mDpy && !extOrient
- && !ctx->dpyAttr[mDpy].mMDPScalingMode)) {
- if(!qdutils::MDPVersion::getInstance().is8x26() &&
- !ctx->dpyAttr[mDpy].customFBSize) {
- getNonWormholeRegion(list, sourceCrop);
- displayFrame = sourceCrop;
- }
- }
-
- calcExtDisplayPosition(ctx, NULL, mDpy, sourceCrop, displayFrame,
- transform, orient);
- hwc_rect_t cropL = sourceCrop;
- hwc_rect_t cropR = sourceCrop;
- hwc_rect_t dstL = displayFrame;
- hwc_rect_t dstR = displayFrame;
-
- //Request left pipe (or 1 by default)
- Overlay::PipeSpecs pipeSpecs;
- pipeSpecs.formatClass = Overlay::FORMAT_RGB;
- pipeSpecs.needsScaling = qhwc::needsScaling(layer);
- pipeSpecs.dpy = mDpy;
- pipeSpecs.mixer = Overlay::MIXER_DEFAULT;
- pipeSpecs.fb = true;
- ovutils::eDest destL = ov.getPipe(pipeSpecs);
- if(destL == ovutils::OV_INVALID) {
- ALOGE("%s: No pipes available to configure fb for dpy %d's left"
- " mixer", __FUNCTION__, mDpy);
- return false;
- }
-
- ovutils::eDest destR = ovutils::OV_INVALID;
-
- /* Use 2 pipes IF
- a) FB's width is > Mixer width or
- b) On primary, driver has indicated with caps to split always. This is
- based on an empirically derived value of panel height.
- */
-
- const bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
- qdutils::MDPVersion::getInstance().isSrcSplitAlways();
- const uint32_t lSplit = getLeftSplit(ctx, mDpy);
- const uint32_t cropWidth = sourceCrop.right - sourceCrop.left;
-
- if((cropWidth > qdutils::MDPVersion::getInstance().getMaxMixerWidth()) or
- (primarySplitAlways and cropWidth > lSplit)) {
- destR = ov.getPipe(pipeSpecs);
- if(destR == ovutils::OV_INVALID) {
- ALOGE("%s: No pipes available to configure fb for dpy %d's right"
- " mixer", __FUNCTION__, mDpy);
- return false;
- }
-
- if(ctx->mOverlay->comparePipePriority(destL, destR) == -1) {
- qhwc::swap(destL, destR);
- }
-
- //Split crop equally when using 2 pipes
- cropL.right = (sourceCrop.right + sourceCrop.left) / 2;
- cropR.left = cropL.right;
- dstL.right = (displayFrame.right + displayFrame.left) / 2;
- dstR.left = dstL.right;
- }
-
- mDestLeft = destL;
- mDestRight = destR;
-
- if(destL != OV_INVALID) {
- if(configMdp(ctx->mOverlay, parg, orient,
- cropL, dstL, NULL /*metadata*/, destL) < 0) {
- ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
- return false;
- }
- }
-
- //configure right pipe
- if(destR != OV_INVALID) {
- if(configMdp(ctx->mOverlay, parg, orient,
- cropR, dstR, NULL /*metadata*/, destR) < 0) {
- ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
- return false;
- }
- }
-
- return true;
-}
-
-//---------------------------------------------------------------------
-}; //namespace qhwc
diff --git a/msm8909/libhwcomposer/hwc_fbupdate.h b/msm8909/libhwcomposer/hwc_fbupdate.h
deleted file mode 100644
index 545f5bd..0000000
--- a/msm8909/libhwcomposer/hwc_fbupdate.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 HWC_FBUPDATE_H
-#define HWC_FBUPDATE_H
-#include "hwc_utils.h"
-#include "overlay.h"
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-namespace overlay {
- class Rotator;
-}
-
-namespace qhwc {
-namespace ovutils = overlay::utils;
-
-//Framebuffer update Interface
-class IFBUpdate {
-public:
- explicit IFBUpdate(hwc_context_t *ctx, const int& dpy);
- virtual ~IFBUpdate() {};
- // Sets up members and prepares overlay if conditions are met
- virtual bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder) = 0;
- virtual bool prepareAndValidate(hwc_context_t *ctx,
- hwc_display_contents_1 *list, int fbZorder);
- // Draws layer
- virtual bool draw(hwc_context_t *ctx, private_handle_t *hnd) = 0;
- //Reset values
- virtual void reset();
- //Factory method that returns a low-res or high-res version
- static IFBUpdate *getObject(hwc_context_t *ctx, const int& dpy);
-
-protected:
- const int mDpy; // display to update
- bool mModeOn; // if prepare happened
- overlay::Rotator *mRot;
- int mAlignedFBWidth;
- int mAlignedFBHeight;
- int mTileEnabled;
-};
-
-//Non-Split panel handler.
-class FBUpdateNonSplit : public IFBUpdate {
-public:
- explicit FBUpdateNonSplit(hwc_context_t *ctx, const int& dpy);
- virtual ~FBUpdateNonSplit() {};
- bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder);
- bool draw(hwc_context_t *ctx, private_handle_t *hnd);
- void reset();
-private:
- bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder);
- bool preRotateExtDisplay(hwc_context_t *ctx,
- hwc_layer_1_t *layer,
- ovutils::Whf &info,
- hwc_rect_t& sourceCrop,
- ovutils::eMdpFlags& mdpFlags,
- int& rotFlags);
- ovutils::eDest mDest; //pipe to draw on
-};
-
-//Split panel handler.
-class FBUpdateSplit : public IFBUpdate {
-public:
- explicit FBUpdateSplit(hwc_context_t *ctx, const int& dpy);
- virtual ~FBUpdateSplit() {};
- bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder);
- bool draw(hwc_context_t *ctx, private_handle_t *hnd);
- void reset();
-
-protected:
- virtual bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder);
- ovutils::eDest mDestLeft; //left pipe to draw on
- ovutils::eDest mDestRight; //right pipe to draw on
-};
-
-//Source Split Handler
-class FBSrcSplit : public FBUpdateSplit {
-public:
- explicit FBSrcSplit(hwc_context_t *ctx, const int& dpy);
- virtual ~FBSrcSplit() {};
-private:
- bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
- hwc_rect_t fbUpdatingRect, int fbZorder);
-};
-
-}; //namespace qhwc
-
-#endif //HWC_FBUPDATE_H
diff --git a/msm8909/libhwcomposer/hwc_mdpcomp.cpp b/msm8909/libhwcomposer/hwc_mdpcomp.cpp
deleted file mode 100644
index 93e0945..0000000
--- a/msm8909/libhwcomposer/hwc_mdpcomp.cpp
+++ /dev/null
@@ -1,2827 +0,0 @@
-/*
- * Copyright (C) 2012-2016, The Linux Foundation. All rights reserved.
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 <math.h>
-#include "hwc_mdpcomp.h"
-#include <sys/ioctl.h>
-#include "hdmi.h"
-#include "qdMetaData.h"
-#include "mdp_version.h"
-#include "hwc_fbupdate.h"
-#include "hwc_ad.h"
-#include <overlayRotator.h>
-#include "hwc_copybit.h"
-#include "qd_utils.h"
-
-using namespace overlay;
-using namespace qdutils;
-using namespace overlay::utils;
-namespace ovutils = overlay::utils;
-
-namespace qhwc {
-
-//==============MDPComp========================================================
-
-IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
-bool MDPComp::sIdleFallBack = false;
-bool MDPComp::sDebugLogs = false;
-bool MDPComp::sEnabled = false;
-bool MDPComp::sEnableMixedMode = true;
-int MDPComp::sSimulationFlags = 0;
-int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
-bool MDPComp::sEnableYUVsplit = false;
-bool MDPComp::sSrcSplitEnabled = false;
-bool MDPComp::enablePartialUpdateForMDP3 = false;
-bool MDPComp::sIsPartialUpdateActive = true;
-MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
- if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
- sSrcSplitEnabled = true;
- return new MDPCompSrcSplit(dpy);
- } else if(isDisplaySplit(ctx, dpy)) {
- return new MDPCompSplit(dpy);
- }
- return new MDPCompNonSplit(dpy);
-}
-
-MDPComp::MDPComp(int dpy) : mDpy(dpy), mModeOn(false), mPrevModeOn(false) {
-};
-
-void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
-{
- if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
- return;
-
- dumpsys_log(buf,"HWC Map for Dpy: %s \n",
- (mDpy == 0) ? "\"PRIMARY\"" :
- (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
- dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
- "fbCount:%2d \n", mCurrentFrame.layerCount,
- mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
- dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
- (mCurrentFrame.needsRedraw? "YES" : "NO"),
- mCurrentFrame.mdpCount, sMaxPipesPerMixer);
- if(isDisplaySplit(ctx, mDpy)) {
- dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
- "Right: [%d, %d, %d, %d] \n",
- ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
- ctx->listStats[mDpy].lRoi.right,
- ctx->listStats[mDpy].lRoi.bottom,
- ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
- ctx->listStats[mDpy].rRoi.right,
- ctx->listStats[mDpy].rRoi.bottom);
- } else {
- dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
- ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
- ctx->listStats[mDpy].lRoi.right,
- ctx->listStats[mDpy].lRoi.bottom);
- }
- dumpsys_log(buf," --------------------------------------------- \n");
- dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
- dumpsys_log(buf," --------------------------------------------- \n");
- for(int index = 0; index < mCurrentFrame.layerCount; index++ )
- dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
- index,
- (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
- mCurrentFrame.layerToMDP[index],
- (mCurrentFrame.isFBComposed[index] ?
- (mCurrentFrame.drop[index] ? "DROP" :
- (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
- (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
- mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
- dumpsys_log(buf,"\n");
-}
-
-bool MDPComp::init(hwc_context_t *ctx) {
-
- if(!ctx) {
- ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
- return false;
- }
-
- char property[PROPERTY_VALUE_MAX] = {0};
-
- sEnabled = false;
- if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
- (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- sEnabled = true;
- }
-
- sEnableMixedMode = true;
- if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- sEnableMixedMode = false;
- }
-
- sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
- if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
- int val = atoi(property);
- if(val >= 0)
- sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
- }
-
- if(ctx->mMDP.panel != MIPI_CMD_PANEL &&
- (ctx->mMDP.version >= qdutils::MDP_V4_0)) {
- sIdleInvalidator = IdleInvalidator::getInstance();
- if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
- delete sIdleInvalidator;
- sIdleInvalidator = NULL;
- }
- }
-
- if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
- !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
- property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
- !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
- sEnableYUVsplit = true;
- }
-
- bool defaultPTOR = false;
- //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
- //8x16 and 8x39 targets by default
- if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
- (qdutils::MDPVersion::getInstance().is8x16() ||
- qdutils::MDPVersion::getInstance().is8x39())) {
- defaultPTOR = true;
- }
-
- if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
- ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
- HWC_DISPLAY_PRIMARY);
- }
-
- if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
- (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
- enablePartialUpdateForMDP3 = true;
- }
-
- if(!enablePartialUpdateForMDP3 &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- enablePartialUpdateForMDP3 = true;
- }
-
- int retPartialUpdatePref = getPartialUpdatePref(ctx);
- if(retPartialUpdatePref >= 0)
- sIsPartialUpdateActive = (retPartialUpdatePref != 0);
-
- return true;
-}
-
-void MDPComp::reset(hwc_context_t *ctx) {
- const int numLayers = ctx->listStats[mDpy].numAppLayers;
- mCurrentFrame.reset(numLayers);
- ctx->mOverlay->clear(mDpy);
- ctx->mLayerRotMap[mDpy]->clear();
- resetROI(ctx, mDpy);
- memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
- mCurrentFrame.dropCount = 0;
-}
-
-void MDPComp::reset() {
- mPrevModeOn = mModeOn;
- mModeOn = false;
-}
-
-void MDPComp::timeout_handler(void *udata) {
- struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
- bool handleTimeout = false;
-
- if(!ctx) {
- ALOGE("%s: received empty data in timer callback", __FUNCTION__);
- return;
- }
-
- ctx->mDrawLock.lock();
-
- /* Handle timeout event only if the previous composition
- on any display is MDP or MIXED*/
- for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
- if(ctx->mMDPComp[i])
- handleTimeout =
- ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
- }
-
- if(!handleTimeout) {
- ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
- ctx->mDrawLock.unlock();
- return;
- }
- if(!ctx->proc) {
- ALOGE("%s: HWC proc not registered", __FUNCTION__);
- ctx->mDrawLock.unlock();
- return;
- }
- sIdleFallBack = true;
- ctx->mDrawLock.unlock();
- /* Trigger SF to redraw the current frame */
- ctx->proc->invalidate(ctx->proc);
-}
-
-void MDPComp::setIdleTimeout(const uint32_t& timeout) {
- enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
-
- if(sIdleInvalidator) {
- if(timeout <= ONE_REFRESH_PERIOD_MS) {
- //If the specified timeout is < 1 draw cycle worth, "virtually"
- //disable idle timeout. The ideal way for clients to disable
- //timeout is to set it to 0
- sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
- ALOGI("Disabled idle timeout");
- return;
- }
- sIdleInvalidator->setIdleTimeout(timeout);
- ALOGI("Idle timeout set to %u", timeout);
- } else {
- ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
- }
-}
-
-void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- LayerProp *layerProp = ctx->layerProp[mDpy];
-
- for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
- hwc_layer_1_t* layer = &(list->hwLayers[index]);
- if(!mCurrentFrame.isFBComposed[index]) {
- layerProp[index].mFlags |= HWC_MDPCOMP;
- layer->compositionType = HWC_OVERLAY;
- layer->hints |= HWC_HINT_CLEAR_FB;
- } else {
- /* Drop the layer when its already present in FB OR when it lies
- * outside frame's ROI */
- if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
- layer->compositionType = HWC_OVERLAY;
- }
- }
- }
-}
-
-void MDPComp::setRedraw(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- mCurrentFrame.needsRedraw = false;
- if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
- (list->flags & HWC_GEOMETRY_CHANGED) ||
- isSkipPresent(ctx, mDpy)) {
- mCurrentFrame.needsRedraw = true;
- }
-}
-
-MDPComp::FrameInfo::FrameInfo() {
- memset(&mdpToLayer, 0, sizeof(mdpToLayer));
- reset(0);
-}
-
-void MDPComp::FrameInfo::reset(const int& numLayers) {
- for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
- if(mdpToLayer[i].pipeInfo) {
- delete mdpToLayer[i].pipeInfo;
- mdpToLayer[i].pipeInfo = NULL;
- //We dont own the rotator
- mdpToLayer[i].rot = NULL;
- }
- }
-
- memset(&mdpToLayer, 0, sizeof(mdpToLayer));
- memset(&layerToMDP, -1, sizeof(layerToMDP));
- memset(&isFBComposed, 1, sizeof(isFBComposed));
-
- layerCount = numLayers;
- fbCount = numLayers;
- mdpCount = 0;
- needsRedraw = true;
- fbZ = -1;
-}
-
-void MDPComp::FrameInfo::map() {
- // populate layer and MDP maps
- int mdpIdx = 0;
- for(int idx = 0; idx < layerCount; idx++) {
- if(!isFBComposed[idx]) {
- mdpToLayer[mdpIdx].listIndex = idx;
- layerToMDP[idx] = mdpIdx++;
- }
- }
-}
-
-MDPComp::LayerCache::LayerCache() {
- reset();
-}
-
-void MDPComp::LayerCache::reset() {
- memset(&isFBComposed, true, sizeof(isFBComposed));
- memset(&drop, false, sizeof(drop));
- layerCount = 0;
-}
-
-void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
- layerCount = curFrame.layerCount;
- memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
- memcpy(&drop, &curFrame.drop, sizeof(drop));
-}
-
-bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
- hwc_display_contents_1_t* list) {
- if(layerCount != curFrame.layerCount)
- return false;
- for(int i = 0; i < curFrame.layerCount; i++) {
- if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
- (curFrame.drop[i] != drop[i])) {
- return false;
- }
- hwc_layer_1_t const* layer = &list->hwLayers[i];
- if(curFrame.isFBComposed[i] && layerUpdating(layer)) {
- return false;
- }
- }
- return true;
-}
-
-bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
- hwc_display_contents_1_t* list) {
-
- if(layerCount != ctx->listStats[dpy].numAppLayers)
- return false;
-
- if((list->flags & HWC_GEOMETRY_CHANGED) ||
- isSkipPresent(ctx, dpy)) {
- return false;
- }
-
- for(int i = 0; i < layerCount; i++) {
- hwc_layer_1_t const* layer = &list->hwLayers[i];
- if(layerUpdating(layer))
- return false;
- }
-
- return true;
-}
-
-bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
- (not isValidDimension(ctx,layer)) ||
- isSkipLayer(layer)) {
- //More conditions here, sRGB+Blend etc
- return false;
- }
- return true;
-}
-
-bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
-
- if(!hnd) {
- if (layer->flags & HWC_COLOR_FILL) {
- // Color layer
- return true;
- }
- ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
- return false;
- }
-
- //XXX: Investigate doing this with pixel phase on MDSS
- if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
- return false;
-
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t dst = layer->displayFrame;
- bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
- int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
- int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
- int dst_w = dst.right - dst.left;
- int dst_h = dst.bottom - dst.top;
- float w_scale = ((float)crop_w / (float)dst_w);
- float h_scale = ((float)crop_h / (float)dst_h);
- MDPVersion& mdpHw = MDPVersion::getInstance();
-
- /* Workaround for MDP HW limitation in DSI command mode panels where
- * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
- * less than 5 pixels
- * There also is a HW limilation in MDP, minimum block size is 2x2
- * Fallback to GPU if height is less than 2.
- */
- if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
- return false;
-
- if((w_scale > 1.0f) || (h_scale > 1.0f)) {
- const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
- const float w_dscale = w_scale;
- const float h_dscale = h_scale;
-
- if(ctx->mMDP.version >= qdutils::MDSS_V5) {
-
- if(!mdpHw.supportsDecimation()) {
- /* On targets that doesnt support Decimation (eg.,8x26)
- * maximum downscale support is overlay pipe downscale.
- */
- if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
- w_dscale > maxMDPDownscale ||
- h_dscale > maxMDPDownscale)
- return false;
- } else {
- // Decimation on macrotile format layers is not supported.
- if(isTileRendered(hnd)) {
- /* Bail out if
- * 1. Src crop > Mixer limit on nonsplit MDPComp
- * 2. exceeds maximum downscale limit
- */
- if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
- !sSrcSplitEnabled) ||
- w_dscale > maxMDPDownscale ||
- h_dscale > maxMDPDownscale) {
- return false;
- }
- } else if(w_dscale > 64 || h_dscale > 64)
- return false;
- }
- } else { //A-family
- if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
- return false;
- }
- }
-
- if((w_scale < 1.0f) || (h_scale < 1.0f)) {
- const uint32_t upscale = mdpHw.getMaxMDPUpscale();
- const float w_uscale = 1.0f / w_scale;
- const float h_uscale = 1.0f / h_scale;
-
- if(w_uscale > upscale || h_uscale > upscale)
- return false;
- }
-
- return true;
-}
-
-bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
- bool ret = true;
-
- if(!isEnabled()) {
- ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
- ret = false;
- } else if((qdutils::MDPVersion::getInstance().is8x26() ||
- qdutils::MDPVersion::getInstance().is8x16() ||
- qdutils::MDPVersion::getInstance().is8x39()) &&
- ctx->mVideoTransFlag &&
- isSecondaryConnected(ctx)) {
- //1 Padding round to shift pipes across mixers
- ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
- __FUNCTION__);
- ret = false;
- } else if((qdutils::MDPVersion::getInstance().is8x26() ||
- qdutils::MDPVersion::getInstance().is8x16() ||
- qdutils::MDPVersion::getInstance().is8x39()) &&
- !mDpy && isSecondaryAnimating(ctx) &&
- isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
- ALOGD_IF(isDebug(),"%s: Display animation in progress",
- __FUNCTION__);
- ret = false;
- } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
- /* TODO: freeing up all the resources only for the targets having total
- number of pipes < 8. Need to analyze number of VIG pipes used
- for primary in previous draw cycle and accordingly decide
- whether to fall back to full GPU comp or video only comp
- */
- if(isSecondaryConfiguring(ctx)) {
- ALOGD_IF( isDebug(),"%s: External Display connection is pending",
- __FUNCTION__);
- ret = false;
- } else if(ctx->isPaddingRound) {
- ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
- __FUNCTION__,mDpy);
- ret = false;
- }
- }
- return ret;
-}
-
-void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
- hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
- fbRect = getIntersection(fbRect, roi);
-}
-
-/* 1) Identify layers that are not visible or lying outside the updating ROI and
- * drop them from composition.
- * 2) If we have a scaling layer which needs cropping against generated
- * ROI, reset ROI to full resolution. */
-bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
-
- for(int i = numAppLayers - 1; i >= 0; i--){
- if(!isValidRect(visibleRect)) {
- mCurrentFrame.drop[i] = true;
- mCurrentFrame.dropCount++;
- continue;
- }
-
- const hwc_layer_1_t* layer = &list->hwLayers[i];
- hwc_rect_t dstRect = layer->displayFrame;
- hwc_rect_t res = getIntersection(visibleRect, dstRect);
-
- if(!isValidRect(res)) {
- mCurrentFrame.drop[i] = true;
- mCurrentFrame.dropCount++;
- } else {
- /* Reset frame ROI when any layer which needs scaling also needs ROI
- * cropping */
- if(!isSameRect(res, dstRect) && needsScaling (layer)) {
- ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
- memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
- mCurrentFrame.dropCount = 0;
- return false;
- }
-
- /* deduct any opaque region from visibleRect */
- if (layer->blending == HWC_BLENDING_NONE &&
- layer->planeAlpha == 0xFF)
- visibleRect = deductRect(visibleRect, res);
- }
- }
- return true;
-}
-
-/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
- * are updating. If DirtyRegion is applicable, calculate it by accounting all
- * the changing layer's dirtyRegion. */
-void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- if(!canPartialUpdate(ctx, list))
- return;
-
- struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
- hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
- (int)ctx->dpyAttr[mDpy].yres};
-
- for(int index = 0; index < numAppLayers; index++ ) {
- hwc_layer_1_t* layer = &list->hwLayers[index];
- if (layerUpdating(layer) ||
- isYuvBuffer((private_handle_t *)layer->handle)) {
- hwc_rect_t dirtyRect = (struct hwc_rect){0, 0, 0, 0};;
- if(!needsScaling(layer) && !layer->transform &&
- (!isYuvBuffer((private_handle_t *)layer->handle)))
- {
- dirtyRect = calculateDirtyRect(layer, fullFrame);
- }
-
- roi = getUnion(roi, dirtyRect);
- }
- }
-
- /* No layer is updating. Still SF wants a refresh.*/
- if(!isValidRect(roi))
- return;
-
- // Align ROI coordinates to panel restrictions
- roi = getSanitizeROI(roi, fullFrame);
-
- ctx->listStats[mDpy].lRoi = roi;
- if(!validateAndApplyROI(ctx, list))
- resetROI(ctx, mDpy);
-
- ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
- ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
- ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
-}
-
-void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
- hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
- hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
-
- hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
- hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
- fbRect = getUnion(l_fbRect, r_fbRect);
-}
-/* 1) Identify layers that are not visible or lying outside BOTH the updating
- * ROI's and drop them from composition. If a layer is spanning across both
- * the halves of the screen but needed by only ROI, the non-contributing
- * half will not be programmed for MDP.
- * 2) If we have a scaling layer which needs cropping against generated
- * ROI, reset ROI to full resolution. */
-bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
-
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
-
- hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
- hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
-
- for(int i = numAppLayers - 1; i >= 0; i--){
- if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
- {
- mCurrentFrame.drop[i] = true;
- mCurrentFrame.dropCount++;
- continue;
- }
-
- const hwc_layer_1_t* layer = &list->hwLayers[i];
- hwc_rect_t dstRect = layer->displayFrame;
-
- hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
- hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
- hwc_rect_t res = getUnion(l_res, r_res);
-
- if(!isValidRect(l_res) && !isValidRect(r_res)) {
- mCurrentFrame.drop[i] = true;
- mCurrentFrame.dropCount++;
- } else {
- /* Reset frame ROI when any layer which needs scaling also needs ROI
- * cropping */
- if(!isSameRect(res, dstRect) && needsScaling (layer)) {
- memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
- mCurrentFrame.dropCount = 0;
- return false;
- }
-
- if (layer->blending == HWC_BLENDING_NONE &&
- layer->planeAlpha == 0xFF) {
- visibleRectL = deductRect(visibleRectL, l_res);
- visibleRectR = deductRect(visibleRectR, r_res);
- }
- }
- }
- return true;
-}
-/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
- * are updating. If DirtyRegion is applicable, calculate it by accounting all
- * the changing layer's dirtyRegion. */
-void MDPCompSplit::generateROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- if(!canPartialUpdate(ctx, list))
- return;
-
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- int lSplit = getLeftSplit(ctx, mDpy);
-
- int hw_h = (int)ctx->dpyAttr[mDpy].yres;
- int hw_w = (int)ctx->dpyAttr[mDpy].xres;
-
- struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
- struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
-
- struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
- struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
-
- for(int index = 0; index < numAppLayers; index++ ) {
- hwc_layer_1_t* layer = &list->hwLayers[index];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if (layerUpdating(layer) || isYuvBuffer(hnd)) {
- hwc_rect_t l_dirtyRect = (struct hwc_rect){0, 0, 0, 0};
- hwc_rect_t r_dirtyRect = (struct hwc_rect){0, 0, 0, 0};
- if(!needsScaling(layer) && !layer->transform)
- {
- l_dirtyRect = calculateDirtyRect(layer, l_frame);
- r_dirtyRect = calculateDirtyRect(layer, r_frame);
- }
- if(isValidRect(l_dirtyRect))
- l_roi = getUnion(l_roi, l_dirtyRect);
-
- if(isValidRect(r_dirtyRect))
- r_roi = getUnion(r_roi, r_dirtyRect);
- }
- }
-
- /* For panels that cannot accept commands in both the interfaces, we cannot
- * send two ROI's (for each half). We merge them into single ROI and split
- * them across lSplit for MDP mixer use. The ROI's will be merged again
- * finally before udpating the panel in the driver. */
- if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
- hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
- l_roi = getIntersection(temp_roi, l_frame);
- r_roi = getIntersection(temp_roi, r_frame);
- }
-
- /* No layer is updating. Still SF wants a refresh. */
- if(!isValidRect(l_roi) && !isValidRect(r_roi))
- return;
-
- l_roi = getSanitizeROI(l_roi, l_frame);
- r_roi = getSanitizeROI(r_roi, r_frame);
-
- ctx->listStats[mDpy].lRoi = l_roi;
- ctx->listStats[mDpy].rRoi = r_roi;
-
- if(!validateAndApplyROI(ctx, list))
- resetROI(ctx, mDpy);
-
- ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
- "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
- ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
- ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
- ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
- ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
-}
-
-/* Checks for conditions where all the layers marked for MDP comp cannot be
- * bypassed. On such conditions we try to bypass atleast YUV layers */
-bool MDPComp::tryFullFrame(hwc_context_t *ctx,
- hwc_display_contents_1_t* list){
-
- const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
-
- // Fall back to video only composition, if AIV video mode is enabled
- if(ctx->listStats[mDpy].mAIVVideoMode) {
- ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
- __FUNCTION__, mDpy);
- return false;
- }
-
- // No Idle fall back, if secure display or secure RGB layers are present or
- // if there's only a single layer being composed
- if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
- !ctx->listStats[mDpy].secureRGBCount) &&
- (ctx->listStats[mDpy].numAppLayers != 1)) {
- ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
- return false;
- }
-
- if(!mDpy && isSecondaryAnimating(ctx) &&
- (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
- isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
- ALOGD_IF(isDebug(),"%s: Display animation in progress",
- __FUNCTION__);
- return false;
- }
-
- // if secondary is configuring or Padding round, fall back to video only
- // composition and release all assigned non VIG pipes from primary.
- if(isSecondaryConfiguring(ctx)) {
- ALOGD_IF( isDebug(),"%s: External Display connection is pending",
- __FUNCTION__);
- return false;
- } else if(ctx->isPaddingRound) {
- ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
- __FUNCTION__,mDpy);
- return false;
- }
-
- MDPVersion& mdpHw = MDPVersion::getInstance();
- if(mDpy > HWC_DISPLAY_PRIMARY &&
- (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
- (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
- // Disable MDP comp on Secondary when the primary is highres panel and
- // the secondary is a normal 1080p, because, MDP comp on secondary under
- // in such usecase, decimation gets used for downscale and there will be
- // a quality mismatch when there will be a fallback to GPU comp
- ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
- __FUNCTION__);
- return false;
- }
-
- // check for action safe flag and MDP scaling mode which requires scaling.
- if(ctx->dpyAttr[mDpy].mActionSafePresent
- || ctx->dpyAttr[mDpy].mMDPScalingMode) {
- ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
- return false;
- }
-
- for(int i = 0; i < numAppLayers; ++i) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
-
- if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
- if(!canUseRotator(ctx, mDpy)) {
- ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
- __FUNCTION__, mDpy);
- return false;
- }
- }
-
- //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
- // may not need it if Gfx pre-rotation can handle all flips & rotations
- int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
- if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
- (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
- return false;
- }
-
- if(ctx->mAD->isDoable()) {
- return false;
- }
-
- //If all above hard conditions are met we can do full or partial MDP comp.
- bool ret = false;
- if(fullMDPComp(ctx, list)) {
- ret = true;
- } else if(fullMDPCompWithPTOR(ctx, list)) {
- ret = true;
- } else if(partialMDPComp(ctx, list)) {
- ret = true;
- }
-
- return ret;
-}
-
-bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
-
- if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
- return false;
-
- //Will benefit presentation / secondary-only layer.
- if((mDpy > HWC_DISPLAY_PRIMARY) &&
- (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
- ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
- return false;
- }
-
- const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- for(int i = 0; i < numAppLayers; i++) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- if(not mCurrentFrame.drop[i] and
- not isSupportedForMDPComp(ctx, layer)) {
- ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
- return false;
- }
- }
-
- if(!mDpy && isSecondaryConnected(ctx) &&
- (qdutils::MDPVersion::getInstance().is8x16() ||
- qdutils::MDPVersion::getInstance().is8x26() ||
- qdutils::MDPVersion::getInstance().is8x39()) &&
- isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
- ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
- return false;
- }
-
- mCurrentFrame.fbCount = 0;
- memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
- sizeof(mCurrentFrame.isFBComposed));
- mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
- mCurrentFrame.dropCount;
-
- if(sEnableYUVsplit){
- adjustForSourceSplit(ctx, list);
- }
-
- if(!postHeuristicsHandling(ctx, list)) {
- ALOGD_IF(isDebug(), "post heuristic handling failed");
- reset(ctx);
- return false;
- }
- ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
- __FUNCTION__);
- return true;
-}
-
-/* Full MDP Composition with Peripheral Tiny Overlap Removal.
- * MDP bandwidth limitations can be avoided, if the overlap region
- * covered by the smallest layer at a higher z-order, gets composed
- * by Copybit on a render buffer, which can be queued to MDP.
- */
-bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
-
- const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- const int stagesForMDP = min(sMaxPipesPerMixer,
- ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
-
- // Hard checks where we cannot use this mode
- if (mDpy || !ctx->mCopyBit[mDpy]) {
- ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
- return false;
- }
-
- // Frame level checks
- if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
- isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
- isSecurePresent(ctx, mDpy)) {
- ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
- return false;
- }
- // MDP comp checks
- for(int i = 0; i < numAppLayers; i++) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- if(not isSupportedForMDPComp(ctx, layer)) {
- ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
- return false;
- }
- }
-
- if(!mDpy && isSecondaryConnected(ctx) &&
- (qdutils::MDPVersion::getInstance().is8x16() ||
- qdutils::MDPVersion::getInstance().is8x26() ||
- qdutils::MDPVersion::getInstance().is8x39()) &&
- isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
- ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
- return false;
- }
-
- /* We cannot use this composition mode, if:
- 1. A below layer needs scaling.
- 2. Overlap is not peripheral to display.
- 3. Overlap or a below layer has 90 degree transform.
- 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
- */
-
- int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
- hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
- memset(overlapRect, 0, sizeof(overlapRect));
- int layerPixelCount, minPixelCount = 0;
- int numPTORLayersFound = 0;
- for (int i = numAppLayers-1; (i >= 0 &&
- numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t dispFrame = layer->displayFrame;
- layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
- // PTOR layer should be peripheral and cannot have transform
- if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
- has90Transform(layer)) {
- continue;
- }
- if((3 * (layerPixelCount + minPixelCount)) >
- ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
- // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
- continue;
- }
- bool found = false;
- for (int j = i-1; j >= 0; j--) {
- // Check if the layers below this layer qualifies for PTOR comp
- hwc_layer_1_t* layer = &list->hwLayers[j];
- hwc_rect_t disFrame = layer->displayFrame;
- // Layer below PTOR is intersecting and has 90 degree transform or
- // needs scaling cannot be supported.
- if (isValidRect(getIntersection(dispFrame, disFrame))) {
- if (has90Transform(layer) || needsScaling(layer)) {
- found = false;
- break;
- }
- found = true;
- }
- }
- // Store the minLayer Index
- if(found) {
- minLayerIndex[numPTORLayersFound] = i;
- overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
- minPixelCount += layerPixelCount;
- numPTORLayersFound++;
- }
- }
-
- // No overlap layers
- if (!numPTORLayersFound)
- return false;
-
- // Store the displayFrame and the sourceCrops of the layers
- hwc_rect_t displayFrame[numAppLayers];
- hwc_rect_t sourceCrop[numAppLayers];
- for(int i = 0; i < numAppLayers; i++) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- displayFrame[i] = layer->displayFrame;
- sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
- }
-
- /**
- * It's possible that 2 PTOR layers might have overlapping.
- * In such case, remove the intersection(again if peripheral)
- * from the lower PTOR layer to avoid overlapping.
- * If intersection is not on peripheral then compromise
- * by reducing number of PTOR layers.
- **/
- hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
- if(isValidRect(commonRect)) {
- overlapRect[1] = deductRect(overlapRect[1], commonRect);
- list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
- }
-
- ctx->mPtorInfo.count = numPTORLayersFound;
- for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
- ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
- }
-
- if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
- // reset PTOR
- ctx->mPtorInfo.count = 0;
- if(isValidRect(commonRect)) {
- // If PTORs are intersecting restore displayframe of PTOR[1]
- // before returning, as we have modified it above.
- list->hwLayers[minLayerIndex[1]].displayFrame =
- displayFrame[minLayerIndex[1]];
- }
- return false;
- }
- private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
- Whf layerWhf[MAX_PTOR_LAYERS]; // To store w,h,f of PTOR layers
-
- // Store the blending mode, planeAlpha, and transform of PTOR layers
- int32_t blending[numPTORLayersFound];
- uint8_t planeAlpha[numPTORLayersFound];
- uint32_t transform[numPTORLayersFound];
-
- for(int j = 0; j < numPTORLayersFound; j++) {
- int index = ctx->mPtorInfo.layerIndex[j];
-
- // Update src crop of PTOR layer
- hwc_layer_1_t* layer = &list->hwLayers[index];
- layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
- layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
- layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
- layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
-
- // Store & update w, h, format of PTOR layer
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
- layerWhf[j] = whf;
- hnd->width = renderBuf->width;
- hnd->height = renderBuf->height;
- hnd->format = renderBuf->format;
-
- // Store & update blending mode, planeAlpha and transform of PTOR layer
- blending[j] = layer->blending;
- planeAlpha[j] = layer->planeAlpha;
- transform[j] = layer->transform;
- layer->blending = HWC_BLENDING_NONE;
- layer->planeAlpha = 0xFF;
- layer->transform = 0;
-
- // Remove overlap from crop & displayFrame of below layers
- for (int i = 0; i < index && index !=-1; i++) {
- layer = &list->hwLayers[i];
- if(!isValidRect(getIntersection(layer->displayFrame,
- overlapRect[j]))) {
- continue;
- }
- // Update layer attributes
- hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t destRect = deductRect(layer->displayFrame,
- getIntersection(layer->displayFrame, overlapRect[j]));
- qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
- layer->transform);
- layer->sourceCropf.left = (float)srcCrop.left;
- layer->sourceCropf.top = (float)srcCrop.top;
- layer->sourceCropf.right = (float)srcCrop.right;
- layer->sourceCropf.bottom = (float)srcCrop.bottom;
- }
- }
-
- mCurrentFrame.mdpCount = numAppLayers;
- mCurrentFrame.fbCount = 0;
- mCurrentFrame.fbZ = -1;
-
- for (int j = 0; j < numAppLayers; j++) {
- if(isValidRect(list->hwLayers[j].displayFrame)) {
- mCurrentFrame.isFBComposed[j] = false;
- } else {
- mCurrentFrame.mdpCount--;
- mCurrentFrame.drop[j] = true;
- }
- }
-
- bool result = postHeuristicsHandling(ctx, list);
-
- // Restore layer attributes
- for(int i = 0; i < numAppLayers; i++) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- layer->displayFrame = displayFrame[i];
- layer->sourceCropf.left = (float)sourceCrop[i].left;
- layer->sourceCropf.top = (float)sourceCrop[i].top;
- layer->sourceCropf.right = (float)sourceCrop[i].right;
- layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
- }
-
- // Restore w,h,f, blending attributes, and transform of PTOR layers
- for (int i = 0; i < numPTORLayersFound; i++) {
- int idx = ctx->mPtorInfo.layerIndex[i];
- hwc_layer_1_t* layer = &list->hwLayers[idx];
- private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
- hnd->width = layerWhf[i].w;
- hnd->height = layerWhf[i].h;
- hnd->format = layerWhf[i].format;
- layer->blending = blending[i];
- layer->planeAlpha = planeAlpha[i];
- layer->transform = transform[i];
- }
-
- if (!result) {
- // reset PTOR
- ctx->mPtorInfo.count = 0;
- reset(ctx);
- } else {
- ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
- ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
- }
-
- ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
- (result ? "successful" : "failed"));
- return result;
-}
-
-bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
-{
- if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
- //Mixed mode is disabled/can't be used. No need to even try caching.
- return false;
- }
-
- bool ret = false;
- if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
- //Try load based first
- ret = loadBasedComp(ctx, list) or
- cacheBasedComp(ctx, list);
- } else {
- ret = cacheBasedComp(ctx, list) or
- loadBasedComp(ctx, list);
- }
-
- return ret;
-}
-
-bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
- return false;
-
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- mCurrentFrame.reset(numAppLayers);
- updateLayerCache(ctx, list, mCurrentFrame);
-
- //If an MDP marked layer is unsupported cannot do partial MDP Comp
- for(int i = 0; i < numAppLayers; i++) {
- if(!mCurrentFrame.isFBComposed[i]) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- if(not isSupportedForMDPComp(ctx, layer)) {
- ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
- __FUNCTION__);
- reset(ctx);
- return false;
- }
- }
- }
-
- updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
- /* mark secure RGB layers for MDP comp */
- updateSecureRGB(ctx, list);
- bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
- if(!ret) {
- ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
- reset(ctx);
- return false;
- }
-
- int mdpCount = mCurrentFrame.mdpCount;
-
- if(sEnableYUVsplit){
- adjustForSourceSplit(ctx, list);
- }
-
- //Will benefit cases where a video has non-updating background.
- if((mDpy > HWC_DISPLAY_PRIMARY) and
- (mdpCount > MAX_SEC_LAYERS)) {
- ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
- reset(ctx);
- return false;
- }
-
- if(!postHeuristicsHandling(ctx, list)) {
- ALOGD_IF(isDebug(), "post heuristic handling failed");
- reset(ctx);
- return false;
- }
- ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
- __FUNCTION__);
-
- return true;
-}
-
-bool MDPComp::loadBasedComp(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
- return false;
-
- if(not isLoadBasedCompDoable(ctx)) {
- return false;
- }
-
- const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
- const int stagesForMDP = min(sMaxPipesPerMixer,
- ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
-
- int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
- int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
- int lastMDPSupportedIndex = numAppLayers;
- int dropCount = 0;
-
- //Find the minimum MDP batch size
- for(int i = 0; i < numAppLayers;i++) {
- if(mCurrentFrame.drop[i]) {
- dropCount++;
- continue;
- }
- hwc_layer_1_t* layer = &list->hwLayers[i];
- if(not isSupportedForMDPComp(ctx, layer)) {
- lastMDPSupportedIndex = i;
- mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
- fbBatchSize = numNonDroppedLayers - mdpBatchSize;
- break;
- }
- }
-
- ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
- "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
- mCurrentFrame.dropCount);
-
- //Start at a point where the fb batch should at least have 2 layers, for
- //this mode to be justified.
- while(fbBatchSize < 2) {
- ++fbBatchSize;
- --mdpBatchSize;
- }
-
- //If there are no layers for MDP, this mode doesnt make sense.
- if(mdpBatchSize < 1) {
- ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
- __FUNCTION__);
- return false;
- }
-
- mCurrentFrame.reset(numAppLayers);
-
- //Try with successively smaller mdp batch sizes until we succeed or reach 1
- while(mdpBatchSize > 0) {
- //Mark layers for MDP comp
- int mdpBatchLeft = mdpBatchSize;
- for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
- if(mCurrentFrame.drop[i]) {
- continue;
- }
- mCurrentFrame.isFBComposed[i] = false;
- --mdpBatchLeft;
- }
-
- mCurrentFrame.fbZ = mdpBatchSize;
- mCurrentFrame.fbCount = fbBatchSize;
- mCurrentFrame.mdpCount = mdpBatchSize;
-
- ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
- __FUNCTION__, mdpBatchSize, fbBatchSize,
- mCurrentFrame.dropCount);
-
- if(postHeuristicsHandling(ctx, list)) {
- ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
- __FUNCTION__);
- ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
- __FUNCTION__);
- return true;
- }
-
- reset(ctx);
- --mdpBatchSize;
- ++fbBatchSize;
- }
-
- return false;
-}
-
-bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
- if(mDpy or isSecurePresent(ctx, mDpy) or
- isYuvPresent(ctx, mDpy)) {
- return false;
- }
- return true;
-}
-
-bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
- hwc_display_contents_1_t* list){
- if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
- isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
- !sIsPartialUpdateActive || mDpy ) {
- return false;
- }
- if(ctx->listStats[mDpy].secureUI)
- return false;
- return true;
-}
-
-bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- const bool secureOnly = true;
- return videoOnlyComp(ctx, list, not secureOnly) or
- videoOnlyComp(ctx, list, secureOnly);
-}
-
-bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
- hwc_display_contents_1_t* list, bool secureOnly) {
- if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
- return false;
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
-
- mCurrentFrame.reset(numAppLayers);
- mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
- updateYUV(ctx, list, secureOnly, mCurrentFrame);
- int mdpCount = mCurrentFrame.mdpCount;
-
- if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
- reset(ctx);
- return false;
- }
-
- /* Bail out if we are processing only secured video layers
- * and we dont have any */
- if(!isSecurePresent(ctx, mDpy) && secureOnly){
- reset(ctx);
- return false;
- }
-
- if(mCurrentFrame.fbCount)
- mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
-
- if(sEnableYUVsplit){
- adjustForSourceSplit(ctx, list);
- }
-
- if(!postHeuristicsHandling(ctx, list)) {
- ALOGD_IF(isDebug(), "post heuristic handling failed");
- reset(ctx);
- return false;
- }
-
- ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
- __FUNCTION__);
- return true;
-}
-
-/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
-bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- // Fall back to video only composition, if AIV video mode is enabled
- if(ctx->listStats[mDpy].mAIVVideoMode) {
- ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
- __FUNCTION__, mDpy);
- return false;
- }
-
- const bool secureOnly = true;
- return mdpOnlyLayersComp(ctx, list, not secureOnly) or
- mdpOnlyLayersComp(ctx, list, secureOnly);
-
-}
-
-bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
- hwc_display_contents_1_t* list, bool secureOnly) {
-
- if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
- return false;
-
- /* Bail out if we are processing only secured video layers
- * and we dont have any */
- if(!isSecurePresent(ctx, mDpy) && secureOnly){
- reset(ctx);
- return false;
- }
-
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- mCurrentFrame.reset(numAppLayers);
- mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
-
- updateYUV(ctx, list, secureOnly, mCurrentFrame);
- /* mark secure RGB layers for MDP comp */
- updateSecureRGB(ctx, list);
-
- if(mCurrentFrame.mdpCount == 0) {
- reset(ctx);
- return false;
- }
-
- /* find the maximum batch of layers to be marked for framebuffer */
- bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
- if(!ret) {
- ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
- reset(ctx);
- return false;
- }
-
- if(sEnableYUVsplit){
- adjustForSourceSplit(ctx, list);
- }
-
- if(!postHeuristicsHandling(ctx, list)) {
- ALOGD_IF(isDebug(), "post heuristic handling failed");
- reset(ctx);
- return false;
- }
-
- ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
- __FUNCTION__);
- return true;
-}
-
-/* Checks for conditions where YUV layers cannot be bypassed */
-bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
- if(isSkipLayer(layer)) {
- ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
- return false;
- }
-
- if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
- ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
- return false;
- }
-
- if(isSecuring(ctx, layer)) {
- ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
- return false;
- }
-
- if(!isValidDimension(ctx, layer)) {
- ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
- __FUNCTION__);
- return false;
- }
-
- if(layer->planeAlpha < 0xFF) {
- ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
- in video only mode",
- __FUNCTION__);
- return false;
- }
-
- return true;
-}
-
-/* Checks for conditions where Secure RGB layers cannot be bypassed */
-bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
- if(isSkipLayer(layer)) {
- ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
- __FUNCTION__, mDpy);
- return false;
- }
-
- if(isSecuring(ctx, layer)) {
- ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
- return false;
- }
-
- if(not isSupportedForMDPComp(ctx, layer)) {
- ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
- __FUNCTION__);
- return false;
- }
- return true;
-}
-
-/* starts at fromIndex and check for each layer to find
- * if it it has overlapping with any Updating layer above it in zorder
- * till the end of the batch. returns true if it finds any intersection */
-bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
- int fromIndex, int toIndex) {
- for(int i = fromIndex; i < toIndex; i++) {
- if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
- if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
- return false;
- }
- }
- }
- return true;
-}
-
-/* Checks if given layer at targetLayerIndex has any
- * intersection with all the updating layers in beween
- * fromIndex and toIndex. Returns true if it finds intersectiion */
-bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
- int fromIndex, int toIndex, int targetLayerIndex) {
- for(int i = fromIndex; i <= toIndex; i++) {
- if(!mCurrentFrame.isFBComposed[i]) {
- if(areLayersIntersecting(&list->hwLayers[i],
- &list->hwLayers[targetLayerIndex])) {
- return true;
- }
- }
- }
- return false;
-}
-
-int MDPComp::getBatch(hwc_display_contents_1_t* list,
- int& maxBatchStart, int& maxBatchEnd,
- int& maxBatchCount) {
- int i = 0;
- int fbZOrder =-1;
- int droppedLayerCt = 0;
- while (i < mCurrentFrame.layerCount) {
- int batchCount = 0;
- int batchStart = i;
- int batchEnd = i;
- /* Adjust batch Z order with the dropped layers so far */
- int fbZ = batchStart - droppedLayerCt;
- int firstZReverseIndex = -1;
- int updatingLayersAbove = 0;//Updating layer count in middle of batch
- while(i < mCurrentFrame.layerCount) {
- if(!mCurrentFrame.isFBComposed[i]) {
- if(!batchCount) {
- i++;
- break;
- }
- updatingLayersAbove++;
- i++;
- continue;
- } else {
- if(mCurrentFrame.drop[i]) {
- i++;
- droppedLayerCt++;
- continue;
- } else if(updatingLayersAbove <= 0) {
- batchCount++;
- batchEnd = i;
- i++;
- continue;
- } else { //Layer is FBComposed, not a drop & updatingLayer > 0
-
- // We have a valid updating layer already. If layer-i not
- // have overlapping with all updating layers in between
- // batch-start and i, then we can add layer i to batch.
- if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
- batchCount++;
- batchEnd = i;
- i++;
- continue;
- } else if(canPushBatchToTop(list, batchStart, i)) {
- //If All the non-updating layers with in this batch
- //does not have intersection with the updating layers
- //above in z-order, then we can safely move the batch to
- //higher z-order. Increment fbZ as it is moving up.
- if( firstZReverseIndex < 0) {
- firstZReverseIndex = i;
- }
- batchCount++;
- batchEnd = i;
- fbZ += updatingLayersAbove;
- i++;
- updatingLayersAbove = 0;
- continue;
- } else {
- //both failed.start the loop again from here.
- if(firstZReverseIndex >= 0) {
- i = firstZReverseIndex;
- }
- break;
- }
- }
- }
- }
- if(batchCount > maxBatchCount) {
- maxBatchCount = batchCount;
- maxBatchStart = batchStart;
- maxBatchEnd = batchEnd;
- fbZOrder = fbZ;
- }
- }
- return fbZOrder;
-}
-
-bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
- hwc_display_contents_1_t* list) {
- /* Idea is to keep as many non-updating(cached) layers in FB and
- * send rest of them through MDP. This is done in 2 steps.
- * 1. Find the maximum contiguous batch of non-updating layers.
- * 2. See if we can improve this batch size for caching by adding
- * opaque layers around the batch, if they don't have
- * any overlapping with the updating layers in between.
- * NEVER mark an updating layer for caching.
- * But cached ones can be marked for MDP */
-
- int maxBatchStart = -1;
- int maxBatchEnd = -1;
- int maxBatchCount = 0;
- int fbZ = -1;
-
- /* Nothing is cached. No batching needed */
- if(mCurrentFrame.fbCount == 0) {
- return true;
- }
-
- /* No MDP comp layers, try to use other comp modes */
- if(mCurrentFrame.mdpCount == 0) {
- return false;
- }
-
- fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
-
- /* reset rest of the layers lying inside ROI for MDP comp */
- for(int i = 0; i < mCurrentFrame.layerCount; i++) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- if((i < maxBatchStart || i > maxBatchEnd) &&
- mCurrentFrame.isFBComposed[i]){
- if(!mCurrentFrame.drop[i]){
- //If an unsupported layer is being attempted to
- //be pulled out we should fail
- if(not isSupportedForMDPComp(ctx, layer)) {
- return false;
- }
- mCurrentFrame.isFBComposed[i] = false;
- }
- }
- }
-
- // update the frame data
- mCurrentFrame.fbZ = fbZ;
- mCurrentFrame.fbCount = maxBatchCount;
- mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
- mCurrentFrame.fbCount - mCurrentFrame.dropCount;
-
- ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
- mCurrentFrame.fbCount);
-
- return true;
-}
-
-void MDPComp::updateLayerCache(hwc_context_t* ctx,
- hwc_display_contents_1_t* list, FrameInfo& frame) {
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- int fbCount = 0;
-
- for(int i = 0; i < numAppLayers; i++) {
- hwc_layer_1_t * layer = &list->hwLayers[i];
- if (!layerUpdating(layer)) {
- if(!frame.drop[i])
- fbCount++;
- frame.isFBComposed[i] = true;
- } else {
- frame.isFBComposed[i] = false;
- }
- }
-
- frame.fbCount = fbCount;
- frame.mdpCount = frame.layerCount - frame.fbCount
- - frame.dropCount;
-
- ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
- __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
-}
-
-// drop other non-AIV layers from external display list.
-void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
- hwc_display_contents_1_t* list) {
- for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
- hwc_layer_1_t * layer = &list->hwLayers[i];
- if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
- mCurrentFrame.dropCount++;
- mCurrentFrame.drop[i] = true;
- }
- }
- mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
- mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
- mCurrentFrame.fbCount - mCurrentFrame.dropCount;
- ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
- __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
- mCurrentFrame.dropCount);
-}
-
-void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
- bool secureOnly, FrameInfo& frame) {
- int nYuvCount = ctx->listStats[mDpy].yuvCount;
- for(int index = 0;index < nYuvCount; index++){
- int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
- hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
-
- if(mCurrentFrame.drop[nYuvIndex]) {
- continue;
- }
-
- if(!isYUVDoable(ctx, layer)) {
- if(!frame.isFBComposed[nYuvIndex]) {
- frame.isFBComposed[nYuvIndex] = true;
- frame.fbCount++;
- }
- } else {
- if(frame.isFBComposed[nYuvIndex]) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(!secureOnly || isSecureBuffer(hnd)) {
- frame.isFBComposed[nYuvIndex] = false;
- frame.fbCount--;
- }
- }
- }
- }
-
- frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
- ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
-}
-
-void MDPComp::updateSecureRGB(hwc_context_t* ctx,
- hwc_display_contents_1_t* list) {
- int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
- for(int index = 0;index < nSecureRGBCount; index++){
- int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
- hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
-
- if(!isSecureRGBDoable(ctx, layer)) {
- if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
- mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
- mCurrentFrame.fbCount++;
- }
- } else {
- if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
- mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
- mCurrentFrame.fbCount--;
- }
- }
- }
-
- mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
- mCurrentFrame.fbCount - mCurrentFrame.dropCount;
- ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
- mCurrentFrame.fbCount);
-}
-
-hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
- hwc_display_contents_1_t* list){
- hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
-
- /* Update only the region of FB needed for composition */
- for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
- if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- hwc_rect_t dst = layer->displayFrame;
- fbRect = getUnion(fbRect, dst);
- }
- }
- trimAgainstROI(ctx, fbRect);
- return fbRect;
-}
-
-bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
-
- //Capability checks
- if(!resourceCheck(ctx, list)) {
- ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
- return false;
- }
-
- //Limitations checks
- if(!hwLimitationsCheck(ctx, list)) {
- ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
- return false;
- }
-
- //Configure framebuffer first if applicable
- if(mCurrentFrame.fbZ >= 0) {
- hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
- if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
- {
- ALOGD_IF(isDebug(), "%s configure framebuffer failed",
- __FUNCTION__);
- return false;
- }
- }
-
- mCurrentFrame.map();
-
- if(!allocLayerPipes(ctx, list)) {
- ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
- return false;
- }
-
- for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
- index++) {
- if(!mCurrentFrame.isFBComposed[index]) {
- int mdpIndex = mCurrentFrame.layerToMDP[index];
- hwc_layer_1_t* layer = &list->hwLayers[index];
-
- //Leave fbZ for framebuffer. CACHE/GLES layers go here.
- if(mdpNextZOrder == mCurrentFrame.fbZ) {
- mdpNextZOrder++;
- }
- MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
- cur_pipe->zOrder = mdpNextZOrder++;
-
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
- if(configure4k2kYuv(ctx, layer,
- mCurrentFrame.mdpToLayer[mdpIndex])
- != 0 ){
- ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
- for layer %d",__FUNCTION__, index);
- return false;
- }
- else{
- mdpNextZOrder++;
- }
- continue;
- }
- if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
- ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
- layer %d",__FUNCTION__, index);
- return false;
- }
- }
- }
-
- if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
- ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
- ,__FUNCTION__, mDpy);
- return false;
- }
-
- setRedraw(ctx, list);
- return true;
-}
-
-bool MDPComp::resourceCheck(hwc_context_t* ctx,
- hwc_display_contents_1_t* list) {
- const bool fbUsed = mCurrentFrame.fbCount;
- if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
- ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
- return false;
- }
- // Init rotCount to number of rotate sessions used by other displays
- int rotCount = ctx->mRotMgr->getNumActiveSessions();
- // Count the number of rotator sessions required for current display
- for (int index = 0; index < mCurrentFrame.layerCount; index++) {
- if(!mCurrentFrame.isFBComposed[index]) {
- hwc_layer_1_t* layer = &list->hwLayers[index];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
- rotCount++;
- }
- }
- }
- // if number of layers to rotate exceeds max rotator sessions, bail out.
- if(rotCount > RotMgr::MAX_ROT_SESS) {
- ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
- __FUNCTION__, mDpy);
- return false;
- }
- return true;
-}
-
-bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
- hwc_display_contents_1_t* list) {
-
- //A-family hw limitation:
- //If a layer need alpha scaling, MDP can not support.
- if(ctx->mMDP.version < qdutils::MDSS_V5) {
- for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
- if(!mCurrentFrame.isFBComposed[i] &&
- isAlphaScaled( &list->hwLayers[i])) {
- ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
- return false;
- }
- }
- }
-
- // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
- //If multiple layers requires downscaling and also they are overlapping
- //fall back to GPU since MDSS can not handle it.
- if(qdutils::MDPVersion::getInstance().is8x74v2() ||
- qdutils::MDPVersion::getInstance().is8x26()) {
- for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
- hwc_layer_1_t* botLayer = &list->hwLayers[i];
- if(!mCurrentFrame.isFBComposed[i] &&
- isDownscaleRequired(botLayer)) {
- //if layer-i is marked for MDP and needs downscaling
- //check if any MDP layer on top of i & overlaps with layer-i
- for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
- hwc_layer_1_t* topLayer = &list->hwLayers[j];
- if(!mCurrentFrame.isFBComposed[j] &&
- isDownscaleRequired(topLayer)) {
- hwc_rect_t r = getIntersection(botLayer->displayFrame,
- topLayer->displayFrame);
- if(isValidRect(r))
- return false;
- }
- }
- }
- }
- }
- return true;
-}
-
-void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
- //For primary display, set the dynamic refreshrate
- if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
- ctx->mUseMetaDataRefreshRate) {
- FrameInfo frame;
- frame.reset(mCurrentFrame.layerCount);
- memset(&frame.drop, 0, sizeof(frame.drop));
- frame.dropCount = 0;
- ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
- __FUNCTION__);
- updateLayerCache(ctx, list, frame);
- updateYUV(ctx, list, false /*secure only*/, frame);
- uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
- MDPVersion& mdpHw = MDPVersion::getInstance();
- if(sIdleFallBack) {
- //Set minimum panel refresh rate during idle timeout
- refreshRate = mdpHw.getMinFpsSupported();
- } else if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
- (frame.layerCount == 1)) {
- //Set the new fresh rate, if there is only one updating YUV layer
- //or there is one single RGB layer with this request
- refreshRate = ctx->listStats[mDpy].refreshRateRequest;
- }
- setRefreshRate(ctx, mDpy, refreshRate);
- }
-}
-
-int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
- int ret = 0;
- char property[PROPERTY_VALUE_MAX];
-
- if(!ctx || !list) {
- ALOGE("%s: Invalid context or list",__FUNCTION__);
- mCachedFrame.reset();
- return -1;
- }
-
- const int numLayers = ctx->listStats[mDpy].numAppLayers;
- if(mDpy == HWC_DISPLAY_PRIMARY) {
- sSimulationFlags = 0;
- if(property_get("debug.hwc.simulate", property, NULL) > 0) {
- int currentFlags = atoi(property);
- if(currentFlags != sSimulationFlags) {
- sSimulationFlags = currentFlags;
- ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
- sSimulationFlags, sSimulationFlags);
- }
- }
- }
- // reset PTOR
- if(!mDpy)
- memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
-
- //reset old data
- mCurrentFrame.reset(numLayers);
- memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
- mCurrentFrame.dropCount = 0;
-
- //Do not cache the information for next draw cycle.
- if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
- ALOGI("%s: Unsupported layer count for mdp composition",
- __FUNCTION__);
- mCachedFrame.reset();
-#ifdef DYNAMIC_FPS
- // Reset refresh rate
- setRefreshRate(ctx, mDpy, ctx->dpyAttr[mDpy].refreshRate);
-#endif
- return -1;
- }
-
- // Detect the start of animation and fall back to GPU only once to cache
- // all the layers in FB and display FB content untill animation completes.
- if(ctx->listStats[mDpy].isDisplayAnimating) {
- mCurrentFrame.needsRedraw = false;
- if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
- mCurrentFrame.needsRedraw = true;
- ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
- }
- setMDPCompLayerFlags(ctx, list);
- mCachedFrame.updateCounts(mCurrentFrame);
-#ifdef DYNAMIC_FPS
- // Reset refresh rate
- setRefreshRate(ctx, mDpy, ctx->dpyAttr[mDpy].refreshRate);
-#endif
- ret = -1;
- return ret;
- } else {
- ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
- }
-
- if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
- mCachedFrame.isSameFrame(ctx,mDpy,list)) {
-
- ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
- mCurrentFrame.needsRedraw = false;
- setMDPCompLayerFlags(ctx, list);
- mCachedFrame.updateCounts(mCurrentFrame);
- return -1;
-
- }
-
- //Hard conditions, if not met, cannot do MDP comp
- if(isFrameDoable(ctx)) {
- generateROI(ctx, list);
- // if AIV Video mode is enabled, drop all non AIV layers from the
- // external display list.
- if(ctx->listStats[mDpy].mAIVVideoMode) {
- dropNonAIVLayers(ctx, list);
- }
-
- // if tryFullFrame fails, try to push all video and secure RGB layers
- // to MDP for composition.
- mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
- tryVideoOnly(ctx, list);
- if(mModeOn) {
- setMDPCompLayerFlags(ctx, list);
- } else {
- resetROI(ctx, mDpy);
- reset(ctx);
- memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
- mCurrentFrame.dropCount = 0;
- ret = -1;
- ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
- "MDP Composition Strategies Failed");
- }
- } else {
- if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
- enablePartialUpdateForMDP3) {
- generateROI(ctx, list);
- for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
- ctx->copybitDrop[i] = mCurrentFrame.drop[i];
- }
- }
- ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
- __FUNCTION__);
- ret = -1;
- }
-
- if(isDebug()) {
- ALOGD("GEOMETRY change: %d",
- (list->flags & HWC_GEOMETRY_CHANGED));
- android::String8 sDump("");
- dump(sDump, ctx);
- ALOGD("%s",sDump.string());
- }
-
-#ifdef DYNAMIC_FPS
- setDynRefreshRate(ctx, list);
-#endif
-
- mCachedFrame.updateCounts(mCurrentFrame);
- return ret;
-}
-
-bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
-
- bool bRet = true;
- int mdpIndex = mCurrentFrame.layerToMDP[index];
- PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
- info.pipeInfo = new MdpYUVPipeInfo;
- info.rot = NULL;
- MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
-
- pipe_info.lIndex = ovutils::OV_INVALID;
- pipe_info.rIndex = ovutils::OV_INVALID;
-
- Overlay::PipeSpecs pipeSpecs;
- pipeSpecs.formatClass = Overlay::FORMAT_YUV;
- pipeSpecs.needsScaling = true;
- pipeSpecs.dpy = mDpy;
- pipeSpecs.fb = false;
-
- pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
- if(pipe_info.lIndex == ovutils::OV_INVALID){
- bRet = false;
- ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
- __FUNCTION__);
- }
- pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
- if(pipe_info.rIndex == ovutils::OV_INVALID){
- bRet = false;
- ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
- __FUNCTION__);
- }
- return bRet;
-}
-
-int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
- int fd = -1;
- if (ctx->mPtorInfo.isActive()) {
- fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
- if (fd < 0) {
- ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
- }
- }
- return fd;
-}
-//=============MDPCompNonSplit==================================================
-
-void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- //If 4k2k Yuv layer split is possible, and if
- //fbz is above 4k2k layer, increment fb zorder by 1
- //as we split 4k2k layer and increment zorder for right half
- //of the layer
- if(!ctx)
- return;
- if(mCurrentFrame.fbZ >= 0) {
- for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
- index++) {
- if(!mCurrentFrame.isFBComposed[index]) {
- if(mdpNextZOrder == mCurrentFrame.fbZ) {
- mdpNextZOrder++;
- }
- mdpNextZOrder++;
- hwc_layer_1_t* layer = &list->hwLayers[index];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(isYUVSplitNeeded(hnd)) {
- if(mdpNextZOrder <= mCurrentFrame.fbZ)
- mCurrentFrame.fbZ += 1;
- mdpNextZOrder++;
- //As we split 4kx2k yuv layer and program to 2 VG pipes
- //(if available) increase mdpcount by 1.
- mCurrentFrame.mdpCount++;
- }
- }
- }
- }
-}
-
-/*
- * Configures pipe(s) for MDP composition
- */
-int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& PipeLayerPair) {
- MdpPipeInfoNonSplit& mdp_info =
- *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
- eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
- eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
- eDest dest = mdp_info.index;
-
- ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
- __FUNCTION__, layer, zOrder, dest);
-
- return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
- &PipeLayerPair.rot);
-}
-
-bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- for(int index = 0; index < mCurrentFrame.layerCount; index++) {
-
- if(mCurrentFrame.isFBComposed[index]) continue;
-
- hwc_layer_1_t* layer = &list->hwLayers[index];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
- if(allocSplitVGPipesfor4k2k(ctx, index)){
- continue;
- }
- }
-
- int mdpIndex = mCurrentFrame.layerToMDP[index];
- PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
- info.pipeInfo = new MdpPipeInfoNonSplit;
- info.rot = NULL;
- MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
-
- Overlay::PipeSpecs pipeSpecs;
- pipeSpecs.formatClass = isYuvBuffer(hnd) ?
- Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
- pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
- (qdutils::MDPVersion::getInstance().is8x26() and
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
- pipeSpecs.dpy = mDpy;
- pipeSpecs.fb = false;
- pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
-
- pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
-
- if(pipe_info.index == ovutils::OV_INVALID) {
- ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
- return false;
- }
- }
- return true;
-}
-
-int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& PipeLayerPair) {
- MdpYUVPipeInfo& mdp_info =
- *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
- eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
- eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
- eDest lDest = mdp_info.lIndex;
- eDest rDest = mdp_info.rIndex;
-
- return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
- lDest, rDest, &PipeLayerPair.rot);
-}
-
-bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
-
- if(!isEnabled() or !mModeOn) {
- ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
- return true;
- }
-
- overlay::Overlay& ov = *ctx->mOverlay;
- LayerProp *layerProp = ctx->layerProp[mDpy];
-
- int numHwLayers = ctx->listStats[mDpy].numAppLayers;
- for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
- {
- if(mCurrentFrame.isFBComposed[i]) continue;
-
- hwc_layer_1_t *layer = &list->hwLayers[i];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(!hnd) {
- if (!(layer->flags & HWC_COLOR_FILL)) {
- ALOGE("%s handle null", __FUNCTION__);
- return false;
- }
- // No PLAY for Color layer
- layerProp[i].mFlags &= ~HWC_MDPCOMP;
- continue;
- }
-
- int mdpIndex = mCurrentFrame.layerToMDP[i];
-
- if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
- {
- MdpYUVPipeInfo& pipe_info =
- *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
- Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
- ovutils::eDest indexL = pipe_info.lIndex;
- ovutils::eDest indexR = pipe_info.rIndex;
- int fd = hnd->fd;
- uint32_t offset = (uint32_t)hnd->offset;
- if(rot) {
- rot->queueBuffer(fd, offset);
- fd = rot->getDstMemId();
- offset = rot->getDstOffset();
- }
- if(indexL != ovutils::OV_INVALID) {
- ovutils::eDest destL = (ovutils::eDest)indexL;
- ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer, hnd, indexL );
- if (!ov.queueBuffer(fd, offset, destL)) {
- ALOGE("%s: queueBuffer failed for display:%d",
- __FUNCTION__, mDpy);
- return false;
- }
- }
-
- if(indexR != ovutils::OV_INVALID) {
- ovutils::eDest destR = (ovutils::eDest)indexR;
- ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer, hnd, indexR );
- if (!ov.queueBuffer(fd, offset, destR)) {
- ALOGE("%s: queueBuffer failed for display:%d",
- __FUNCTION__, mDpy);
- return false;
- }
- }
- }
- else{
- MdpPipeInfoNonSplit& pipe_info =
- *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
- ovutils::eDest dest = pipe_info.index;
- if(dest == ovutils::OV_INVALID) {
- ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
- return false;
- }
-
- if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
- continue;
- }
-
- int fd = hnd->fd;
- uint32_t offset = (uint32_t)hnd->offset;
- int index = ctx->mPtorInfo.getPTORArrayIndex(i);
- if (!mDpy && (index != -1)) {
- hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
- fd = hnd->fd;
- offset = 0;
- }
-
- ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer,
- hnd, dest );
-
- Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
- if(rot) {
- if(!rot->queueBuffer(fd, offset))
- return false;
- fd = rot->getDstMemId();
- offset = rot->getDstOffset();
- }
-
- if (!ov.queueBuffer(fd, offset, dest)) {
- ALOGE("%s: queueBuffer failed for display:%d ",
- __FUNCTION__, mDpy);
- return false;
- }
- }
-
- layerProp[i].mFlags &= ~HWC_MDPCOMP;
- }
- return true;
-}
-
-//=============MDPCompSplit===================================================
-
-void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
- hwc_display_contents_1_t* list){
- //if 4kx2k yuv layer is totally present in either in left half
- //or right half then try splitting the yuv layer to avoid decimation
- const int lSplit = getLeftSplit(ctx, mDpy);
- if(mCurrentFrame.fbZ >= 0) {
- for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
- index++) {
- if(!mCurrentFrame.isFBComposed[index]) {
- if(mdpNextZOrder == mCurrentFrame.fbZ) {
- mdpNextZOrder++;
- }
- mdpNextZOrder++;
- hwc_layer_1_t* layer = &list->hwLayers[index];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(isYUVSplitNeeded(hnd)) {
- hwc_rect_t dst = layer->displayFrame;
- if((dst.left > lSplit) || (dst.right < lSplit)) {
- mCurrentFrame.mdpCount += 1;
- }
- if(mdpNextZOrder <= mCurrentFrame.fbZ)
- mCurrentFrame.fbZ += 1;
- mdpNextZOrder++;
- }
- }
- }
- }
-}
-
-bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
- MdpPipeInfoSplit& pipe_info) {
-
- const int lSplit = getLeftSplit(ctx, mDpy);
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- hwc_rect_t dst = layer->displayFrame;
- pipe_info.lIndex = ovutils::OV_INVALID;
- pipe_info.rIndex = ovutils::OV_INVALID;
-
- Overlay::PipeSpecs pipeSpecs;
- pipeSpecs.formatClass = isYuvBuffer(hnd) ?
- Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
- pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
- pipeSpecs.dpy = mDpy;
- pipeSpecs.mixer = Overlay::MIXER_LEFT;
- pipeSpecs.fb = false;
-
- // Acquire pipe only for the updating half
- hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
- hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
-
- if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
- pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
- if(pipe_info.lIndex == ovutils::OV_INVALID)
- return false;
- }
-
- if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
- pipeSpecs.mixer = Overlay::MIXER_RIGHT;
- pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
- if(pipe_info.rIndex == ovutils::OV_INVALID)
- return false;
- }
-
- return true;
-}
-
-bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
-
- if(mCurrentFrame.isFBComposed[index]) continue;
-
- hwc_layer_1_t* layer = &list->hwLayers[index];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- hwc_rect_t dst = layer->displayFrame;
- const int lSplit = getLeftSplit(ctx, mDpy);
- if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
- if((dst.left > lSplit)||(dst.right < lSplit)){
- if(allocSplitVGPipesfor4k2k(ctx, index)){
- continue;
- }
- }
- }
- int mdpIndex = mCurrentFrame.layerToMDP[index];
- PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
- info.pipeInfo = new MdpPipeInfoSplit;
- info.rot = NULL;
- MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
-
- if(!acquireMDPPipes(ctx, layer, pipe_info)) {
- ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
- __FUNCTION__);
- return false;
- }
- }
- return true;
-}
-
-int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& PipeLayerPair) {
- const int lSplit = getLeftSplit(ctx, mDpy);
- hwc_rect_t dst = layer->displayFrame;
- if((dst.left > lSplit)||(dst.right < lSplit)){
- MdpYUVPipeInfo& mdp_info =
- *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
- eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
- eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
- eDest lDest = mdp_info.lIndex;
- eDest rDest = mdp_info.rIndex;
-
- return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
- lDest, rDest, &PipeLayerPair.rot);
- }
- else{
- return configure(ctx, layer, PipeLayerPair);
- }
-}
-
-/*
- * Configures pipe(s) for MDP composition
- */
-int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& PipeLayerPair) {
- MdpPipeInfoSplit& mdp_info =
- *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
- eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
- eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
- eDest lDest = mdp_info.lIndex;
- eDest rDest = mdp_info.rIndex;
-
- ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
- "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
-
- return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
- rDest, &PipeLayerPair.rot);
-}
-
-bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
-
- if(!isEnabled() or !mModeOn) {
- ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
- return true;
- }
-
- overlay::Overlay& ov = *ctx->mOverlay;
- LayerProp *layerProp = ctx->layerProp[mDpy];
-
- int numHwLayers = ctx->listStats[mDpy].numAppLayers;
- for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
- {
- if(mCurrentFrame.isFBComposed[i]) continue;
-
- hwc_layer_1_t *layer = &list->hwLayers[i];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(!hnd) {
- ALOGE("%s handle null", __FUNCTION__);
- return false;
- }
-
- if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
- continue;
- }
-
- int mdpIndex = mCurrentFrame.layerToMDP[i];
-
- if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
- {
- MdpYUVPipeInfo& pipe_info =
- *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
- Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
- ovutils::eDest indexL = pipe_info.lIndex;
- ovutils::eDest indexR = pipe_info.rIndex;
- int fd = hnd->fd;
- uint32_t offset = (uint32_t)hnd->offset;
- if(rot) {
- rot->queueBuffer(fd, offset);
- fd = rot->getDstMemId();
- offset = rot->getDstOffset();
- }
- if(indexL != ovutils::OV_INVALID) {
- ovutils::eDest destL = (ovutils::eDest)indexL;
- ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer, hnd, indexL );
- if (!ov.queueBuffer(fd, offset, destL)) {
- ALOGE("%s: queueBuffer failed for display:%d",
- __FUNCTION__, mDpy);
- return false;
- }
- }
-
- if(indexR != ovutils::OV_INVALID) {
- ovutils::eDest destR = (ovutils::eDest)indexR;
- ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer, hnd, indexR );
- if (!ov.queueBuffer(fd, offset, destR)) {
- ALOGE("%s: queueBuffer failed for display:%d",
- __FUNCTION__, mDpy);
- return false;
- }
- }
- }
- else{
- MdpPipeInfoSplit& pipe_info =
- *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
- Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
-
- ovutils::eDest indexL = pipe_info.lIndex;
- ovutils::eDest indexR = pipe_info.rIndex;
-
- int fd = hnd->fd;
- uint32_t offset = (uint32_t)hnd->offset;
- int index = ctx->mPtorInfo.getPTORArrayIndex(i);
- if (!mDpy && (index != -1)) {
- hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
- fd = hnd->fd;
- offset = 0;
- }
-
- if(ctx->mAD->draw(ctx, fd, offset)) {
- fd = ctx->mAD->getDstFd();
- offset = ctx->mAD->getDstOffset();
- }
-
- if(rot) {
- rot->queueBuffer(fd, offset);
- fd = rot->getDstMemId();
- offset = rot->getDstOffset();
- }
-
- //************* play left mixer **********
- if(indexL != ovutils::OV_INVALID) {
- ovutils::eDest destL = (ovutils::eDest)indexL;
- ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer, hnd, indexL );
- if (!ov.queueBuffer(fd, offset, destL)) {
- ALOGE("%s: queueBuffer failed for left mixer",
- __FUNCTION__);
- return false;
- }
- }
-
- //************* play right mixer **********
- if(indexR != ovutils::OV_INVALID) {
- ovutils::eDest destR = (ovutils::eDest)indexR;
- ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer, hnd, indexR );
- if (!ov.queueBuffer(fd, offset, destR)) {
- ALOGE("%s: queueBuffer failed for right mixer",
- __FUNCTION__);
- return false;
- }
- }
- }
-
- layerProp[i].mFlags &= ~HWC_MDPCOMP;
- }
-
- return true;
-}
-
-//================MDPCompSrcSplit==============================================
-bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
- MdpPipeInfoSplit& pipe_info) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- hwc_rect_t dst = layer->displayFrame;
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- pipe_info.lIndex = ovutils::OV_INVALID;
- pipe_info.rIndex = ovutils::OV_INVALID;
-
- //If 2 pipes are staged on a single stage of a mixer, then the left pipe
- //should have a higher priority than the right one. Pipe priorities are
- //starting with VG0, VG1 ... , RGB0 ..., DMA1
-
- Overlay::PipeSpecs pipeSpecs;
- pipeSpecs.formatClass = isYuvBuffer(hnd) ?
- Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
- pipeSpecs.needsScaling = qhwc::needsScaling(layer);
- pipeSpecs.dpy = mDpy;
- pipeSpecs.fb = false;
-
- //1 pipe by default for a layer
- pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
- if(pipe_info.lIndex == ovutils::OV_INVALID) {
- return false;
- }
-
- /* Use 2 pipes IF
- a) Layer's crop width is > 2048 or
- b) Layer's dest width > 2048 or
- c) On primary, driver has indicated with caps to split always. This is
- based on an empirically derived value of panel height. Applied only
- if the layer's width is > mixer's width
- */
-
- MDPVersion& mdpHw = MDPVersion::getInstance();
- bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
- mdpHw.isSrcSplitAlways();
- int lSplit = getLeftSplit(ctx, mDpy);
- int dstWidth = dst.right - dst.left;
- int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
- crop.right - crop.left;
-
- //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
- //pipe line length, we are still using 2 pipes. This is fine just because
- //this is source split where destination doesn't matter. Evaluate later to
- //see if going through all the calcs to save a pipe is worth it
- if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
- cropWidth > (int) mdpHw.getMaxMixerWidth() or
- (primarySplitAlways and (cropWidth > lSplit))) {
- pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
- if(pipe_info.rIndex == ovutils::OV_INVALID) {
- return false;
- }
-
- // Return values
- // 1 Left pipe is higher priority, do nothing.
- // 0 Pipes of same priority.
- //-1 Right pipe is of higher priority, needs swap.
- if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
- pipe_info.rIndex) == -1) {
- qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
- }
- }
-
- return true;
-}
-
-int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& PipeLayerPair) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(!hnd) {
- ALOGE("%s: layer handle is NULL", __FUNCTION__);
- return -1;
- }
- MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
- MdpPipeInfoSplit& mdp_info =
- *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
- Rotator **rot = &PipeLayerPair.rot;
- eZorder z = static_cast<eZorder>(mdp_info.zOrder);
- eDest lDest = mdp_info.lIndex;
- eDest rDest = mdp_info.rIndex;
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t dst = layer->displayFrame;
- int transform = layer->transform;
- eTransform orient = static_cast<eTransform>(transform);
- int rotFlags = ROT_FLAGS_NONE;
- uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
- Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
-
- ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
- "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
-
- // Handle R/B swap
- if (layer->flags & HWC_FORMAT_RB_SWAP) {
- if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
- whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
- else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
- whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
- }
- // update source crop and destination position of AIV video layer.
- if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
- updateCoordinates(ctx, crop, dst, mDpy);
- }
- /* Calculate the external display position based on MDP downscale,
- ActionSafe, and extorientation features. */
- calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
-
- int downscale = getRotDownscale(ctx, layer);
- eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
- setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
-
- if(lDest != OV_INVALID && rDest != OV_INVALID) {
- //Enable overfetch
- setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
- }
-
- if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
- (*rot) = ctx->mRotMgr->getNext();
- if((*rot) == NULL) return -1;
- ctx->mLayerRotMap[mDpy]->add(layer, *rot);
- //If the video is using a single pipe, enable BWC
- if(rDest == OV_INVALID) {
- BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
- }
- //Configure rotator for pre-rotation
- if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
- ALOGE("%s: configRotator failed!", __FUNCTION__);
- return -1;
- }
- updateSource(orient, whf, crop, *rot);
- rotFlags |= ovutils::ROT_PREROTATED;
- }
-
- //If 2 pipes being used, divide layer into half, crop and dst
- hwc_rect_t cropL = crop;
- hwc_rect_t cropR = crop;
- hwc_rect_t dstL = dst;
- hwc_rect_t dstR = dst;
- if(lDest != OV_INVALID && rDest != OV_INVALID) {
- cropL.right = (crop.right + crop.left) / 2;
- cropR.left = cropL.right;
- sanitizeSourceCrop(cropL, cropR, hnd);
-
- bool cropSwap = false;
- //Swap crops on H flip since 2 pipes are being used
- if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
- hwc_rect_t tmp = cropL;
- cropL = cropR;
- cropR = tmp;
- cropSwap = true;
- }
-
- //cropSwap trick: If the src and dst widths are both odd, let us say
- //2507, then splitting both into half would cause left width to be 1253
- //and right 1254. If crop is swapped because of H flip, this will cause
- //left crop width to be 1254, whereas left dst width remains 1253, thus
- //inducing a scaling that is unaccounted for. To overcome that we add 1
- //to the dst width if there is a cropSwap. So if the original width was
- //2507, the left dst width will be 1254. Even if the original width was
- //even for ex: 2508, the left dst width will still remain 1254.
- dstL.right = (dst.right + dst.left + cropSwap) / 2;
- dstR.left = dstL.right;
- }
-
- //For the mdp, since either we are pre-rotating or MDP does flips
- orient = OVERLAY_TRANSFORM_0;
- transform = 0;
-
- //configure left pipe
- if(lDest != OV_INVALID) {
- PipeArgs pargL(mdpFlags, whf, z,
- static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
- (ovutils::eBlending) getBlending(layer->blending));
-
- if(configMdp(ctx->mOverlay, pargL, orient,
- cropL, dstL, metadata, lDest) < 0) {
- ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
- return -1;
- }
- }
-
- //configure right pipe
- if(rDest != OV_INVALID) {
- PipeArgs pargR(mdpFlags, whf, z,
- static_cast<eRotFlags>(rotFlags),
- layer->planeAlpha,
- (ovutils::eBlending) getBlending(layer->blending));
- if(configMdp(ctx->mOverlay, pargR, orient,
- cropR, dstR, metadata, rDest) < 0) {
- ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
- return -1;
- }
- }
-
- return 0;
-}
-
-int MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
- Locker::Autolock _l(ctx->mDrawLock);
- const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
- char path[MAX_SYSFS_FILE_PATH];
- snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
- int fd = open(path, O_RDONLY);
- if(fd < 0) {
- ALOGE("%s: Failed to open sysfs node: %s", __FUNCTION__, path);
- return -1;
- }
- char value[4];
- ssize_t size_read = read(fd, value, sizeof(value)-1);
- if(size_read <= 0) {
- ALOGE("%s: Failed to read sysfs node: %s", __FUNCTION__, path);
- close(fd);
- return -1;
- }
- close(fd);
- value[size_read] = '\0';
- return atoi(value);
-}
-
-int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
- Locker::Autolock _l(ctx->mDrawLock);
- const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
- char path[MAX_SYSFS_FILE_PATH];
- snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
- int fd = open(path, O_WRONLY);
- if(fd < 0) {
- ALOGE("%s: Failed to open sysfs node: %s", __FUNCTION__, path);
- return -1;
- }
- char value[4];
- snprintf(value, sizeof(value), "%d", (int)enable);
- ssize_t ret = write(fd, value, strlen(value));
- if(ret <= 0) {
- ALOGE("%s: Failed to write to sysfs nodes: %s", __FUNCTION__, path);
- close(fd);
- return -1;
- }
- close(fd);
- return 0;
-}
-}; //namespace
-
diff --git a/msm8909/libhwcomposer/hwc_mdpcomp.h b/msm8909/libhwcomposer/hwc_mdpcomp.h
deleted file mode 100644
index e6b0228..0000000
--- a/msm8909/libhwcomposer/hwc_mdpcomp.h
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 HWC_MDP_COMP
-#define HWC_MDP_COMP
-
-#include <hwc_utils.h>
-#include <idle_invalidator.h>
-#include <cutils/properties.h>
-#include <overlay.h>
-
-#define MAX_PIPES_PER_MIXER 4
-
-namespace overlay {
-class Rotator;
-};
-
-namespace qhwc {
-namespace ovutils = overlay::utils;
-
-class MDPComp {
-public:
- explicit MDPComp(int);
- virtual ~MDPComp(){};
- /*sets up mdp comp for the current frame */
- int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- /* draw */
- virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;
- //Reset values
- void reset();
- /* dumpsys */
- void dump(android::String8& buf, hwc_context_t *ctx);
- bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
- bool isMDPComp() { return mModeOn; }
- int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- static MDPComp* getObject(hwc_context_t *ctx, const int& dpy);
- /* Handler to invoke frame redraw on Idle Timer expiry */
- static void timeout_handler(void *udata);
- /* Initialize MDP comp*/
- static bool init(hwc_context_t *ctx);
- static void resetIdleFallBack() { sIdleFallBack = false; }
- static bool isIdleFallback() { return sIdleFallBack; }
- static void dynamicDebug(bool enable){ sDebugLogs = enable; }
- static void setIdleTimeout(const uint32_t& timeout);
- static int setPartialUpdatePref(hwc_context_t *ctx, bool enable);
- void setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- static int getPartialUpdatePref(hwc_context_t *ctx);
- static void enablePartialUpdate(bool enable)
- { sIsPartialUpdateActive = enable; };
-
-protected:
- enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
-
- enum ePipeType {
- MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
- MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
- MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA,
- MDPCOMP_OV_ANY,
- };
-
- //Simulation flags
- enum {
- MDPCOMP_AVOID_FULL_MDP = 0x001,
- MDPCOMP_AVOID_CACHE_MDP = 0x002,
- MDPCOMP_AVOID_LOAD_MDP = 0x004,
- MDPCOMP_AVOID_VIDEO_ONLY = 0x008,
- MDPCOMP_AVOID_MDP_ONLY_LAYERS = 0x010,
- };
-
- /* mdp pipe data */
- struct MdpPipeInfo {
- int zOrder;
- virtual ~MdpPipeInfo(){};
- };
-
- struct MdpYUVPipeInfo : public MdpPipeInfo{
- ovutils::eDest lIndex;
- ovutils::eDest rIndex;
- virtual ~MdpYUVPipeInfo(){};
- };
-
- /* per layer data */
- struct PipeLayerPair {
- MdpPipeInfo *pipeInfo;
- overlay::Rotator* rot;
- int listIndex;
- };
-
- /* per frame data */
- struct FrameInfo {
- /* maps layer list to mdp list */
- int layerCount;
- int layerToMDP[MAX_NUM_APP_LAYERS];
-
- /* maps mdp list to layer list */
- int mdpCount;
- struct PipeLayerPair mdpToLayer[MAX_PIPES_PER_MIXER];
-
- /* layer composing on FB? */
- int fbCount;
- bool isFBComposed[MAX_NUM_APP_LAYERS];
- /* layers lying outside ROI. Will
- * be dropped off from the composition */
- int dropCount;
- bool drop[MAX_NUM_APP_LAYERS];
-
- bool needsRedraw;
- int fbZ;
-
- /* c'tor */
- FrameInfo();
- /* clear old frame data */
- void reset(const int& numLayers);
- void map();
- };
-
- /* cached data */
- struct LayerCache {
- int layerCount;
- bool isFBComposed[MAX_NUM_APP_LAYERS];
- bool drop[MAX_NUM_APP_LAYERS];
-
- /* c'tor */
- LayerCache();
- /* clear caching info*/
- void reset();
- void updateCounts(const FrameInfo&);
- bool isSameFrame(const FrameInfo& curFrame,
- hwc_display_contents_1_t* list);
- bool isSameFrame(hwc_context_t *ctx, int dpy,
- hwc_display_contents_1_t* list);
- };
-
- /* allocates pipe from pipe book */
- virtual bool allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) = 0;
- /* configures MPD pipes */
- virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair) = 0;
- /* Increments mdpCount if 4k2k yuv layer split is enabled.
- * updates framebuffer z order if fb lies above source-split layer */
- virtual void adjustForSourceSplit(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) = 0;
- /* configures 4kx2k yuv layer*/
- virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& PipeLayerPair) = 0;
- /* generates ROI based on the modified area of the frame */
- virtual void generateROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) = 0;
- /* validates the ROI generated for fallback conditions */
- virtual bool validateAndApplyROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) = 0;
- /* Trims fbRect calculated against ROI generated */
- virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) = 0;
-
- /* set/reset flags for MDPComp */
- void setMDPCompLayerFlags(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- void setRedraw(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- /* checks for conditions where mdpcomp is not possible */
- bool isFrameDoable(hwc_context_t *ctx);
- /* checks for conditions where RGB layers cannot be bypassed */
- bool tryFullFrame(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- /* checks if full MDP comp can be done */
- bool fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- /* Full MDP Composition with Peripheral Tiny Overlap Removal */
- bool fullMDPCompWithPTOR(hwc_context_t *ctx,hwc_display_contents_1_t* list);
- /* check if we can use layer cache to do at least partial MDP comp */
- bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- /* Partial MDP comp that uses caching to save power as primary goal */
- bool cacheBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- /* Partial MDP comp that balances the load between MDP and GPU such that
- * MDP is loaded to the max of its capacity. The lower z order layers are
- * fed to MDP, whereas the upper ones to GPU, because the upper ones have
- * lower number of pixels and can reduce GPU processing time */
- bool loadBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- /* Checks if its worth doing load based partial comp */
- bool isLoadBasedCompDoable(hwc_context_t *ctx);
- /* checks for conditions where only video can be bypassed */
- bool tryVideoOnly(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- bool videoOnlyComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
- bool secureOnly);
- /* checks for conditions where only secure RGB and video can be bypassed */
- bool tryMDPOnlyLayers(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- bool mdpOnlyLayersComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
- bool secureOnly);
- /* checks for conditions where YUV layers cannot be bypassed */
- bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
- /* checks for conditions where Secure RGB layers cannot be bypassed */
- bool isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
- /* checks if MDP/MDSS can process current list w.r.to HW limitations
- * All peculiar HW limitations should go here */
- bool hwLimitationsCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
- /* Is debug enabled */
- static bool isDebug() { return sDebugLogs ? true : false; };
- /* Is feature enabled */
- static bool isEnabled() { return sEnabled; };
- /* checks for mdp comp dimension limitation */
- bool isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer);
- /* tracks non updating layers*/
- void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list,
- FrameInfo& frame);
- /* optimize layers for mdp comp*/
- bool markLayersForCaching(hwc_context_t* ctx,
- hwc_display_contents_1_t* list);
- int getBatch(hwc_display_contents_1_t* list,
- int& maxBatchStart, int& maxBatchEnd,
- int& maxBatchCount);
- bool canPushBatchToTop(const hwc_display_contents_1_t* list,
- int fromIndex, int toIndex);
- bool intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
- int fromIndex, int toIndex, int targetLayerIndex);
-
- /* drop other non-AIV layers from external display list.*/
- void dropNonAIVLayers(hwc_context_t* ctx, hwc_display_contents_1_t* list);
-
- /* updates cache map with YUV info */
- void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
- bool secureOnly, FrameInfo& frame);
- /* updates cache map with secure RGB info */
- void updateSecureRGB(hwc_context_t* ctx,
- hwc_display_contents_1_t* list);
- /* Validates if the GPU/MDP layer split chosen by a strategy is supported
- * by MDP.
- * Sets up MDP comp data structures to reflect covnversion from layers to
- * overlay pipes.
- * Configures overlay.
- * Configures if GPU should redraw.
- */
- bool postHeuristicsHandling(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- void reset(hwc_context_t *ctx);
- bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
- bool resourceCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
- hwc_rect_t getUpdatingFBRect(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- /* checks for conditions to enable partial udpate */
- bool canPartialUpdate(hwc_context_t *ctx, hwc_display_contents_1_t* list);
-
- int mDpy;
- static bool sEnabled;
- static bool sEnableMixedMode;
- static int sSimulationFlags;
- static bool sDebugLogs;
- static bool sIdleFallBack;
- static int sMaxPipesPerMixer;
- static bool sSrcSplitEnabled;
- static IdleInvalidator *sIdleInvalidator;
- struct FrameInfo mCurrentFrame;
- struct LayerCache mCachedFrame;
- static bool sIsPartialUpdateActive;
- //Enable 4kx2k yuv layer split
- static bool sEnableYUVsplit;
- bool mModeOn; // if prepare happened
- bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
- bool mPrevModeOn; //if previous prepare happened
- //Enable Partial Update for MDP3 targets
- static bool enablePartialUpdateForMDP3;
-};
-
-class MDPCompNonSplit : public MDPComp {
-public:
- explicit MDPCompNonSplit(int dpy):MDPComp(dpy){};
- virtual ~MDPCompNonSplit(){};
- virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-
-private:
- struct MdpPipeInfoNonSplit : public MdpPipeInfo {
- ovutils::eDest index;
- virtual ~MdpPipeInfoNonSplit() {};
- };
-
- /* configure's overlay pipes for the frame */
- virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair);
-
- /* allocates pipes to selected candidates */
- virtual bool allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
-
- /* Increments mdpCount if 4k2k yuv layer split is enabled.
- * updates framebuffer z order if fb lies above source-split layer */
- virtual void adjustForSourceSplit(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
-
- /* configures 4kx2k yuv layer to 2 VG pipes*/
- virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& PipeLayerPair);
- /* generates ROI based on the modified area of the frame */
- virtual void generateROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- /* validates the ROI generated for fallback conditions */
- virtual bool validateAndApplyROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- /* Trims fbRect calculated against ROI generated */
- virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect);
-};
-
-class MDPCompSplit : public MDPComp {
-public:
- explicit MDPCompSplit(int dpy):MDPComp(dpy){};
- virtual ~MDPCompSplit(){};
- virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-
-protected:
- struct MdpPipeInfoSplit : public MdpPipeInfo {
- ovutils::eDest lIndex;
- ovutils::eDest rIndex;
- virtual ~MdpPipeInfoSplit() {};
- };
-
- virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
- MdpPipeInfoSplit& pipe_info);
-
- /* configure's overlay pipes for the frame */
- virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair);
-
- /* allocates pipes to selected candidates */
- virtual bool allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
-private:
- /* Increments mdpCount if 4k2k yuv layer split is enabled.
- * updates framebuffer z order if fb lies above source-split layer */
- virtual void adjustForSourceSplit(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
-
- /* configures 4kx2k yuv layer*/
- virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& PipeLayerPair);
- /* generates ROI based on the modified area of the frame */
- virtual void generateROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- /* validates the ROI generated for fallback conditions */
- virtual bool validateAndApplyROI(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- /* Trims fbRect calculated against ROI generated */
- virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect);
-};
-
-class MDPCompSrcSplit : public MDPCompSplit {
-public:
- explicit MDPCompSrcSplit(int dpy) : MDPCompSplit(dpy){};
- virtual ~MDPCompSrcSplit(){};
-private:
- virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
- MdpPipeInfoSplit& pipe_info);
-
- virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair);
-};
-
-}; //namespace
-#endif
diff --git a/msm8909/libhwcomposer/hwc_qclient.cpp b/msm8909/libhwcomposer/hwc_qclient.cpp
deleted file mode 100644
index 4db4fa7..0000000
--- a/msm8909/libhwcomposer/hwc_qclient.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright (c) 2013-15, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR CLIENTS; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <hwc_qclient.h>
-#include <IQService.h>
-#include <hwc_utils.h>
-#include <mdp_version.h>
-#include <hwc_mdpcomp.h>
-#include <hwc_virtual.h>
-#include <overlay.h>
-#include <display_config.h>
-#include <hwc_qdcm.h>
-
-#define QCLIENT_DEBUG 0
-
-using namespace android;
-using namespace qService;
-using namespace qhwc;
-using namespace overlay;
-using namespace qdutils;
-using namespace qQdcm;
-
-namespace qClient {
-
-// ----------------------------------------------------------------------------
-QClient::QClient(hwc_context_t *ctx) : mHwcContext(ctx),
- mMPDeathNotifier(new MPDeathNotifier(ctx))
-{
- ALOGD_IF(QCLIENT_DEBUG, "QClient Constructor invoked");
-}
-
-QClient::~QClient()
-{
- ALOGD_IF(QCLIENT_DEBUG,"QClient Destructor invoked");
-}
-
-static void securing(hwc_context_t *ctx, uint32_t startEnd) {
- //The only way to make this class in this process subscribe to media
- //player's death.
- IMediaDeathNotifier::getMediaPlayerService();
-
- ctx->mDrawLock.lock();
- ctx->mSecuring = startEnd;
- //We're done securing
- if(startEnd == IQService::END)
- ctx->mSecureMode = true;
- ctx->mDrawLock.unlock();
-
- if(ctx->proc)
- ctx->proc->invalidate(ctx->proc);
-}
-
-static void unsecuring(hwc_context_t *ctx, uint32_t startEnd) {
- ctx->mDrawLock.lock();
- ctx->mSecuring = startEnd;
- //We're done unsecuring
- if(startEnd == IQService::END)
- ctx->mSecureMode = false;
- ctx->mDrawLock.unlock();
-
- if(ctx->proc)
- ctx->proc->invalidate(ctx->proc);
-}
-
-void QClient::MPDeathNotifier::died() {
- mHwcContext->mDrawLock.lock();
- ALOGD_IF(QCLIENT_DEBUG, "Media Player died");
- mHwcContext->mSecuring = false;
- mHwcContext->mSecureMode = false;
- mHwcContext->mDrawLock.unlock();
- if(mHwcContext->proc)
- mHwcContext->proc->invalidate(mHwcContext->proc);
-}
-
-static android::status_t screenRefresh(hwc_context_t *ctx) {
- status_t result = NO_INIT;
- if(ctx->proc) {
- ctx->proc->invalidate(ctx->proc);
- result = NO_ERROR;
- }
- return result;
-}
-
-static void setExtOrientation(hwc_context_t *ctx, uint32_t orientation) {
- ctx->mExtOrientation = orientation;
-}
-
-static void isExternalConnected(hwc_context_t* ctx, Parcel* outParcel) {
- int connected;
- connected = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected ? 1 : 0;
- outParcel->writeInt32(connected);
-}
-
-static void getDisplayAttributes(hwc_context_t* ctx, const Parcel* inParcel,
- Parcel* outParcel) {
- int dpy = inParcel->readInt32();
- outParcel->writeInt32(ctx->dpyAttr[dpy].vsync_period);
- if (ctx->dpyAttr[dpy].customFBSize) {
- outParcel->writeInt32(ctx->dpyAttr[dpy].xres_new);
- outParcel->writeInt32(ctx->dpyAttr[dpy].yres_new);
- } else {
- outParcel->writeInt32(ctx->dpyAttr[dpy].xres);
- outParcel->writeInt32(ctx->dpyAttr[dpy].yres);
- }
- outParcel->writeFloat(ctx->dpyAttr[dpy].xdpi);
- outParcel->writeFloat(ctx->dpyAttr[dpy].ydpi);
- //XXX: Need to check what to return for HDMI
- outParcel->writeInt32(ctx->mMDP.panel);
-}
-static void setHSIC(const Parcel* inParcel) {
- int dpy = inParcel->readInt32();
- ALOGD_IF(0, "In %s: dpy = %d", __FUNCTION__, dpy);
- HSICData_t hsic_data;
- hsic_data.hue = inParcel->readInt32();
- hsic_data.saturation = inParcel->readFloat();
- hsic_data.intensity = inParcel->readInt32();
- hsic_data.contrast = inParcel->readFloat();
- //XXX: Actually set the HSIC data through ABL lib
-}
-
-
-static void setBufferMirrorMode(hwc_context_t *ctx, uint32_t enable) {
- ctx->mBufferMirrorMode = enable;
-}
-
-static status_t getDisplayVisibleRegion(hwc_context_t* ctx, int dpy,
- Parcel* outParcel) {
- // Get the info only if the dpy is valid
- if(dpy >= HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
- Locker::Autolock _sl(ctx->mDrawLock);
- if(dpy && (ctx->mExtOrientation || ctx->mBufferMirrorMode)) {
- // Return the destRect on external, if external orienation
- // is enabled
- outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.left);
- outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.top);
- outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.right);
- outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.bottom);
- } else {
- outParcel->writeInt32(ctx->mViewFrame[dpy].left);
- outParcel->writeInt32(ctx->mViewFrame[dpy].top);
- outParcel->writeInt32(ctx->mViewFrame[dpy].right);
- outParcel->writeInt32(ctx->mViewFrame[dpy].bottom);
- }
- return NO_ERROR;
- } else {
- ALOGE("In %s: invalid dpy index %d", __FUNCTION__, dpy);
- return BAD_VALUE;
- }
-}
-
-// USed for setting the secondary(hdmi/wfd) status
-static void setSecondaryDisplayStatus(hwc_context_t *ctx,
- const Parcel* inParcel) {
- uint32_t dpy = inParcel->readInt32();
- uint32_t status = inParcel->readInt32();
- ALOGD_IF(QCLIENT_DEBUG, "%s: dpy = %d status = %s", __FUNCTION__,
- dpy, getExternalDisplayState(status));
-
- if(dpy > HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
- if(dpy == HWC_DISPLAY_VIRTUAL && status == qdutils::EXTERNAL_OFFLINE) {
- ctx->mWfdSyncLock.lock();
- ctx->mWfdSyncLock.signal();
- ctx->mWfdSyncLock.unlock();
- } else if(status == qdutils::EXTERNAL_PAUSE) {
- handle_pause(ctx, dpy);
- } else if(status == qdutils::EXTERNAL_RESUME) {
- handle_resume(ctx, dpy);
- }
- } else {
- ALOGE("%s: Invalid dpy %d", __FUNCTION__, dpy);
- return;
- }
-}
-
-
-static status_t setViewFrame(hwc_context_t* ctx, const Parcel* inParcel) {
- int dpy = inParcel->readInt32();
- if(dpy >= HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
- Locker::Autolock _sl(ctx->mDrawLock);
- ctx->mViewFrame[dpy].left = inParcel->readInt32();
- ctx->mViewFrame[dpy].top = inParcel->readInt32();
- ctx->mViewFrame[dpy].right = inParcel->readInt32();
- ctx->mViewFrame[dpy].bottom = inParcel->readInt32();
- ALOGD_IF(QCLIENT_DEBUG, "%s: mViewFrame[%d] = [%d %d %d %d]",
- __FUNCTION__, dpy,
- ctx->mViewFrame[dpy].left, ctx->mViewFrame[dpy].top,
- ctx->mViewFrame[dpy].right, ctx->mViewFrame[dpy].bottom);
- return NO_ERROR;
- } else {
- ALOGE("In %s: invalid dpy index %d", __FUNCTION__, dpy);
- return BAD_VALUE;
- }
-}
-
-static void toggleDynamicDebug(hwc_context_t* ctx, const Parcel* inParcel) {
- int debug_type = inParcel->readInt32();
- bool enable = !!inParcel->readInt32();
- ALOGD("%s: debug_type: %d enable:%d",
- __FUNCTION__, debug_type, enable);
- Locker::Autolock _sl(ctx->mDrawLock);
- switch (debug_type) {
- //break is ignored for DEBUG_ALL to toggle all of them at once
- case IQService::DEBUG_ALL:
- case IQService::DEBUG_MDPCOMP:
- qhwc::MDPComp::dynamicDebug(enable);
- if (debug_type != IQService::DEBUG_ALL)
- break;
- case IQService::DEBUG_VSYNC:
- ctx->vstate.debug = enable;
- if (debug_type != IQService::DEBUG_ALL)
- break;
- case IQService::DEBUG_VD:
- HWCVirtualVDS::dynamicDebug(enable);
- if (debug_type != IQService::DEBUG_ALL)
- break;
- case IQService::DEBUG_PIPE_LIFECYCLE:
- Overlay::debugPipeLifecycle(enable);
- if (debug_type != IQService::DEBUG_ALL)
- break;
- }
-}
-
-static void setIdleTimeout(hwc_context_t* ctx, const Parcel* inParcel) {
- uint32_t timeout = (uint32_t)inParcel->readInt32();
- ALOGD("%s :%u ms", __FUNCTION__, timeout);
- Locker::Autolock _sl(ctx->mDrawLock);
- MDPComp::setIdleTimeout(timeout);
-}
-
-static void configureDynRefreshRate(hwc_context_t* ctx,
- const Parcel* inParcel) {
- uint32_t op = (uint32_t)inParcel->readInt32();
- uint32_t refresh_rate = (uint32_t)inParcel->readInt32();
- MDPVersion& mdpHw = MDPVersion::getInstance();
- uint32_t dpy = HWC_DISPLAY_PRIMARY;
-
- if(mdpHw.isDynFpsSupported()) {
- Locker::Autolock _sl(ctx->mDrawLock);
-
- switch (op) {
- case DISABLE_METADATA_DYN_REFRESH_RATE:
- ctx->mUseMetaDataRefreshRate = false;
- setRefreshRate(ctx, dpy, ctx->dpyAttr[dpy].refreshRate);
- break;
- case ENABLE_METADATA_DYN_REFRESH_RATE:
- ctx->mUseMetaDataRefreshRate = true;
- setRefreshRate(ctx, dpy, ctx->dpyAttr[dpy].refreshRate);
- break;
- case SET_BINDER_DYN_REFRESH_RATE:
- if(ctx->mUseMetaDataRefreshRate)
- ALOGW("%s: Ignoring binder request to change refresh-rate",
- __FUNCTION__);
- else {
- uint32_t rate = roundOff(refresh_rate);
- if((rate >= mdpHw.getMinFpsSupported() &&
- rate <= mdpHw.getMaxFpsSupported())) {
- setRefreshRate(ctx, dpy, rate);
- } else {
- ALOGE("%s: Requested refresh-rate should be between \
- (%d) and (%d). Given (%d)", __FUNCTION__,
- mdpHw.getMinFpsSupported(),
- mdpHw.getMaxFpsSupported(), rate);
- }
- }
- break;
- default:
- ALOGE("%s: Invalid op %d",__FUNCTION__,op);
- }
- }
-}
-
-static status_t setPartialUpdateState(hwc_context_t *ctx, uint32_t state) {
- ALOGD("%s: state: %d", __FUNCTION__, state);
- switch(state) {
- case IQService::PREF_PARTIAL_UPDATE:
- if(qhwc::MDPComp::setPartialUpdatePref(ctx, true) < 0)
- return NO_INIT;
- return NO_ERROR;
- case IQService::PREF_POST_PROCESSING:
- if(qhwc::MDPComp::setPartialUpdatePref(ctx, false) < 0)
- return NO_INIT;
- qhwc::MDPComp::enablePartialUpdate(false);
- return NO_ERROR;
- case IQService::ENABLE_PARTIAL_UPDATE:
- qhwc::MDPComp::enablePartialUpdate(true);
- return NO_ERROR;
- default:
- ALOGE("%s: Invalid state", __FUNCTION__);
- return NO_ERROR;
- };
-}
-
-static void toggleScreenUpdate(hwc_context_t* ctx, uint32_t on) {
- ALOGD("%s: toggle update: %d", __FUNCTION__, on);
- if (on == 0) {
- ctx->mDrawLock.lock();
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isPause = true;
- ctx->mOverlay->configBegin();
- ctx->mOverlay->configDone();
- ctx->mRotMgr->clear();
- if(!Overlay::displayCommit(ctx->dpyAttr[0].fd)) {
- ALOGE("%s: Display commit failed", __FUNCTION__);
- }
- ctx->mDrawLock.unlock();
- } else {
- ctx->mDrawLock.lock();
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isPause = false;
- ctx->mDrawLock.unlock();
- ctx->proc->invalidate(ctx->proc);
- }
-}
-
-status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
- Parcel* outParcel) {
- status_t ret = NO_ERROR;
-
- switch(command) {
- case IQService::SECURING:
- securing(mHwcContext, inParcel->readInt32());
- break;
- case IQService::UNSECURING:
- unsecuring(mHwcContext, inParcel->readInt32());
- break;
- case IQService::SCREEN_REFRESH:
- return screenRefresh(mHwcContext);
- break;
- case IQService::EXTERNAL_ORIENTATION:
- setExtOrientation(mHwcContext, inParcel->readInt32());
- break;
- case IQService::BUFFER_MIRRORMODE:
- setBufferMirrorMode(mHwcContext, inParcel->readInt32());
- break;
- case IQService::GET_DISPLAY_VISIBLE_REGION:
- ret = getDisplayVisibleRegion(mHwcContext, inParcel->readInt32(),
- outParcel);
- break;
- case IQService::CHECK_EXTERNAL_STATUS:
- isExternalConnected(mHwcContext, outParcel);
- break;
- case IQService::GET_DISPLAY_ATTRIBUTES:
- getDisplayAttributes(mHwcContext, inParcel, outParcel);
- break;
- case IQService::SET_HSIC_DATA:
- setHSIC(inParcel);
- break;
- case IQService::SET_SECONDARY_DISPLAY_STATUS:
- setSecondaryDisplayStatus(mHwcContext, inParcel);
- break;
- case IQService::SET_VIEW_FRAME:
- setViewFrame(mHwcContext, inParcel);
- break;
- case IQService::DYNAMIC_DEBUG:
- toggleDynamicDebug(mHwcContext, inParcel);
- break;
- case IQService::SET_IDLE_TIMEOUT:
- setIdleTimeout(mHwcContext, inParcel);
- break;
- case IQService::SET_PARTIAL_UPDATE:
- ret = setPartialUpdateState(mHwcContext, inParcel->readInt32());
- break;
- case IQService::CONFIGURE_DYN_REFRESH_RATE:
- configureDynRefreshRate(mHwcContext, inParcel);
- case IQService::QDCM_SVC_CMDS:
- qdcmCmdsHandler(mHwcContext, inParcel, outParcel);
- break;
- case IQService::TOGGLE_SCREEN_UPDATE:
- toggleScreenUpdate(mHwcContext, inParcel->readInt32());
- break;
- default:
- ret = NO_ERROR;
- }
- return ret;
-}
-
-}
diff --git a/msm8909/libhwcomposer/hwc_qclient.h b/msm8909/libhwcomposer/hwc_qclient.h
deleted file mode 100644
index d955377..0000000
--- a/msm8909/libhwcomposer/hwc_qclient.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR CLIENTS; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ANDROID_QCLIENT_H
-#define ANDROID_QCLIENT_H
-
-#include <utils/Errors.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-#include <binder/IServiceManager.h>
-#include <media/IMediaDeathNotifier.h>
-#include <IQClient.h>
-
-struct hwc_context_t;
-
-class Params;
-namespace qClient {
-// ----------------------------------------------------------------------------
-
-class QClient : public BnQClient {
-public:
- QClient(hwc_context_t *ctx);
- virtual ~QClient();
- virtual android::status_t notifyCallback(uint32_t command,
- const android::Parcel* inParcel,
- android::Parcel* outParcel);
-
-private:
- //Notifies of Media Player death
- class MPDeathNotifier : public android::IMediaDeathNotifier {
- public:
- MPDeathNotifier(hwc_context_t* ctx) : mHwcContext(ctx){}
- virtual void died();
- hwc_context_t *mHwcContext;
- };
-
- hwc_context_t *mHwcContext;
- const android::sp<android::IMediaDeathNotifier> mMPDeathNotifier;
-};
-}; // namespace qClient
-#endif // ANDROID_QCLIENT_H
diff --git a/msm8909/libhwcomposer/hwc_qdcm.cpp b/msm8909/libhwcomposer/hwc_qdcm.cpp
deleted file mode 100644
index 9821e4e..0000000
--- a/msm8909/libhwcomposer/hwc_qdcm.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <hwc_qdcm.h>
-#include <hwc_utils.h>
-#include <utils/String16.h>
-#include <mdp_version.h>
-#include "mode_manager.h"
-#include "libmm-disp-apis.h"
-#include "IQService.h"
-
-using namespace android;
-using namespace qService;
-using namespace qhwc;
-using namespace qmode;
-
-namespace qQdcm {
-//----------------------------------------------------------------------------
-void qdcmInitContext(hwc_context_t *ctx)
-{
- loadQdcmLibrary(ctx);
-}
-
-void qdcmCloseContext(hwc_context_t *ctx)
-{
- if (ctx->mQdcmInfo.mQdcmMode) {
- unloadQdcmLibrary(ctx);
- }
-}
-
-void qdcmApplyDefaultAfterBootAnimationDone(hwc_context_t *ctx)
-{
- if (ctx->mQdcmInfo.mQdcmMode)
- ctx->mQdcmInfo.mQdcmMode->applyDefaultMode(0);
-}
-
-static void qdcmSetActiveMode(hwc_context_t *ctx, const Parcel *in, Parcel *out)
-{
- int ret = 0;
-
- if (ctx->mQdcmInfo.mQdcmMode && in && out) {
-
- struct SET_MODE_PROP_IN params =
- { (disp_id_type)in->readInt32(), in->readInt32()};
-
- ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SET_ACTIVE_MODE,
- (void *)¶ms, (void *)NULL);
-
- out->writeInt32(ret); //return operation status via binder.
- }
-}
-
-static void qdcmSetDefaultMode(hwc_context_t *ctx, const Parcel *in, Parcel *out)
-{
- int ret = 0;
-
- if (ctx->mQdcmInfo.mQdcmMode && in && out) {
-
- struct SET_MODE_PROP_IN params =
- { (disp_id_type)in->readInt32(), in->readInt32()};
-
- ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SET_DEFAULT_MODE,
- (void *)¶ms, (void *)NULL);
-
- out->writeInt32(ret); //return operation status via binder.
- }
-}
-
-static void qdcmGetDefaultMode(hwc_context_t *ctx,
- const Parcel *in, Parcel *out)
-{
- int ret = 0;
-
- if (ctx->mQdcmInfo.mQdcmMode && in && out) {
-
- int params = in->readInt32();
- int modeid = 0;
-
- ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_GET_DEFAULT_MODE,
- (const void *)¶ms, (void *)&modeid);
-
- out->writeInt32(modeid);
- out->writeInt32(ret); //return operation status via binder.
- }
-}
-
-static void qdcmGetColorBalanceRange(hwc_context_t *ctx __unused,
- const Parcel *in __unused, Parcel *out __unused)
-{
-}
-
-static void qdcmGetColorBalance(hwc_context_t *ctx,
- const Parcel *in, Parcel *out)
-{
- int ret = 0;
-
- if (ctx->mQdcmInfo.mQdcmMode && in && out) {
-
- int params = in->readInt32();
- int warmness = 0;
-
- ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_GET_CB,
- (const void *)¶ms, (void *)&warmness);
-
- out->writeInt32(warmness);
- out->writeInt32(ret); //return operation status via binder.
- }
-}
-
-static void qdcmSetColorBalance(hwc_context_t *ctx,
- const Parcel *in, Parcel *out)
-{
- int ret = 0;
-
- if (ctx->mQdcmInfo.mQdcmMode && in && out) {
-
- struct SET_CB_IN params =
- { (disp_id_type)in->readInt32(), in->readInt32() };
-
- ALOGD_IF(QDCM_DEBUG, "%s dispID = %d, warmness = %d\n",
- __FUNCTION__, params.id, params.warmness);
-
- ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SET_CB,
- (const void *)¶ms, NULL);
-
- out->writeInt32(ret); //return operation status via binder.
- }
-}
-
-static void qdcmSaveModeV2(hwc_context_t *ctx, const Parcel *in, Parcel *out)
-{
- int ret = 0;
-
- if (ctx->mQdcmInfo.mQdcmMode && in && out) {
-
- struct SAVE_DISPLAY_MODE_V2_IN params =
- { (disp_id_type)in->readInt32(),
- in->readCString(),
- (uint32_t)in->readInt32(),
- in->readInt32()
- };
- int value = 0;
-
- ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SAVE_MODE_V2,
- (const void *)¶ms, (void *)&value);
-
- out->writeInt32(value);
- out->writeInt32(ret); //return operation status via binder.
- }
-}
-
-static void qdcmSetPaConfig(hwc_context_t *ctx, const Parcel *in, Parcel *out)
-{
- int ret = 0;
-
- if (ctx->mQdcmInfo.mQdcmMode && in && out) {
-
- struct SET_PA_CONFIG_IN params;
-
- params.id = (disp_id_type)in->readInt32();
- params.pa.ops = in->readInt32();
- params.pa.data.hue = in->readInt32();
- params.pa.data.saturation = in->readInt32();
- params.pa.data.value = in->readInt32();
- params.pa.data.contrast = in->readInt32();
- params.pa.data.sat_thresh = in->readInt32();
-
- ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SET_PA_CONFIG,
- (const void *)¶ms, NULL);
-
- out->writeInt32(ret); //return operation status via binder.
- }
-}
-
-static void qdcmGetPaConfig(hwc_context_t *ctx, const Parcel *in, Parcel *out)
-{
- int ret = 0;
-
- if (ctx->mQdcmInfo.mQdcmMode && in && out) {
-
- int params = in->readInt32();
- struct disp_pa_config value;
-
- ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_GET_PA_CONFIG,
- (const void *)¶ms, (void *)&value);
-
- out->writeInt32(value.ops);
- out->writeInt32(value.data.hue);
- out->writeInt32(value.data.saturation);
- out->writeInt32(value.data.value);
- out->writeInt32(value.data.contrast);
- out->writeInt32(value.data.sat_thresh);
-
- out->writeInt32(ret); //return operation status via binder.
- }
-}
-
-static void qdcmGetPaRange(hwc_context_t *ctx, const Parcel *in, Parcel *out)
-{
- int ret = 0;
-
- if (ctx->mQdcmInfo.mQdcmMode && in && out) {
-
- int params = in->readInt32();
- struct disp_pa_range value;
-
- ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_GET_PA_RANGE,
- (const void *)¶ms, (void *)&value);
-
- out->writeInt32(value.max.hue);
- out->writeInt32(value.max.saturation);
- out->writeInt32(value.max.value);
- out->writeInt32(value.max.contrast);
- out->writeInt32(value.max.sat_thresh);
- out->writeInt32(value.min.hue);
- out->writeInt32(value.min.saturation);
- out->writeInt32(value.min.value);
- out->writeInt32(value.min.contrast);
- out->writeInt32(value.min.sat_thresh);
-
- out->writeInt32(ret); //return operation status via binder.
- }
-}
-
-void qdcmCmdsHandler(hwc_context_t *ctx, const Parcel *in, Parcel *out)
-{
- int subcmd = in->readInt32();
-
- ALOGD_IF(QDCM_DEBUG, "%s enter subcmd = %d\n", __FUNCTION__, subcmd);
- switch (subcmd) {
- case CMD_SET_ACTIVE_MODE:
- qdcmSetActiveMode(ctx, in, out);
- break;
- case CMD_SET_DEFAULT_MODE:
- qdcmSetDefaultMode(ctx, in, out);
- break;
- case CMD_GET_DEFAULT_MODE:
- qdcmGetDefaultMode(ctx, in, out);
- break;
- case CMD_GET_CB_RANGE:
- qdcmGetColorBalanceRange(ctx, in, out);
- break;
- case CMD_GET_CB:
- qdcmGetColorBalance(ctx, in, out);
- break;
- case CMD_SET_CB:
- qdcmSetColorBalance(ctx, in, out);
- break;
- case CMD_SAVE_MODE_V2:
- qdcmSaveModeV2(ctx, in, out);
- break;
- case CMD_SET_PA_CONFIG:
- qdcmSetPaConfig(ctx, in, out);
- break;
- case CMD_GET_PA_CONFIG:
- qdcmGetPaConfig(ctx, in, out);
- break;
- case CMD_GET_PA_RANGE:
- qdcmGetPaRange(ctx, in, out);
- break;
- }
-}
-
-
-} //namespace qQdcm
-
diff --git a/msm8909/libhwcomposer/hwc_qdcm.h b/msm8909/libhwcomposer/hwc_qdcm.h
deleted file mode 100644
index 6453159..0000000
--- a/msm8909/libhwcomposer/hwc_qdcm.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ANDROID_QDCM_H
-#define ANDROID_QDCM_H
-
-#include <utils/Errors.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-#include <hwc_utils.h>
-#include <dlfcn.h>
-#include <binder/Parcel.h>
-#include <cutils/properties.h>
-
-#define QDCM_DEBUG 0
-
-namespace qmode {
-class ModeManager;
-}
-
-using namespace android;
-
-namespace qQdcm {
-// ----------------------------------------------------------------------------
-
-//function prototypes used for QDCM library and service
-static inline void loadQdcmLibrary(hwc_context_t *ctx)
-{
- ctx->mQdcmInfo.mQdcmLib = dlopen("libmm-qdcm.so", RTLD_NOW);
- qmode::ModeManager* (*factory)() = NULL;
-
- if (ctx->mQdcmInfo.mQdcmLib)
- *(void **)&factory = dlsym(ctx->mQdcmInfo.mQdcmLib, "getObject");
-
- if (factory) {
- ctx->mQdcmInfo.mQdcmMode = factory();
- } else {
- ctx->mQdcmInfo.mQdcmMode = NULL;
- ALOGE("QDCM LIbrary load failing!");
- }
-
- ALOGD_IF(QDCM_DEBUG, "QDCM LIbrary loaded successfully!");
-}
-
-static inline void unloadQdcmLibrary(hwc_context_t *ctx)
-{
- void (*destroy)(qmode::ModeManager*) = NULL;
-
- if (ctx->mQdcmInfo.mQdcmLib) {
- *(void **)&destroy = dlsym(ctx->mQdcmInfo.mQdcmLib, "deleteObject");
-
- if (destroy) {
- destroy(ctx->mQdcmInfo.mQdcmMode);
- ctx->mQdcmInfo.mQdcmMode = NULL;
- }
-
- dlclose(ctx->mQdcmInfo.mQdcmLib);
- ctx->mQdcmInfo.mQdcmLib = NULL;
- }
-}
-
-void qdcmInitContext(hwc_context_t *);
-void qdcmCloseContext(hwc_context_t *);
-void qdcmApplyDefaultAfterBootAnimationDone(hwc_context_t *);
-void qdcmCmdsHandler(hwc_context_t*, const Parcel*, Parcel*);
-
-}; // namespace qQdcm
-#endif // ANDROID_QDCM_H
diff --git a/msm8909/libhwcomposer/hwc_qdcm_legacy.cpp b/msm8909/libhwcomposer/hwc_qdcm_legacy.cpp
deleted file mode 100644
index f9ce09f..0000000
--- a/msm8909/libhwcomposer/hwc_qdcm_legacy.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2014,2016, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <hwc_qdcm.h>
-#include <hwc_utils.h>
-#include <IQService.h>
-#include <mdp_version.h>
-#include <dlfcn.h>
-
-using namespace android;
-using namespace qService;
-using namespace qhwc;
-
-namespace qQdcm {
-//----------------------------------------------------------------------------
-void qdcmInitContext(hwc_context_t* /*ctx*/)
-{
-}
-
-void qdcmCloseContext(hwc_context_t* /*ctx*/)
-{
-}
-
-void qdcmApplyDefaultAfterBootAnimationDone(hwc_context_t* /*ctx*/)
-{
- int ret = 0;
- int (*applyMode)(int) = NULL;
- void *modeHandle = NULL;
-
- modeHandle = dlopen("libmm-qdcm.so", RTLD_NOW);
- if (modeHandle) {
- *(void **)&applyMode = dlsym(modeHandle, "applyDefaults");
- if (applyMode) {
- ret = applyMode(HWC_DISPLAY_PRIMARY);
- if (ret)
- ALOGE("%s: Not able to apply default mode", __FUNCTION__);
- } else {
- ALOGE("%s: No symbol applyDefaults found", __FUNCTION__);
- }
- dlclose(modeHandle);
- } else {
- ALOGE("%s: Not able to load libmm-qdcm.so", __FUNCTION__);
- }
-}
-
-//do nothing in case qdcm legacy implementation.
-void qdcmCmdsHandler(hwc_context_t* /*ctx*/, const Parcel* /*in*/, Parcel* /*out*/)
-{
-}
-
-
-} //namespace qQdcm
-
diff --git a/msm8909/libhwcomposer/hwc_uevents.cpp b/msm8909/libhwcomposer/hwc_uevents.cpp
deleted file mode 100644
index 0c85a8d..0000000
--- a/msm8909/libhwcomposer/hwc_uevents.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-14, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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.
- */
-#define UEVENT_DEBUG 0
-#include <hardware_legacy/uevent.h>
-#include <utils/Log.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-#include <string.h>
-#include <stdlib.h>
-#include "hwc_utils.h"
-#include "hwc_fbupdate.h"
-#include "hwc_mdpcomp.h"
-#include "hwc_copybit.h"
-#include "comptype.h"
-#include "hdmi.h"
-#include "hwc_virtual.h"
-#include "mdp_version.h"
-using namespace overlay;
-namespace qhwc {
-#define HWC_UEVENT_SWITCH_STR "change@/devices/virtual/switch/"
-#define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
-
-/* Parse uevent data for devices which we are interested */
-static int getConnectedDisplay(hwc_context_t* ctx, const char* strUdata)
-{
- int ret = -1;
- // Switch node for HDMI as PRIMARY/EXTERNAL
- if(strcasestr("change@/devices/virtual/switch/hdmi", strUdata)) {
- if (ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
- ret = HWC_DISPLAY_PRIMARY;
- } else {
- ret = HWC_DISPLAY_EXTERNAL;
- }
- }
- return ret;
-}
-
-static bool getPanelResetStatus(hwc_context_t* ctx, const char* strUdata, int len)
-{
- const char* iter_str = strUdata;
- if (strcasestr("change@/devices/virtual/graphics/fb0", strUdata)) {
- while(((iter_str - strUdata) <= len) && (*iter_str)) {
- const char* pstr = strstr(iter_str, "PANEL_ALIVE=0");
- if (pstr != NULL) {
- ALOGI("%s: got change event in fb0 with PANEL_ALIVE=0",
- __FUNCTION__);
- ctx->mPanelResetStatus = true;
- return true;
- }
- iter_str += strlen(iter_str)+1;
- }
- }
- return false;
-}
-
-/* Parse uevent data for action requested for the display */
-static int getConnectedState(const char* strUdata, int len)
-{
- const char* iter_str = strUdata;
- while(((iter_str - strUdata) <= len) && (*iter_str)) {
- const char* pstr = strstr(iter_str, "SWITCH_STATE=");
- if (pstr != NULL) {
- return (atoi(pstr + strlen("SWITCH_STATE=")));
- }
- iter_str += strlen(iter_str)+1;
- }
- return -1;
-}
-
-static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
-{
- bool bpanelReset = getPanelResetStatus(ctx, udata, len);
- if (bpanelReset) {
- ctx->proc->invalidate(ctx->proc);
- return;
- }
-
- int dpy = getConnectedDisplay(ctx, udata);
- if(dpy < 0) {
- ALOGD_IF(UEVENT_DEBUG, "%s: Not disp Event ", __FUNCTION__);
- return;
- }
-
- int switch_state = getConnectedState(udata, len);
-
- ALOGE_IF(UEVENT_DEBUG,"%s: uevent received: %s switch state: %d",
- __FUNCTION__,udata, switch_state);
-
- switch(switch_state) {
- case EXTERNAL_OFFLINE:
- {
- /* Display not connected */
- if(!ctx->dpyAttr[dpy].connected){
- ALOGE_IF(UEVENT_DEBUG,"%s: Ignoring EXTERNAL_OFFLINE event"
- "for display: %d", __FUNCTION__, dpy);
- break;
- }
-
- ctx->mDrawLock.lock();
- handle_offline(ctx, dpy);
- ctx->mDrawLock.unlock();
-
- /* We need to send hotplug to SF only when we are disconnecting
- * HDMI as an external display. */
- if(dpy == HWC_DISPLAY_EXTERNAL) {
- ALOGE_IF(UEVENT_DEBUG,"%s:Sending EXTERNAL OFFLINE hotplug"
- "event", __FUNCTION__);
- ctx->proc->hotplug(ctx->proc, dpy, EXTERNAL_OFFLINE);
- }
- break;
- }
- case EXTERNAL_ONLINE:
- {
- /* Display already connected */
- if(ctx->dpyAttr[dpy].connected) {
- ALOGE_IF(UEVENT_DEBUG,"%s: Ignoring EXTERNAL_ONLINE event"
- "for display: %d", __FUNCTION__, dpy);
- break;
- }
-
- if (ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
- ctx->mDrawLock.lock();
- handle_online(ctx, dpy);
- ctx->mDrawLock.unlock();
-
- ctx->proc->invalidate(ctx->proc);
- break;
- } else {
- ctx->mDrawLock.lock();
- //Force composition to give up resources like pipes and
- //close fb. For example if assertive display is going on,
- //fb2 could be open, thus connecting Layer Mixer#0 to
- //WriteBack module. If HDMI attempts to open fb1, the driver
- //will try to attach Layer Mixer#0 to HDMI INT, which will
- //fail, since Layer Mixer#0 is still connected to WriteBack.
- //This block will force composition to close fb2 in above
- //example.
- ctx->dpyAttr[dpy].isConfiguring = true;
- ctx->mDrawLock.unlock();
-
- ctx->proc->invalidate(ctx->proc);
- }
- //2 cycles for slower content
- usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
- * 2 / 1000);
-
- if(isVDConnected(ctx)) {
- // Do not initiate WFD teardown if WFD architecture is based
- // on VDS mechanism.
- // WFD Stack listens to HDMI intent and initiates virtual
- // display teardown.
- // ToDo: Currently non-WFD Virtual display clients do not
- // involve HWC. If there is a change, we need to come up
- // with mechanism of how to address non-WFD Virtual display
- // clients + HDMI
- ctx->mWfdSyncLock.lock();
- ALOGD_IF(HWC_WFDDISPSYNC_LOG,
- "%s: Waiting for wfd-teardown to be signalled",
- __FUNCTION__);
- ctx->mWfdSyncLock.wait();
- ALOGD_IF(HWC_WFDDISPSYNC_LOG,
- "%s: Teardown signalled. Completed waiting in"
- "uevent thread", __FUNCTION__);
- ctx->mWfdSyncLock.unlock();
- }
- ctx->mHDMIDisplay->configure();
- ctx->mHDMIDisplay->activateDisplay();
-
- ctx->mDrawLock.lock();
- updateDisplayInfo(ctx, dpy);
- initCompositionResources(ctx, dpy);
- ctx->dpyAttr[dpy].isPause = false;
- ctx->dpyAttr[dpy].connected = true;
- ctx->dpyAttr[dpy].isConfiguring = true;
- ctx->mDrawLock.unlock();
-
- /* External display is HDMI */
- ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL ONLINE"
- "hotplug event", __FUNCTION__);
- ctx->proc->hotplug(ctx->proc, dpy, EXTERNAL_ONLINE);
- break;
- }
- default:
- {
- ALOGE("%s: Invalid state to swtich:%d", __FUNCTION__, switch_state);
- break;
- }
- }
-}
-
-static void *uevent_loop(void *param)
-{
- int len = 0;
- static char udata[PAGE_SIZE];
- hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);
- char thread_name[64] = HWC_UEVENT_THREAD_NAME;
- prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
- setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
- if(!uevent_init()) {
- ALOGE("%s: failed to init uevent ",__FUNCTION__);
- return NULL;
- }
-
- while(1) {
- len = uevent_next_event(udata, (int)sizeof(udata) - 2);
- handle_uevent(ctx, udata, len);
- }
-
- return NULL;
-}
-
-void init_uevent_thread(hwc_context_t* ctx)
-{
- pthread_t uevent_thread;
- int ret;
-
- ALOGI("Initializing UEVENT Thread");
- ret = pthread_create(&uevent_thread, NULL, uevent_loop, (void*) ctx);
- if (ret) {
- ALOGE("%s: failed to create %s: %s", __FUNCTION__,
- HWC_UEVENT_THREAD_NAME, strerror(ret));
- }
-}
-
-}; //namespace
diff --git a/msm8909/libhwcomposer/hwc_utils.cpp b/msm8909/libhwcomposer/hwc_utils.cpp
deleted file mode 100644
index 3b32072..0000000
--- a/msm8909/libhwcomposer/hwc_utils.cpp
+++ /dev/null
@@ -1,2907 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014,2016, The Linux Foundation All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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.
- */
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-#define HWC_UTILS_DEBUG 0
-#include <math.h>
-#include <sys/ioctl.h>
-#include <linux/fb.h>
-#include <binder/IServiceManager.h>
-#include <EGL/egl.h>
-#include <cutils/properties.h>
-#include <utils/Trace.h>
-#include <gralloc_priv.h>
-#include <overlay.h>
-#include <overlayRotator.h>
-#include <overlayWriteback.h>
-#include "hwc_utils.h"
-#include "hwc_mdpcomp.h"
-#include "hwc_fbupdate.h"
-#include "hwc_ad.h"
-#include "mdp_version.h"
-#include "hwc_copybit.h"
-#include "hwc_dump_layers.h"
-#include "hdmi.h"
-#include "hwc_qclient.h"
-#include "QService.h"
-#include "comptype.h"
-#include "hwc_virtual.h"
-#include "qd_utils.h"
-#include "hwc_qdcm.h"
-#include <sys/sysinfo.h>
-#include <dlfcn.h>
-
-using namespace qClient;
-using namespace qService;
-using namespace android;
-using namespace overlay;
-using namespace overlay::utils;
-using namespace qQdcm;
-namespace ovutils = overlay::utils;
-
-#ifdef QTI_BSP
-
-#define EGL_GPU_HINT_1 0x32D0
-#define EGL_GPU_HINT_2 0x32D1
-
-#define EGL_GPU_LEVEL_0 0x0
-#define EGL_GPU_LEVEL_1 0x1
-#define EGL_GPU_LEVEL_2 0x2
-#define EGL_GPU_LEVEL_3 0x3
-#define EGL_GPU_LEVEL_4 0x4
-#define EGL_GPU_LEVEL_5 0x5
-
-#endif
-
-#define PROP_DEFAULT_APPBUFFER "hw.sf.app_buff_count"
-#define MAX_RAM_SIZE 512*1024*1024
-#define qHD_WIDTH 540
-
-
-namespace qhwc {
-
-// Std refresh rates for digital videos- 24p, 30p, 48p and 60p
-uint32_t stdRefreshRates[] = { 30, 24, 48, 60 };
-
-static uint32_t getFBformat(fb_var_screeninfo /*vinfo*/) {
- uint32_t fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
-
-#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
- // Here, we are adding the formats that are supported by both GPU and MDP.
- // The formats that fall in this category are RGBA_8888, RGB_565, RGB_888
- switch(vinfo.bits_per_pixel) {
- case 16:
- fbformat = HAL_PIXEL_FORMAT_RGB_565;
- break;
- case 24:
- if ((vinfo.transp.offset == 0) && (vinfo.transp.length == 0))
- fbformat = HAL_PIXEL_FORMAT_RGB_888;
- break;
- case 32:
- if ((vinfo.red.offset == 0) && (vinfo.green.offset == 8) &&
- (vinfo.blue.offset == 16) && (vinfo.transp.offset == 24))
- fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
- break;
- default:
- fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
- }
-#endif
- return fbformat;
-}
-
-bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
-{
- return !((xres > qdutils::MDPVersion::getInstance().getMaxMixerWidth() &&
- !isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY)) ||
- (xres < MIN_DISPLAY_XRES || yres < MIN_DISPLAY_YRES));
-}
-
-void changeResolution(hwc_context_t *ctx, int xres_orig, int yres_orig,
- int width, int height) {
- //Store original display resolution.
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_orig;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_orig;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = false;
- char property[PROPERTY_VALUE_MAX] = {'\0'};
- char *yptr = NULL;
- if (property_get("debug.hwc.fbsize", property, NULL) > 0) {
- yptr = strcasestr(property,"x");
- if(yptr) {
- int xres_new = atoi(property);
- int yres_new = atoi(yptr + 1);
- if (isValidResolution(ctx,xres_new,yres_new) &&
- xres_new != xres_orig && yres_new != yres_orig) {
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_new;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_new;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
-
- //Caluculate DPI according to changed resolution.
- float xdpi = ((float)xres_new * 25.4f) / (float)width;
- float ydpi = ((float)yres_new * 25.4f) / (float)height;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
- }
- }
- }
-}
-
-// Initialize hdmi display attributes based on
-// hdmi display class state
-void updateDisplayInfo(hwc_context_t* ctx, int dpy) {
- struct fb_var_screeninfo info;
-
- if (ioctl(ctx->mHDMIDisplay->getFd(), FBIOGET_VSCREENINFO, &info) == -1) {
- ALOGE("%s:Error in ioctl FBIOGET_VSCREENINFO: %s",
- __FUNCTION__, strerror(errno));
- }
-
- ctx->dpyAttr[dpy].fbformat = getFBformat(info);
- ctx->dpyAttr[dpy].fd = ctx->mHDMIDisplay->getFd();
- ctx->dpyAttr[dpy].xres = ctx->mHDMIDisplay->getWidth();
- ctx->dpyAttr[dpy].yres = ctx->mHDMIDisplay->getHeight();
- ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mHDMIDisplay->getMDPScalingMode();
- ctx->dpyAttr[dpy].vsync_period = ctx->mHDMIDisplay->getVsyncPeriod();
- ctx->mViewFrame[dpy].left = 0;
- ctx->mViewFrame[dpy].top = 0;
- ctx->mViewFrame[dpy].right = ctx->dpyAttr[dpy].xres;
- ctx->mViewFrame[dpy].bottom = ctx->dpyAttr[dpy].yres;
-}
-
-// Reset hdmi display attributes and list stats structures
-void resetDisplayInfo(hwc_context_t* ctx, int dpy) {
- memset(&(ctx->dpyAttr[dpy]), 0, sizeof(ctx->dpyAttr[dpy]));
- memset(&(ctx->listStats[dpy]), 0, sizeof(ctx->listStats[dpy]));
- // We reset the fd to -1 here but External display class is responsible
- // for it when the display is disconnected. This is handled as part of
- // EXTERNAL_OFFLINE event.
- ctx->dpyAttr[dpy].fd = -1;
-}
-
-// Initialize composition resources
-void initCompositionResources(hwc_context_t* ctx, int dpy) {
- ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx, dpy);
- ctx->mMDPComp[dpy] = MDPComp::getObject(ctx, dpy);
-}
-
-void destroyCompositionResources(hwc_context_t* ctx, int dpy) {
- if(ctx->mFBUpdate[dpy]) {
- delete ctx->mFBUpdate[dpy];
- ctx->mFBUpdate[dpy] = NULL;
- }
- if(ctx->mMDPComp[dpy]) {
- delete ctx->mMDPComp[dpy];
- ctx->mMDPComp[dpy] = NULL;
- }
-}
-
-static int openFramebufferDevice(hwc_context_t *ctx)
-{
- struct fb_fix_screeninfo finfo;
- struct fb_var_screeninfo info;
-
- int fb_fd = openFb(HWC_DISPLAY_PRIMARY);
- if(fb_fd < 0) {
- ALOGE("%s: Error Opening FB : %s", __FUNCTION__, strerror(errno));
- return -errno;
- }
-
- if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &info) == -1) {
- ALOGE("%s:Error in ioctl FBIOGET_VSCREENINFO: %s", __FUNCTION__,
- strerror(errno));
- close(fb_fd);
- return -errno;
- }
-
- if (int(info.width) <= 0 || int(info.height) <= 0) {
- // the driver doesn't return that information
- // default to 160 dpi
- info.width = (int)(((float)info.xres * 25.4f)/160.0f + 0.5f);
- info.height = (int)(((float)info.yres * 25.4f)/160.0f + 0.5f);
- }
-
- float xdpi = ((float)info.xres * 25.4f) / (float)info.width;
- float ydpi = ((float)info.yres * 25.4f) / (float)info.height;
-
-#ifdef MSMFB_METADATA_GET
- struct msmfb_metadata metadata;
- memset(&metadata, 0 , sizeof(metadata));
- metadata.op = metadata_op_frame_rate;
-
- if (ioctl(fb_fd, MSMFB_METADATA_GET, &metadata) == -1) {
- ALOGE("%s:Error retrieving panel frame rate: %s", __FUNCTION__,
- strerror(errno));
- close(fb_fd);
- return -errno;
- }
-
- float fps = (float)metadata.data.panel_frame_rate;
-#else
- //XXX: Remove reserved field usage on all baselines
- //The reserved[3] field is used to store FPS by the driver.
- float fps = info.reserved[3] & 0xFF;
-#endif
-
- if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
- ALOGE("%s:Error in ioctl FBIOGET_FSCREENINFO: %s", __FUNCTION__,
- strerror(errno));
- close(fb_fd);
- return -errno;
- }
-
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = fb_fd;
- //xres, yres may not be 32 aligned
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride = finfo.line_length /(info.xres/8);
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = info.xres;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = info.yres;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].refreshRate = (uint32_t)fps;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].dynRefreshRate = (uint32_t)fps;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period =
- (uint32_t)(1000000000l / fps);
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fbformat = getFBformat(info);
-
- //To change resolution of primary display
- changeResolution(ctx, info.xres, info.yres, info.width, info.height);
-
- //Unblank primary on first boot
- if(ioctl(fb_fd, FBIOBLANK,FB_BLANK_UNBLANK) < 0) {
- ALOGE("%s: Failed to unblank display", __FUNCTION__);
- return -errno;
- }
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive = true;
-
- return 0;
-}
-
-static void changeDefaultAppBufferCount() {
- struct sysinfo info;
- unsigned long int ramSize = 0;
- if (!sysinfo(&info)) {
- ramSize = info.totalram ;
- }
- int fb_fd = -1;
- struct fb_var_screeninfo sInfo ={0};
- fb_fd = open("/dev/graphics/fb0", O_RDONLY);
- if (fb_fd >=0) {
- ioctl(fb_fd, FBIOGET_VSCREENINFO, &sInfo);
- close(fb_fd);
- }
- if ((ramSize && ramSize < MAX_RAM_SIZE) &&
- (sInfo.xres && sInfo.xres <= qHD_WIDTH )) {
- property_set(PROP_DEFAULT_APPBUFFER, "3");
- }
-}
-
-void initContext(hwc_context_t *ctx)
-{
- overlay::Overlay::initOverlay();
- ctx->mHDMIDisplay = new HDMIDisplay();
- uint32_t priW = 0, priH = 0;
- // 1. HDMI as Primary
- // -If HDMI cable is connected, read display configs from edid data
- // -If HDMI cable is not connected then use default data in vscreeninfo
- // 2. HDMI as External
- // -Initialize HDMI class for use with external display
- // -Use vscreeninfo to populate display configs
- if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
- int connected = ctx->mHDMIDisplay->getConnectedState();
- if(connected == 1) {
- ctx->mHDMIDisplay->configure();
- updateDisplayInfo(ctx, HWC_DISPLAY_PRIMARY);
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
- } else {
- openFramebufferDevice(ctx);
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = false;
- }
- } else {
- openFramebufferDevice(ctx);
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
- // Send the primary resolution to the hdmi display class
- // to be used for MDP scaling functionality
- priW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
- priH = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
- ctx->mHDMIDisplay->setPrimaryAttributes(priW, priH);
- }
-
- char value[PROPERTY_VALUE_MAX];
- ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
- ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
- ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
- ctx->mOverlay = overlay::Overlay::getInstance();
- ctx->mRotMgr = RotMgr::getInstance();
-
- //default_app_buffer for ferrum
- if (ctx->mMDP.version == qdutils::MDP_V3_0_5) {
- changeDefaultAppBufferCount();
- }
- // Initialize composition objects for the primary display
- initCompositionResources(ctx, HWC_DISPLAY_PRIMARY);
-
- // Check if the target supports copybit compostion (dyn/mdp) to
- // decide if we need to open the copybit module.
- int compositionType =
- qdutils::QCCompositionType::getInstance().getCompositionType();
-
- // Only MDP copybit is used
- if ((compositionType & (qdutils::COMPOSITION_TYPE_DYN |
- qdutils::COMPOSITION_TYPE_MDP)) &&
- ((qdutils::MDPVersion::getInstance().getMDPVersion() ==
- qdutils::MDP_V3_0_4) ||
- (qdutils::MDPVersion::getInstance().getMDPVersion() ==
- qdutils::MDP_V3_0_5))) {
- ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
- HWC_DISPLAY_PRIMARY);
- }
-
- ctx->mHWCVirtual = new HWCVirtualVDS();
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
- ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = false;
- ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected = false;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].mMDPScalingMode= false;
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].mMDPScalingMode = false;
- ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].mMDPScalingMode = false;
-
- //Initialize the primary display viewFrame info
- ctx->mViewFrame[HWC_DISPLAY_PRIMARY].left = 0;
- ctx->mViewFrame[HWC_DISPLAY_PRIMARY].top = 0;
- ctx->mViewFrame[HWC_DISPLAY_PRIMARY].right =
- (int)ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
- ctx->mViewFrame[HWC_DISPLAY_PRIMARY].bottom =
- (int)ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
-
- for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
- ctx->mHwcDebug[i] = new HwcDebug(i);
- ctx->mLayerRotMap[i] = new LayerRotMap();
- ctx->mAnimationState[i] = ANIMATION_STOPPED;
- ctx->dpyAttr[i].mActionSafePresent = false;
- ctx->dpyAttr[i].mAsWidthRatio = 0;
- ctx->dpyAttr[i].mAsHeightRatio = 0;
- }
-
- for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
- ctx->mPrevHwLayerCount[i] = 0;
- }
-
- MDPComp::init(ctx);
- ctx->mAD = new AssertiveDisplay(ctx);
-
- ctx->vstate.enable = false;
- ctx->vstate.fakevsync = false;
- ctx->mExtOrientation = 0;
- ctx->numActiveDisplays = 1;
-
- //Right now hwc starts the service but anybody could do it, or it could be
- //independent process as well.
- QService::init();
- sp<IQClient> client = new QClient(ctx);
- android::sp<qService::IQService> qservice_sp = interface_cast<IQService>(
- defaultServiceManager()->getService(
- String16("display.qservice")));
- if (qservice_sp.get()) {
- qservice_sp->connect(client);
- } else {
- ALOGE("%s: Failed to acquire service pointer", __FUNCTION__);
- return ;
- }
-
- // Initialize device orientation to its default orientation
- ctx->deviceOrientation = 0;
- ctx->mBufferMirrorMode = false;
-
- property_get("sys.hwc.windowbox_aspect_ratio_tolerance", value, "0");
- ctx->mAspectRatioToleranceLevel = (((float)atoi(value)) / 100.0f);
-
- ctx->enableABC = false;
- property_get("debug.sf.hwc.canUseABC", value, "0");
- ctx->enableABC = atoi(value) ? true : false;
-
- // Initializing boot anim completed check to false
- ctx->mBootAnimCompleted = false;
-
- // Initialize gpu perfomance hint related parameters
-#ifdef QTI_BSP
- ctx->mEglLib = NULL;
- ctx->mpfn_eglGpuPerfHintQCOM = NULL;
- ctx->mpfn_eglGetCurrentDisplay = NULL;
- ctx->mpfn_eglGetCurrentContext = NULL;
- ctx->mGPUHintInfo.mGpuPerfModeEnable = false;
- ctx->mGPUHintInfo.mEGLDisplay = NULL;
- ctx->mGPUHintInfo.mEGLContext = NULL;
- ctx->mGPUHintInfo.mCompositionState = COMPOSITION_STATE_MDP;
- ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
- if(property_get("sys.hwc.gpu_perf_mode", value, "0") > 0) {
- int val = atoi(value);
- if(val > 0 && loadEglLib(ctx)) {
- ctx->mGPUHintInfo.mGpuPerfModeEnable = true;
- }
- }
-#endif
- // Read the system property to determine if windowboxing feature is enabled.
- ctx->mWindowboxFeature = false;
- if(property_get("sys.hwc.windowbox_feature", value, "false")
- && !strcmp(value, "true")) {
- ctx->mWindowboxFeature = true;
- }
-
- ctx->mUseMetaDataRefreshRate = true;
- if(property_get("persist.metadata_dynfps.disable", value, "false")
- && !strcmp(value, "true")) {
- ctx->mUseMetaDataRefreshRate = false;
- }
-
- memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
-
- //init qdcm service related context.
- qdcmInitContext(ctx);
-
- ALOGI("Initializing Qualcomm Hardware Composer");
- ALOGI("MDP version: %d", ctx->mMDP.version);
-}
-
-void closeContext(hwc_context_t *ctx)
-{
- //close qdcm service related context.
- qdcmCloseContext(ctx);
-
- if(ctx->mOverlay) {
- delete ctx->mOverlay;
- ctx->mOverlay = NULL;
- }
-
- if(ctx->mRotMgr) {
- delete ctx->mRotMgr;
- ctx->mRotMgr = NULL;
- }
-
- for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
- if(ctx->mCopyBit[i]) {
- delete ctx->mCopyBit[i];
- ctx->mCopyBit[i] = NULL;
- }
- }
-
- if(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd) {
- close(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd);
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1;
- }
-
- if(ctx->mHDMIDisplay) {
- delete ctx->mHDMIDisplay;
- ctx->mHDMIDisplay = NULL;
- }
-
- for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
- destroyCompositionResources(ctx, i);
-
- if(ctx->mHwcDebug[i]) {
- delete ctx->mHwcDebug[i];
- ctx->mHwcDebug[i] = NULL;
- }
- if(ctx->mLayerRotMap[i]) {
- delete ctx->mLayerRotMap[i];
- ctx->mLayerRotMap[i] = NULL;
- }
- }
- if(ctx->mHWCVirtual) {
- delete ctx->mHWCVirtual;
- ctx->mHWCVirtual = NULL;
- }
- if(ctx->mAD) {
- delete ctx->mAD;
- ctx->mAD = NULL;
- }
-
-#ifdef QTI_BSP
- ctx->mpfn_eglGpuPerfHintQCOM = NULL;
- ctx->mpfn_eglGetCurrentDisplay = NULL;
- ctx->mpfn_eglGetCurrentContext = NULL;
- if(ctx->mEglLib) {
- dlclose(ctx->mEglLib);
- ctx->mEglLib = NULL;
- }
-#endif
-}
-
-uint32_t getRefreshRate(hwc_context_t* ctx, uint32_t requestedRefreshRate) {
-
- qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
- int dpy = HWC_DISPLAY_PRIMARY;
- uint32_t defaultRefreshRate = ctx->dpyAttr[dpy].refreshRate;
- uint32_t rate = defaultRefreshRate;
-
- if(!requestedRefreshRate)
- return defaultRefreshRate;
-
- uint32_t maxNumIterations =
- (uint32_t)ceil(
- (float)mdpHw.getMaxFpsSupported()/
- (float)requestedRefreshRate);
-
- for(uint32_t i = 1; i <= maxNumIterations; i++) {
- rate = i * roundOff(requestedRefreshRate);
- if(rate < mdpHw.getMinFpsSupported()) {
- continue;
- } else if((rate >= mdpHw.getMinFpsSupported() &&
- rate <= mdpHw.getMaxFpsSupported())) {
- break;
- } else {
- rate = defaultRefreshRate;
- break;
- }
- }
- return rate;
-}
-
-//Helper to roundoff the refreshrates to the std refresh-rates
-uint32_t roundOff(uint32_t refreshRate) {
- int count = (int) (sizeof(stdRefreshRates)/sizeof(stdRefreshRates[0]));
- uint32_t rate = refreshRate;
- for(int i=0; i< count; i++) {
- if(abs((int)(stdRefreshRates[i] - refreshRate)) < 2) {
- // Most likely used for video, the fps can fluctuate
- // Ex: b/w 29 and 30 for 30 fps clip
- rate = stdRefreshRates[i];
- break;
- }
- }
- return rate;
-}
-
-//Helper func to set the dyn fps
-void setRefreshRate(hwc_context_t* ctx, int dpy, uint32_t refreshRate) {
- //Update only if different
- if(!ctx || refreshRate == ctx->dpyAttr[dpy].dynRefreshRate)
- return;
- const int fbNum = Overlay::getFbForDpy(dpy);
- char sysfsPath[qdutils::MAX_SYSFS_FILE_PATH];
- snprintf (sysfsPath, sizeof(sysfsPath),
- "/sys/class/graphics/fb%d/dynamic_fps", fbNum);
-
- int fd = open(sysfsPath, O_WRONLY);
- if(fd >= 0) {
- char str[64];
- snprintf(str, sizeof(str), "%d", refreshRate);
- ssize_t ret = write(fd, str, strlen(str));
- if(ret < 0) {
- ALOGE("%s: Failed to write %d with error %s",
- __FUNCTION__, refreshRate, strerror(errno));
- } else {
- ctx->dpyAttr[dpy].dynRefreshRate = refreshRate;
- ALOGD_IF(HWC_UTILS_DEBUG, "%s: Wrote %d to dynamic_fps",
- __FUNCTION__, refreshRate);
- }
- close(fd);
- } else {
- ALOGE("%s: Failed to open %s with error %s", __FUNCTION__, sysfsPath,
- strerror(errno));
- }
-}
-
-void dumpsys_log(android::String8& buf, const char* fmt, ...)
-{
- va_list varargs;
- va_start(varargs, fmt);
- buf.appendFormatV(fmt, varargs);
- va_end(varargs);
-}
-
-int getExtOrientation(hwc_context_t* ctx) {
- int extOrient = ctx->mExtOrientation;
- if(ctx->mBufferMirrorMode)
- extOrient = getMirrorModeOrientation(ctx);
- return extOrient;
-}
-
-/* Calculates the destination position based on the action safe rectangle */
-void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& rect) {
- // Position
- int x = rect.left, y = rect.top;
- int w = rect.right - rect.left;
- int h = rect.bottom - rect.top;
-
- if(!ctx->dpyAttr[dpy].mActionSafePresent)
- return;
- // Read action safe properties
- int asWidthRatio = ctx->dpyAttr[dpy].mAsWidthRatio;
- int asHeightRatio = ctx->dpyAttr[dpy].mAsHeightRatio;
-
- float wRatio = 1.0;
- float hRatio = 1.0;
- float xRatio = 1.0;
- float yRatio = 1.0;
-
- uint32_t fbWidth = ctx->dpyAttr[dpy].xres;
- uint32_t fbHeight = ctx->dpyAttr[dpy].yres;
- if(ctx->dpyAttr[dpy].mMDPScalingMode) {
- // if MDP scaling mode is enabled for external, need to query
- // the actual width and height, as that is the physical w & h
- ctx->mHDMIDisplay->getAttributes(fbWidth, fbHeight);
- }
-
-
- // Since external is rotated 90, need to swap width/height
- int extOrient = getExtOrientation(ctx);
-
- if(extOrient & HWC_TRANSFORM_ROT_90)
- swap(fbWidth, fbHeight);
-
- float asX = 0;
- float asY = 0;
- float asW = (float)fbWidth;
- float asH = (float)fbHeight;
-
- // based on the action safe ratio, get the Action safe rectangle
- asW = ((float)fbWidth * (1.0f - (float)asWidthRatio / 100.0f));
- asH = ((float)fbHeight * (1.0f - (float)asHeightRatio / 100.0f));
- asX = ((float)fbWidth - asW) / 2;
- asY = ((float)fbHeight - asH) / 2;
-
- // calculate the position ratio
- xRatio = (float)x/(float)fbWidth;
- yRatio = (float)y/(float)fbHeight;
- wRatio = (float)w/(float)fbWidth;
- hRatio = (float)h/(float)fbHeight;
-
- //Calculate the position...
- x = int((xRatio * asW) + asX);
- y = int((yRatio * asH) + asY);
- w = int(wRatio * asW);
- h = int(hRatio * asH);
-
- // Convert it back to hwc_rect_t
- rect.left = x;
- rect.top = y;
- rect.right = w + rect.left;
- rect.bottom = h + rect.top;
-
- return;
-}
-
-// This function gets the destination position for Seconday display
-// based on the position and aspect ratio with orientation
-void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
- hwc_rect_t& inRect, hwc_rect_t& outRect) {
- // Physical display resolution
- float fbWidth = (float)ctx->dpyAttr[dpy].xres;
- float fbHeight = (float)ctx->dpyAttr[dpy].yres;
- //display position(x,y,w,h) in correct aspectratio after rotation
- int xPos = 0;
- int yPos = 0;
- float width = fbWidth;
- float height = fbHeight;
- // Width/Height used for calculation, after rotation
- float actualWidth = fbWidth;
- float actualHeight = fbHeight;
-
- float wRatio = 1.0;
- float hRatio = 1.0;
- float xRatio = 1.0;
- float yRatio = 1.0;
- hwc_rect_t rect = {0, 0, (int)fbWidth, (int)fbHeight};
-
- Dim inPos(inRect.left, inRect.top, inRect.right - inRect.left,
- inRect.bottom - inRect.top);
- Dim outPos(outRect.left, outRect.top, outRect.right - outRect.left,
- outRect.bottom - outRect.top);
-
- Whf whf((uint32_t)fbWidth, (uint32_t)fbHeight, 0);
- eTransform extorient = static_cast<eTransform>(extOrientation);
- // To calculate the destination co-ordinates in the new orientation
- preRotateSource(extorient, whf, inPos);
-
- if(extOrientation & HAL_TRANSFORM_ROT_90) {
- // Swap width/height for input position
- swapWidthHeight(actualWidth, actualHeight);
- qdutils::getAspectRatioPosition((int)fbWidth, (int)fbHeight,
- (int)actualWidth, (int)actualHeight, rect);
- xPos = rect.left;
- yPos = rect.top;
- width = float(rect.right - rect.left);
- height = float(rect.bottom - rect.top);
- }
- xRatio = (float)((float)inPos.x/actualWidth);
- yRatio = (float)((float)inPos.y/actualHeight);
- wRatio = (float)((float)inPos.w/actualWidth);
- hRatio = (float)((float)inPos.h/actualHeight);
-
- //Calculate the pos9ition...
- outPos.x = uint32_t((xRatio * width) + (float)xPos);
- outPos.y = uint32_t((yRatio * height) + (float)yPos);
- outPos.w = uint32_t(wRatio * width);
- outPos.h = uint32_t(hRatio * height);
- ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio Position: x = %d,"
- "y = %d w = %d h = %d", __FUNCTION__, outPos.x, outPos.y,
- outPos.w, outPos.h);
-
- // For sidesync, the dest fb will be in portrait orientation, and the crop
- // will be updated to avoid the black side bands, and it will be upscaled
- // to fit the dest RB, so recalculate
- // the position based on the new width and height
- if ((extOrientation & HWC_TRANSFORM_ROT_90) &&
- isOrientationPortrait(ctx)) {
- hwc_rect_t r = {0, 0, 0, 0};
- //Calculate the position
- xRatio = (float)(outPos.x - xPos)/width;
- // GetaspectRatio -- tricky to get the correct aspect ratio
- // But we need to do this.
- qdutils::getAspectRatioPosition((int)width, (int)height,
- (int)width,(int)height, r);
- xPos = r.left;
- yPos = r.top;
- float tempHeight = float(r.bottom - r.top);
- yRatio = (float)yPos/height;
- wRatio = (float)outPos.w/width;
- hRatio = tempHeight/height;
-
- //Map the coordinates back to Framebuffer domain
- outPos.x = uint32_t(xRatio * fbWidth);
- outPos.y = uint32_t(yRatio * fbHeight);
- outPos.w = uint32_t(wRatio * fbWidth);
- outPos.h = uint32_t(hRatio * fbHeight);
-
- ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio for device in"
- "portrait: x = %d,y = %d w = %d h = %d", __FUNCTION__,
- outPos.x, outPos.y,
- outPos.w, outPos.h);
- }
- if(ctx->dpyAttr[dpy].mMDPScalingMode) {
- uint32_t extW = 0, extH = 0;
- if(dpy == HWC_DISPLAY_EXTERNAL) {
- ctx->mHDMIDisplay->getAttributes(extW, extH);
- } else if(dpy == HWC_DISPLAY_VIRTUAL) {
- extW = ctx->mHWCVirtual->getScalingWidth();
- extH = ctx->mHWCVirtual->getScalingHeight();
- }
- ALOGD_IF(HWC_UTILS_DEBUG, "%s: Scaling mode extW=%d extH=%d",
- __FUNCTION__, extW, extH);
-
- fbWidth = (float)ctx->dpyAttr[dpy].xres;
- fbHeight = (float)ctx->dpyAttr[dpy].yres;
- //Calculate the position...
- xRatio = (float)outPos.x/fbWidth;
- yRatio = (float)outPos.y/fbHeight;
- wRatio = (float)outPos.w/fbWidth;
- hRatio = (float)outPos.h/fbHeight;
-
- outPos.x = uint32_t(xRatio * (float)extW);
- outPos.y = uint32_t(yRatio * (float)extH);
- outPos.w = uint32_t(wRatio * (float)extW);
- outPos.h = uint32_t(hRatio * (float)extH);
- }
- // Convert Dim to hwc_rect_t
- outRect.left = outPos.x;
- outRect.top = outPos.y;
- outRect.right = outPos.x + outPos.w;
- outRect.bottom = outPos.y + outPos.h;
-
- return;
-}
-
-bool isPrimaryPortrait(hwc_context_t *ctx) {
- int fbWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
- int fbHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
- if(fbWidth < fbHeight) {
- return true;
- }
- return false;
-}
-
-bool isOrientationPortrait(hwc_context_t *ctx) {
- if(isPrimaryPortrait(ctx)) {
- return !(ctx->deviceOrientation & 0x1);
- }
- return (ctx->deviceOrientation & 0x1);
-}
-
-void calcExtDisplayPosition(hwc_context_t *ctx,
- private_handle_t *hnd,
- int dpy,
- hwc_rect_t& sourceCrop,
- hwc_rect_t& displayFrame,
- int& transform,
- ovutils::eTransform& orient) {
- // Swap width and height when there is a 90deg transform
- int extOrient = getExtOrientation(ctx);
- if(dpy && ctx->mOverlay->isUIScalingOnExternalSupported()) {
- if(!isYuvBuffer(hnd)) {
- if(extOrient & HWC_TRANSFORM_ROT_90) {
- int dstWidth = ctx->dpyAttr[dpy].xres;
- int dstHeight = ctx->dpyAttr[dpy].yres;;
- int srcWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
- int srcHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
- if(!isPrimaryPortrait(ctx)) {
- swap(srcWidth, srcHeight);
- } // Get Aspect Ratio for external
- qdutils::getAspectRatioPosition(dstWidth, dstHeight, srcWidth,
- srcHeight, displayFrame);
- // Crop - this is needed, because for sidesync, the dest fb will
- // be in portrait orientation, so update the crop to not show the
- // black side bands.
- if (isOrientationPortrait(ctx)) {
- sourceCrop = displayFrame;
- displayFrame.left = 0;
- displayFrame.top = 0;
- displayFrame.right = dstWidth;
- displayFrame.bottom = dstHeight;
- }
- }
- if(ctx->dpyAttr[dpy].mMDPScalingMode) {
- uint32_t extW = 0, extH = 0;
- // if MDP scaling mode is enabled, map the co-ordinates to new
- // domain(downscaled)
- float fbWidth = (float)ctx->dpyAttr[dpy].xres;
- float fbHeight = (float)ctx->dpyAttr[dpy].yres;
- // query MDP configured attributes
- if(dpy == HWC_DISPLAY_EXTERNAL) {
- ctx->mHDMIDisplay->getAttributes(extW, extH);
- } else if(dpy == HWC_DISPLAY_VIRTUAL) {
- extW = ctx->mHWCVirtual->getScalingWidth();
- extH = ctx->mHWCVirtual->getScalingHeight();
- }
- ALOGD_IF(HWC_UTILS_DEBUG, "%s: Scaling mode extW=%d extH=%d",
- __FUNCTION__, extW, extH);
-
- //Calculate the ratio...
- float wRatio = ((float)extW)/fbWidth;
- float hRatio = ((float)extH)/fbHeight;
-
- //convert Dim to hwc_rect_t
- displayFrame.left = int(wRatio*(float)displayFrame.left);
- displayFrame.top = int(hRatio*(float)displayFrame.top);
- displayFrame.right = int(wRatio*(float)displayFrame.right);
- displayFrame.bottom = int(hRatio*(float)displayFrame.bottom);
- ALOGD_IF(DEBUG_MDPDOWNSCALE, "Calculated external display frame"
- " for MDPDownscale feature [%d %d %d %d]",
- displayFrame.left, displayFrame.top,
- displayFrame.right, displayFrame.bottom);
- }
- }else {
- if(extOrient || ctx->dpyAttr[dpy].mMDPScalingMode) {
- getAspectRatioPosition(ctx, dpy, extOrient,
- displayFrame, displayFrame);
- }
- }
- // If there is a external orientation set, use that
- if(extOrient) {
- transform = extOrient;
- orient = static_cast<ovutils::eTransform >(extOrient);
- }
- // Calculate the actionsafe dimensions for External(dpy = 1 or 2)
- getActionSafePosition(ctx, dpy, displayFrame);
- }
-}
-
-/* Returns the orientation which needs to be set on External for
- * SideSync/Buffer Mirrormode
- */
-int getMirrorModeOrientation(hwc_context_t *ctx) {
- int extOrientation = 0;
- int deviceOrientation = ctx->deviceOrientation;
- if(!isPrimaryPortrait(ctx))
- deviceOrientation = (deviceOrientation + 1) % 4;
- if (deviceOrientation == 0)
- extOrientation = HWC_TRANSFORM_ROT_270;
- else if (deviceOrientation == 1)//90
- extOrientation = 0;
- else if (deviceOrientation == 2)//180
- extOrientation = HWC_TRANSFORM_ROT_90;
- else if (deviceOrientation == 3)//270
- extOrientation = HWC_TRANSFORM_FLIP_V | HWC_TRANSFORM_FLIP_H;
-
- return extOrientation;
-}
-
-/* Get External State names */
-const char* getExternalDisplayState(uint32_t external_state) {
- static const char* externalStates[EXTERNAL_MAXSTATES] = {0};
- externalStates[EXTERNAL_OFFLINE] = STR(EXTERNAL_OFFLINE);
- externalStates[EXTERNAL_ONLINE] = STR(EXTERNAL_ONLINE);
- externalStates[EXTERNAL_PAUSE] = STR(EXTERNAL_PAUSE);
- externalStates[EXTERNAL_RESUME] = STR(EXTERNAL_RESUME);
-
- if(external_state >= EXTERNAL_MAXSTATES) {
- return "EXTERNAL_INVALID";
- }
-
- return externalStates[external_state];
-}
-
-bool isDownscaleRequired(hwc_layer_1_t const* layer) {
- hwc_rect_t displayFrame = layer->displayFrame;
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
- int dst_w, dst_h, src_w, src_h;
- dst_w = displayFrame.right - displayFrame.left;
- dst_h = displayFrame.bottom - displayFrame.top;
- src_w = sourceCrop.right - sourceCrop.left;
- src_h = sourceCrop.bottom - sourceCrop.top;
-
- if(((src_w > dst_w) || (src_h > dst_h)))
- return true;
-
- return false;
-}
-bool needsScaling(hwc_layer_1_t const* layer) {
- int dst_w, dst_h, src_w, src_h;
- hwc_rect_t displayFrame = layer->displayFrame;
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
-
- dst_w = displayFrame.right - displayFrame.left;
- dst_h = displayFrame.bottom - displayFrame.top;
- src_w = sourceCrop.right - sourceCrop.left;
- src_h = sourceCrop.bottom - sourceCrop.top;
-
- if(((src_w != dst_w) || (src_h != dst_h)))
- return true;
-
- return false;
-}
-
-// Checks if layer needs scaling with split
-bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
- const int& dpy) {
-
- int src_width_l, src_height_l;
- int src_width_r, src_height_r;
- int dst_width_l, dst_height_l;
- int dst_width_r, dst_height_r;
- int hw_w = ctx->dpyAttr[dpy].xres;
- int hw_h = ctx->dpyAttr[dpy].yres;
- hwc_rect_t cropL, dstL, cropR, dstR;
- const int lSplit = getLeftSplit(ctx, dpy);
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t displayFrame = layer->displayFrame;
- private_handle_t *hnd = (private_handle_t *)layer->handle;
-
- cropL = sourceCrop;
- dstL = displayFrame;
- hwc_rect_t scissorL = { 0, 0, lSplit, hw_h };
- scissorL = getIntersection(ctx->mViewFrame[dpy], scissorL);
- qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);
-
- cropR = sourceCrop;
- dstR = displayFrame;
- hwc_rect_t scissorR = { lSplit, 0, hw_w, hw_h };
- scissorR = getIntersection(ctx->mViewFrame[dpy], scissorR);
- qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);
-
- // Sanitize Crop to stitch
- sanitizeSourceCrop(cropL, cropR, hnd);
-
- // Calculate the left dst
- dst_width_l = dstL.right - dstL.left;
- dst_height_l = dstL.bottom - dstL.top;
- src_width_l = cropL.right - cropL.left;
- src_height_l = cropL.bottom - cropL.top;
-
- // check if there is any scaling on the left
- if(((src_width_l != dst_width_l) || (src_height_l != dst_height_l)))
- return true;
-
- // Calculate the right dst
- dst_width_r = dstR.right - dstR.left;
- dst_height_r = dstR.bottom - dstR.top;
- src_width_r = cropR.right - cropR.left;
- src_height_r = cropR.bottom - cropR.top;
-
- // check if there is any scaling on the right
- if(((src_width_r != dst_width_r) || (src_height_r != dst_height_r)))
- return true;
-
- return false;
-}
-
-bool isAlphaScaled(hwc_layer_1_t const* layer) {
- if(needsScaling(layer) && isAlphaPresent(layer)) {
- return true;
- }
- return false;
-}
-
-bool isAlphaPresent(hwc_layer_1_t const* layer) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(hnd) {
- int format = hnd->format;
- switch(format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- // In any more formats with Alpha go here..
- return true;
- default : return false;
- }
- }
- return false;
-}
-
-bool isAlphaPresentinFB(hwc_context_t *ctx, int dpy) {
- switch(ctx->dpyAttr[dpy].fbformat) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return true;
- default : return false;
- }
- return false;
-}
-
-static void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
- hwc_rect_t& crop, hwc_rect_t& dst) {
- int hw_w = ctx->dpyAttr[dpy].xres;
- int hw_h = ctx->dpyAttr[dpy].yres;
- if(dst.left < 0 || dst.top < 0 ||
- dst.right > hw_w || dst.bottom > hw_h) {
- hwc_rect_t scissor = {0, 0, hw_w, hw_h };
- scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
- qhwc::calculate_crop_rects(crop, dst, scissor, transform);
- }
-}
-
-static void trimList(hwc_context_t *ctx, hwc_display_contents_1_t *list,
- const int& dpy) {
- for(uint32_t i = 0; i < list->numHwLayers - 1; i++) {
- hwc_layer_1_t *layer = &list->hwLayers[i];
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- int transform = (list->hwLayers[i].flags & HWC_COLOR_FILL) ? 0 :
- list->hwLayers[i].transform;
- trimLayer(ctx, dpy,
- transform,
- (hwc_rect_t&)crop,
- (hwc_rect_t&)list->hwLayers[i].displayFrame);
- layer->sourceCropf.left = (float)crop.left;
- layer->sourceCropf.right = (float)crop.right;
- layer->sourceCropf.top = (float)crop.top;
- layer->sourceCropf.bottom = (float)crop.bottom;
- }
-}
-
-void setListStats(hwc_context_t *ctx,
- hwc_display_contents_1_t *list, int dpy) {
- const int prevYuvCount = ctx->listStats[dpy].yuvCount;
- memset(&ctx->listStats[dpy], 0, sizeof(ListStats));
- ctx->listStats[dpy].numAppLayers = (int)list->numHwLayers - 1;
- ctx->listStats[dpy].fbLayerIndex = (int)list->numHwLayers - 1;
- ctx->listStats[dpy].skipCount = 0;
- ctx->listStats[dpy].preMultipliedAlpha = false;
- ctx->listStats[dpy].isSecurePresent = false;
- ctx->listStats[dpy].yuvCount = 0;
- char property[PROPERTY_VALUE_MAX];
- ctx->listStats[dpy].isDisplayAnimating = false;
- ctx->listStats[dpy].secureUI = false;
- ctx->listStats[dpy].yuv4k2kCount = 0;
- ctx->dpyAttr[dpy].mActionSafePresent = isActionSafePresent(ctx, dpy);
- ctx->listStats[dpy].renderBufIndexforABC = -1;
- ctx->listStats[dpy].secureRGBCount = 0;
- ctx->listStats[dpy].refreshRateRequest = ctx->dpyAttr[dpy].refreshRate;
- uint32_t refreshRate = 0;
- qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
-
- ctx->listStats[dpy].mAIVVideoMode = false;
- resetROI(ctx, dpy);
-
- trimList(ctx, list, dpy);
- optimizeLayerRects(list);
- for (size_t i = 0; i < (size_t)ctx->listStats[dpy].numAppLayers; i++) {
- hwc_layer_1_t const* layer = &list->hwLayers[i];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
-
-#ifdef QTI_BSP
- // Window boxing feature is applicable obly for external display, So
- // enable mAIVVideoMode only for external display
- if(ctx->mWindowboxFeature && dpy && isAIVVideoLayer(layer)) {
- ctx->listStats[dpy].mAIVVideoMode = true;
- }
- if (layer->flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
- ctx->listStats[dpy].isDisplayAnimating = true;
- }
- if(isSecureDisplayBuffer(hnd)) {
- ctx->listStats[dpy].secureUI = true;
- }
-#endif
- // continue if number of app layers exceeds MAX_NUM_APP_LAYERS
- if(ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS)
- continue;
-
- //reset yuv indices
- ctx->listStats[dpy].yuvIndices[i] = -1;
- ctx->listStats[dpy].yuv4k2kIndices[i] = -1;
-
- if (isSecureBuffer(hnd)) {
- ctx->listStats[dpy].isSecurePresent = true;
- if(not isYuvBuffer(hnd)) {
- // cache secureRGB layer parameters like we cache for YUV layers
- int& secureRGBCount = ctx->listStats[dpy].secureRGBCount;
- ctx->listStats[dpy].secureRGBIndices[secureRGBCount] = (int)i;
- secureRGBCount++;
- }
- }
-
- if (isSkipLayer(&list->hwLayers[i])) {
- ctx->listStats[dpy].skipCount++;
- }
-
- if (UNLIKELY(isYuvBuffer(hnd))) {
- int& yuvCount = ctx->listStats[dpy].yuvCount;
- ctx->listStats[dpy].yuvIndices[yuvCount] = (int)i;
- yuvCount++;
-
- if(UNLIKELY(isYUVSplitNeeded(hnd))){
- int& yuv4k2kCount = ctx->listStats[dpy].yuv4k2kCount;
- ctx->listStats[dpy].yuv4k2kIndices[yuv4k2kCount] = (int)i;
- yuv4k2kCount++;
- }
- }
- if(layer->blending == HWC_BLENDING_PREMULT)
- ctx->listStats[dpy].preMultipliedAlpha = true;
-
-#ifdef DYNAMIC_FPS
- if (!dpy && mdpHw.isDynFpsSupported() && ctx->mUseMetaDataRefreshRate){
- /* Dyn fps: get refreshrate from metadata */
- MetaData_t *mdata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
- if (mdata && (mdata->operation & UPDATE_REFRESH_RATE)) {
- // Valid refreshRate in metadata and within the range
- uint32_t rate = getRefreshRate(ctx, mdata->refreshrate);
- if (!refreshRate) {
- refreshRate = rate;
- } else if(refreshRate != rate) {
- /* Support multiple refresh rates if they are same
- * else set to default.
- */
- refreshRate = ctx->dpyAttr[dpy].refreshRate;
- }
- }
- }
-#endif
- }
- if(ctx->listStats[dpy].yuvCount > 0) {
- if (property_get("hw.cabl.yuv", property, NULL) > 0) {
- if (atoi(property) != 1) {
- property_set("hw.cabl.yuv", "1");
- }
- }
- } else {
- if (property_get("hw.cabl.yuv", property, NULL) > 0) {
- if (atoi(property) != 0) {
- property_set("hw.cabl.yuv", "0");
- }
- }
- }
-
- //The marking of video begin/end is useful on some targets where we need
- //to have a padding round to be able to shift pipes across mixers.
- if(prevYuvCount != ctx->listStats[dpy].yuvCount) {
- ctx->mVideoTransFlag = true;
- }
-
- if(dpy == HWC_DISPLAY_PRIMARY) {
- ctx->mAD->markDoable(ctx, list);
- //Store the requested fresh rate
- ctx->listStats[dpy].refreshRateRequest = refreshRate ?
- refreshRate : ctx->dpyAttr[dpy].refreshRate;
- }
-}
-
-
-static void calc_cut(double& leftCutRatio, double& topCutRatio,
- double& rightCutRatio, double& bottomCutRatio, int orient) {
- if(orient & HAL_TRANSFORM_FLIP_H) {
- swap(leftCutRatio, rightCutRatio);
- }
- if(orient & HAL_TRANSFORM_FLIP_V) {
- swap(topCutRatio, bottomCutRatio);
- }
- if(orient & HAL_TRANSFORM_ROT_90) {
- //Anti clock swapping
- double tmpCutRatio = leftCutRatio;
- leftCutRatio = topCutRatio;
- topCutRatio = rightCutRatio;
- rightCutRatio = bottomCutRatio;
- bottomCutRatio = tmpCutRatio;
- }
-}
-
-bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer) {
- if((ctx->mMDP.version < qdutils::MDSS_V5) &&
- (ctx->mMDP.version > qdutils::MDP_V3_0) &&
- ctx->mSecuring) {
- return true;
- }
- if (isSecureModePolicy(ctx->mMDP.version)) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(ctx->mSecureMode) {
- if (! isSecureBuffer(hnd)) {
- ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning ON ...",
- __FUNCTION__);
- return true;
- }
- } else {
- if (isSecureBuffer(hnd)) {
- ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning OFF ...",
- __FUNCTION__);
- return true;
- }
- }
- }
- return false;
-}
-
-bool isSecureModePolicy(int mdpVersion) {
- if (mdpVersion < qdutils::MDSS_V5)
- return true;
- else
- return false;
-}
-
-bool isRotatorSupportedFormat(private_handle_t *hnd) {
- // Following rotator src formats are supported by mdp driver
- // TODO: Add more formats in future, if mdp driver adds support
- switch(hnd->format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGB_565:
- case HAL_PIXEL_FORMAT_RGB_888:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return true;
- default:
- return false;
- }
- return false;
-}
-
-bool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd) {
- // Rotate layers, if it is YUV type or rendered by CPU and not
- // for the MDP versions below MDP5
- if((isCPURendered(hnd) && isRotatorSupportedFormat(hnd) &&
- !(ctx->mMDP.version < qdutils::MDSS_V5))
- || isYuvBuffer(hnd)) {
- return true;
- }
- return false;
-}
-
-// returns true if Action safe dimensions are set and target supports Actionsafe
-bool isActionSafePresent(hwc_context_t *ctx, int dpy) {
- // if external supports underscan, do nothing
- // it will be taken care in the driver
- // Disable Action safe for 8974 due to HW limitation for downscaling
- // layers with overlapped region
- // Disable Actionsafe for non HDMI displays.
- if(!(dpy == HWC_DISPLAY_EXTERNAL) ||
- qdutils::MDPVersion::getInstance().is8x74v2() ||
- ctx->mHDMIDisplay->isCEUnderscanSupported()) {
- return false;
- }
-
- char value[PROPERTY_VALUE_MAX];
- // Read action safe properties
- property_get("persist.sys.actionsafe.width", value, "0");
- ctx->dpyAttr[dpy].mAsWidthRatio = atoi(value);
- property_get("persist.sys.actionsafe.height", value, "0");
- ctx->dpyAttr[dpy].mAsHeightRatio = atoi(value);
-
- if(!ctx->dpyAttr[dpy].mAsWidthRatio && !ctx->dpyAttr[dpy].mAsHeightRatio) {
- //No action safe ratio set, return
- return false;
- }
- return true;
-}
-
-int getBlending(int blending) {
- switch(blending) {
- case HWC_BLENDING_NONE:
- return overlay::utils::OVERLAY_BLENDING_OPAQUE;
- case HWC_BLENDING_PREMULT:
- return overlay::utils::OVERLAY_BLENDING_PREMULT;
- case HWC_BLENDING_COVERAGE :
- default:
- return overlay::utils::OVERLAY_BLENDING_COVERAGE;
- }
-}
-
-//Crops source buffer against destination and FB boundaries
-void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
- const hwc_rect_t& scissor, int orient) {
-
- int& crop_l = crop.left;
- int& crop_t = 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_l = dst.left;
- int& dst_t = dst.top;
- int& dst_r = dst.right;
- int& dst_b = dst.bottom;
- int dst_w = abs(dst.right - dst.left);
- int dst_h = abs(dst.bottom - dst.top);
-
- const int& sci_l = scissor.left;
- const int& sci_t = scissor.top;
- const int& sci_r = scissor.right;
- const int& sci_b = scissor.bottom;
-
- double leftCutRatio = 0.0, rightCutRatio = 0.0, topCutRatio = 0.0,
- bottomCutRatio = 0.0;
-
- if(dst_l < sci_l) {
- leftCutRatio = (double)(sci_l - dst_l) / (double)dst_w;
- dst_l = sci_l;
- }
-
- if(dst_r > sci_r) {
- rightCutRatio = (double)(dst_r - sci_r) / (double)dst_w;
- dst_r = sci_r;
- }
-
- if(dst_t < sci_t) {
- topCutRatio = (double)(sci_t - dst_t) / (double)dst_h;
- dst_t = sci_t;
- }
-
- if(dst_b > sci_b) {
- bottomCutRatio = (double)(dst_b - sci_b) / (double)dst_h;
- dst_b = sci_b;
- }
-
- calc_cut(leftCutRatio, topCutRatio, rightCutRatio, bottomCutRatio, orient);
- crop_l += (int)round((double)crop_w * leftCutRatio);
- crop_t += (int)round((double)crop_h * topCutRatio);
- crop_r -= (int)round((double)crop_w * rightCutRatio);
- crop_b -= (int)round((double)crop_h * bottomCutRatio);
-}
-
-bool areLayersIntersecting(const hwc_layer_1_t* layer1,
- const hwc_layer_1_t* layer2) {
- hwc_rect_t irect = getIntersection(layer1->displayFrame,
- layer2->displayFrame);
- return isValidRect(irect);
-}
-
-bool isSameRect(const hwc_rect& rect1, const hwc_rect& rect2)
-{
- return ((rect1.left == rect2.left) && (rect1.top == rect2.top) &&
- (rect1.right == rect2.right) && (rect1.bottom == rect2.bottom));
-}
-
-bool isValidRect(const hwc_rect& rect)
-{
- return ((rect.bottom > rect.top) && (rect.right > rect.left)) ;
-}
-
-bool operator ==(const hwc_rect_t& lhs, const hwc_rect_t& rhs) {
- if(lhs.left == rhs.left && lhs.top == rhs.top &&
- lhs.right == rhs.right && lhs.bottom == rhs.bottom )
- return true ;
- return false;
-}
-
-bool layerUpdating(const hwc_layer_1_t* layer) {
- hwc_region_t surfDamage = layer->surfaceDamage;
- return ((surfDamage.numRects == 0) ||
- isValidRect(layer->surfaceDamage.rects[0]));
-}
-
-hwc_rect_t calculateDirtyRect(const hwc_layer_1_t* layer,
- hwc_rect_t& scissor) {
- hwc_region_t surfDamage = layer->surfaceDamage;
- hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t dst = layer->displayFrame;
- int x_off = dst.left - src.left;
- int y_off = dst.top - src.top;
- hwc_rect dirtyRect = (hwc_rect){0, 0, 0, 0};
- hwc_rect_t updatingRect = dst;
-
- if (surfDamage.numRects == 0) {
- // full layer updating, dirty rect is full frame
- dirtyRect = getIntersection(layer->displayFrame, scissor);
- } else {
- for(uint32_t i = 0; i < surfDamage.numRects; i++) {
- updatingRect = moveRect(surfDamage.rects[i], x_off, y_off);
- hwc_rect_t intersect = getIntersection(updatingRect, scissor);
- if(isValidRect(intersect)) {
- dirtyRect = getUnion(intersect, dirtyRect);
- }
- }
- }
- return dirtyRect;
-}
-
-hwc_rect_t moveRect(const hwc_rect_t& rect, const int& x_off, const int& y_off)
-{
- hwc_rect_t res;
-
- if(!isValidRect(rect))
- return (hwc_rect_t){0, 0, 0, 0};
-
- res.left = rect.left + x_off;
- res.top = rect.top + y_off;
- res.right = rect.right + x_off;
- res.bottom = rect.bottom + y_off;
-
- return res;
-}
-
-/* computes the intersection of two rects */
-hwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2)
-{
- hwc_rect_t res;
-
- if(!isValidRect(rect1) || !isValidRect(rect2)){
- return (hwc_rect_t){0, 0, 0, 0};
- }
-
-
- res.left = max(rect1.left, rect2.left);
- res.top = max(rect1.top, rect2.top);
- res.right = min(rect1.right, rect2.right);
- res.bottom = min(rect1.bottom, rect2.bottom);
-
- if(!isValidRect(res))
- return (hwc_rect_t){0, 0, 0, 0};
-
- return res;
-}
-
-/* computes the union of two rects */
-hwc_rect_t getUnion(const hwc_rect &rect1, const hwc_rect &rect2)
-{
- hwc_rect_t res;
-
- if(!isValidRect(rect1)){
- return rect2;
- }
-
- if(!isValidRect(rect2)){
- return rect1;
- }
-
- res.left = min(rect1.left, rect2.left);
- res.top = min(rect1.top, rect2.top);
- res.right = max(rect1.right, rect2.right);
- res.bottom = max(rect1.bottom, rect2.bottom);
-
- return res;
-}
-
-/* Not a geometrical rect deduction. Deducts rect2 from rect1 only if it results
- * a single rect */
-hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
-
- hwc_rect_t res = rect1;
-
- if((rect1.left == rect2.left) && (rect1.right == rect2.right)) {
- if((rect1.top == rect2.top) && (rect2.bottom <= rect1.bottom))
- res.top = rect2.bottom;
- else if((rect1.bottom == rect2.bottom)&& (rect2.top >= rect1.top))
- res.bottom = rect2.top;
- }
- else if((rect1.top == rect2.top) && (rect1.bottom == rect2.bottom)) {
- if((rect1.left == rect2.left) && (rect2.right <= rect1.right))
- res.left = rect2.right;
- else if((rect1.right == rect2.right)&& (rect2.left >= rect1.left))
- res.right = rect2.left;
- }
- return res;
-}
-
-void optimizeLayerRects(const hwc_display_contents_1_t *list) {
- int i= (int)list->numHwLayers-2;
- while(i > 0) {
- //see if there is no blending required.
- //If it is opaque see if we can substract this region from below
- //layers.
- if(list->hwLayers[i].blending == HWC_BLENDING_NONE &&
- list->hwLayers[i].planeAlpha == 0xFF) {
- int j= i-1;
- hwc_rect_t& topframe =
- (hwc_rect_t&)list->hwLayers[i].displayFrame;
- while(j >= 0) {
- if(!needsScaling(&list->hwLayers[j])) {
- hwc_layer_1_t* layer = (hwc_layer_1_t*)&list->hwLayers[j];
- hwc_rect_t& bottomframe = layer->displayFrame;
- hwc_rect_t bottomCrop =
- integerizeSourceCrop(layer->sourceCropf);
- int transform = (layer->flags & HWC_COLOR_FILL) ? 0 :
- layer->transform;
-
- hwc_rect_t irect = getIntersection(bottomframe, topframe);
- if(isValidRect(irect)) {
- hwc_rect_t dest_rect;
- //if intersection is valid rect, deduct it
- dest_rect = deductRect(bottomframe, irect);
- qhwc::calculate_crop_rects(bottomCrop, bottomframe,
- dest_rect, transform);
- //Update layer sourceCropf
- layer->sourceCropf.left =(float)bottomCrop.left;
- layer->sourceCropf.top = (float)bottomCrop.top;
- layer->sourceCropf.right = (float)bottomCrop.right;
- layer->sourceCropf.bottom = (float)bottomCrop.bottom;
- }
- }
- j--;
- }
- }
- i--;
- }
-}
-
-void getNonWormholeRegion(hwc_display_contents_1_t* list,
- hwc_rect_t& nwr)
-{
- size_t last = list->numHwLayers - 1;
- hwc_rect_t fbDisplayFrame = list->hwLayers[last].displayFrame;
- //Initiliaze nwr to first frame
- nwr.left = list->hwLayers[0].displayFrame.left;
- nwr.top = list->hwLayers[0].displayFrame.top;
- nwr.right = list->hwLayers[0].displayFrame.right;
- nwr.bottom = list->hwLayers[0].displayFrame.bottom;
-
- for (size_t i = 1; i < last; i++) {
- hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
- nwr = getUnion(nwr, displayFrame);
- }
-
- //Intersect with the framebuffer
- nwr = getIntersection(nwr, fbDisplayFrame);
-}
-
-bool isExternalActive(hwc_context_t* ctx) {
- return ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive;
-}
-
-void closeAcquireFds(hwc_display_contents_1_t* list) {
- if(LIKELY(list)) {
- for(uint32_t i = 0; i < list->numHwLayers; i++) {
- //Close the acquireFenceFds
- //HWC_FRAMEBUFFER are -1 already by SF, rest we close.
- if(list->hwLayers[i].acquireFenceFd >= 0) {
- close(list->hwLayers[i].acquireFenceFd);
- list->hwLayers[i].acquireFenceFd = -1;
- }
- }
- //Writeback
- if(list->outbufAcquireFenceFd >= 0) {
- close(list->outbufAcquireFenceFd);
- list->outbufAcquireFenceFd = -1;
- }
- }
-}
-
-int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
- int fd) {
- ATRACE_CALL();
- int ret = 0;
- int acquireFd[MAX_NUM_APP_LAYERS];
- int count = 0;
- int releaseFd = -1;
- int retireFd = -1;
- int fbFd = -1;
- bool swapzero = false;
-
- struct mdp_buf_sync data;
- memset(&data, 0, sizeof(data));
- data.acq_fen_fd = acquireFd;
- data.rel_fen_fd = &releaseFd;
- data.retire_fen_fd = &retireFd;
- data.flags = MDP_BUF_SYNC_FLAG_RETIRE_FENCE;
-
-#ifdef DEBUG_SWAPINTERVAL
- char property[PROPERTY_VALUE_MAX];
- if(property_get("debug.egl.swapinterval", property, "1") > 0) {
- if(atoi(property) == 0)
- swapzero = true;
- }
-#endif
-
- bool isExtAnimating = false;
- if(dpy)
- isExtAnimating = ctx->listStats[dpy].isDisplayAnimating;
-
- //Send acquireFenceFds to rotator
- for(uint32_t i = 0; i < ctx->mLayerRotMap[dpy]->getCount(); i++) {
- int rotFd = ctx->mRotMgr->getRotDevFd();
- int rotReleaseFd = -1;
- overlay::Rotator* currRot = ctx->mLayerRotMap[dpy]->getRot(i);
- hwc_layer_1_t* currLayer = ctx->mLayerRotMap[dpy]->getLayer(i);
- if((currRot == NULL) || (currLayer == NULL)) {
- continue;
- }
- struct mdp_buf_sync rotData;
- memset(&rotData, 0, sizeof(rotData));
- rotData.acq_fen_fd =
- &currLayer->acquireFenceFd;
- rotData.rel_fen_fd = &rotReleaseFd; //driver to populate this
- rotData.session_id = currRot->getSessId();
- if(currLayer->acquireFenceFd >= 0) {
- rotData.acq_fen_fd_cnt = 1; //1 ioctl call per rot session
- }
- int ret = 0;
- if(LIKELY(!swapzero) and (not ctx->mLayerRotMap[dpy]->isRotCached(i)))
- ret = ioctl(rotFd, MSMFB_BUFFER_SYNC, &rotData);
-
- if(ret < 0) {
- ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed for rot sync, err=%s",
- __FUNCTION__, strerror(errno));
- close(rotReleaseFd);
- } else {
- close(currLayer->acquireFenceFd);
- //For MDP to wait on.
- currLayer->acquireFenceFd =
- dup(rotReleaseFd);
- //A buffer is free to be used by producer as soon as its copied to
- //rotator
- currLayer->releaseFenceFd =
- rotReleaseFd;
- }
- }
-
- //Accumulate acquireFenceFds for MDP Overlays
- if(list->outbufAcquireFenceFd >= 0) {
- //Writeback output buffer
- if(LIKELY(!swapzero) )
- acquireFd[count++] = list->outbufAcquireFenceFd;
- }
-
- for(uint32_t i = 0; i < list->numHwLayers; i++) {
- if(((isAbcInUse(ctx)== true ) ||
- (list->hwLayers[i].compositionType == HWC_OVERLAY)) &&
- list->hwLayers[i].acquireFenceFd >= 0) {
- if(LIKELY(!swapzero) ) {
- // if ABC is enabled for more than one layer.
- // renderBufIndexforABC will work as FB.Hence
- // set the acquireFD from fd - which is coming from copybit
- if(fd >= 0 && (isAbcInUse(ctx) == true)) {
- if(ctx->listStats[dpy].renderBufIndexforABC ==(int32_t)i)
- acquireFd[count++] = fd;
- else
- continue;
- } else
- acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
- }
- }
- if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
- if(LIKELY(!swapzero) ) {
- if(fd >= 0) {
- //set the acquireFD from fd - which is coming from c2d
- acquireFd[count++] = fd;
- // Buffer sync IOCTL should be async when using c2d fence is
- // used
- data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
- } else if(list->hwLayers[i].acquireFenceFd >= 0)
- acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
- }
- }
- }
-
- if ((fd >= 0) && !dpy && ctx->mPtorInfo.isActive()) {
- // Acquire c2d fence of Overlap render buffer
- if(LIKELY(!swapzero) )
- acquireFd[count++] = fd;
- }
-
- data.acq_fen_fd_cnt = count;
- fbFd = ctx->dpyAttr[dpy].fd;
-
- //Waits for acquire fences, returns a release fence
- if(LIKELY(!swapzero)) {
- ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
- }
-
- if(ret < 0) {
- ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed, err=%s",
- __FUNCTION__, strerror(errno));
- ALOGE("%s: acq_fen_fd_cnt=%d flags=%d fd=%d dpy=%d numHwLayers=%zu",
- __FUNCTION__, data.acq_fen_fd_cnt, data.flags, fbFd,
- dpy, list->numHwLayers);
- close(releaseFd);
- releaseFd = -1;
- close(retireFd);
- retireFd = -1;
- }
-
- for(uint32_t i = 0; i < list->numHwLayers; i++) {
- if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
-#ifdef QTI_BSP
- list->hwLayers[i].compositionType == HWC_BLIT ||
-#endif
- list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
- //Populate releaseFenceFds.
- if(UNLIKELY(swapzero)) {
- list->hwLayers[i].releaseFenceFd = -1;
- } else if(isExtAnimating) {
- // Release all the app layer fds immediately,
- // if animation is in progress.
- list->hwLayers[i].releaseFenceFd = -1;
- } else if(list->hwLayers[i].releaseFenceFd < 0 ) {
-#ifdef QTI_BSP
- //If rotator has not already populated this field
- // & if it's a not VPU layer
-
- // if ABC is enabled for more than one layer
- if(fd >= 0 && (isAbcInUse(ctx) == true) &&
- ctx->listStats[dpy].renderBufIndexforABC !=(int32_t)i){
- list->hwLayers[i].releaseFenceFd = dup(fd);
- } else if((list->hwLayers[i].compositionType == HWC_BLIT)&&
- (isAbcInUse(ctx) == false)){
- //For Blit, the app layers should be released when the Blit
- //is complete. This fd was passed from copybit->draw
- list->hwLayers[i].releaseFenceFd = dup(fd);
- } else
-#endif
- {
- list->hwLayers[i].releaseFenceFd = dup(releaseFd);
- }
- }
- }
- }
-
- if(fd >= 0) {
- close(fd);
- fd = -1;
- }
-
- if (ctx->mCopyBit[dpy]) {
- if (!dpy && ctx->mPtorInfo.isActive())
- ctx->mCopyBit[dpy]->setReleaseFdSync(releaseFd);
- else
- ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
- }
-
- //Signals when MDP finishes reading rotator buffers.
- ctx->mLayerRotMap[dpy]->setReleaseFd(releaseFd);
- close(releaseFd);
- releaseFd = -1;
-
- if(UNLIKELY(swapzero)) {
- list->retireFenceFd = -1;
- } else {
- list->retireFenceFd = retireFd;
- }
- return ret;
-}
-
-void setMdpFlags(hwc_context_t *ctx, hwc_layer_1_t *layer,
- ovutils::eMdpFlags &mdpFlags,
- int rotDownscale, int transform) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- MetaData_t *metadata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
-
- if(layer->blending == HWC_BLENDING_PREMULT) {
- ovutils::setMdpFlags(mdpFlags,
- ovutils::OV_MDP_BLEND_FG_PREMULT);
- }
-
- if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
- metadata->interlaced) {
- ovutils::setMdpFlags(mdpFlags,
- ovutils::OV_MDP_DEINTERLACE);
- }
-
- // Mark MDP flags with SECURE_OVERLAY_SESSION for driver
- if(isSecureBuffer(hnd)) {
- ovutils::setMdpFlags(mdpFlags,
- ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
- }
-
- if(isSecureDisplayBuffer(hnd)) {
- // Mark MDP flags with SECURE_DISPLAY_OVERLAY_SESSION for driver
- ovutils::setMdpFlags(mdpFlags,
- ovutils::OV_MDP_SECURE_DISPLAY_OVERLAY_SESSION);
- }
-
- //Pre-rotation will be used using rotator.
- if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
- ovutils::setMdpFlags(mdpFlags,
- ovutils::OV_MDP_SOURCE_ROTATED_90);
- }
- //No 90 component and no rot-downscale then flips done by MDP
- //If we use rot then it might as well do flips
- if(!(transform & HWC_TRANSFORM_ROT_90) && !rotDownscale) {
- if(transform & HWC_TRANSFORM_FLIP_H) {
- ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
- }
-
- if(transform & HWC_TRANSFORM_FLIP_V) {
- ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V);
- }
- }
-
- if(metadata &&
- ((metadata->operation & PP_PARAM_HSIC)
- || (metadata->operation & PP_PARAM_IGC)
- || (metadata->operation & PP_PARAM_SHARP2))) {
- ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_PP_EN);
- }
-}
-
-int configRotator(Rotator *rot, Whf& whf,
- hwc_rect_t& crop, const eMdpFlags& mdpFlags,
- const eTransform& orient, const int& downscale) {
-
- // Fix alignments for TILED format
- if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
- whf.format == MDP_Y_CBCR_H2V2_TILE) {
- whf.w = utils::alignup(whf.w, 64);
- whf.h = utils::alignup(whf.h, 32);
- }
- rot->setSource(whf);
-
- if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
- qdutils::MDSS_V5) {
- Dim rotCrop(crop.left, crop.top, crop.right - crop.left,
- crop.bottom - crop.top);
- rot->setCrop(rotCrop);
- }
-
- rot->setFlags(mdpFlags);
- rot->setTransform(orient);
- rot->setDownscale(downscale);
- if(!rot->commit()) return -1;
- return 0;
-}
-
-int configMdp(Overlay *ov, const PipeArgs& parg,
- const eTransform& orient, const hwc_rect_t& crop,
- const hwc_rect_t& pos, const MetaData_t *metadata,
- const eDest& dest) {
- ov->setSource(parg, dest);
- ov->setTransform(orient, dest);
-
- int crop_w = crop.right - crop.left;
- int crop_h = crop.bottom - crop.top;
- Dim dcrop(crop.left, crop.top, crop_w, crop_h);
- ov->setCrop(dcrop, dest);
-
- int posW = pos.right - pos.left;
- int posH = pos.bottom - pos.top;
- Dim position(pos.left, pos.top, posW, posH);
- ov->setPosition(position, dest);
-
- if (metadata)
- ov->setVisualParams(*metadata, dest);
-
- if (!ov->commit(dest)) {
- return -1;
- }
- return 0;
-}
-
-int configColorLayer(hwc_context_t *ctx, hwc_layer_1_t *layer,
- const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
- const eDest& dest) {
-
- hwc_rect_t dst = layer->displayFrame;
- trimLayer(ctx, dpy, 0, dst, dst);
-
- int w = ctx->dpyAttr[dpy].xres;
- int h = ctx->dpyAttr[dpy].yres;
- int dst_w = dst.right - dst.left;
- int dst_h = dst.bottom - dst.top;
- uint32_t color = layer->transform;
- Whf whf(w, h, getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888), 0);
-
- ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SOLID_FILL);
- if (layer->blending == HWC_BLENDING_PREMULT)
- ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_BLEND_FG_PREMULT);
-
- PipeArgs parg(mdpFlags, whf, z, static_cast<eRotFlags>(0),
- layer->planeAlpha,
- (ovutils::eBlending) getBlending(layer->blending));
-
- // Configure MDP pipe for Color layer
- Dim pos(dst.left, dst.top, dst_w, dst_h);
- ctx->mOverlay->setSource(parg, dest);
- ctx->mOverlay->setColor(color, dest);
- ctx->mOverlay->setTransform(0, dest);
- ctx->mOverlay->setCrop(pos, dest);
- ctx->mOverlay->setPosition(pos, dest);
-
- if (!ctx->mOverlay->commit(dest)) {
- ALOGE("%s: Configure color layer failed!", __FUNCTION__);
- return -1;
- }
- return 0;
-}
-
-void updateSource(eTransform& orient, Whf& whf,
- hwc_rect_t& crop, Rotator *rot) {
- Dim transformedCrop(crop.left, crop.top,
- crop.right - crop.left,
- crop.bottom - crop.top);
- if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
- qdutils::MDSS_V5) {
- //B-family rotator internally could modify destination dimensions if
- //downscaling is supported
- whf = rot->getDstWhf();
- transformedCrop = rot->getDstDimensions();
- } else {
- //A-family rotator rotates entire buffer irrespective of crop, forcing
- //us to recompute the crop based on transform
- orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
- preRotateSource(orient, whf, transformedCrop);
- }
-
- crop.left = transformedCrop.x;
- crop.top = transformedCrop.y;
- crop.right = transformedCrop.x + transformedCrop.w;
- crop.bottom = transformedCrop.y + transformedCrop.h;
-}
-
-int getRotDownscale(hwc_context_t *ctx, const hwc_layer_1_t *layer) {
- if(not qdutils::MDPVersion::getInstance().isRotDownscaleEnabled()) {
- return 0;
- }
-
- int downscale = 0;
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t dst = layer->displayFrame;
- private_handle_t *hnd = (private_handle_t *)layer->handle;
-
- if(not hnd) {
- return 0;
- }
-
- MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
- bool isInterlaced = metadata && (metadata->operation & PP_PARAM_INTERLACED)
- && metadata->interlaced;
- int transform = layer->transform;
- uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
-
- if(isYuvBuffer(hnd)) {
- if(ctx->mMDP.version >= qdutils::MDP_V4_2 &&
- ctx->mMDP.version < qdutils::MDSS_V5) {
- downscale = Rotator::getDownscaleFactor(crop.right - crop.left,
- crop.bottom - crop.top, dst.right - dst.left,
- dst.bottom - dst.top, format, isInterlaced);
- } else {
- Dim adjCrop(crop.left, crop.top, crop.right - crop.left,
- crop.bottom - crop.top);
- Dim pos(dst.left, dst.top, dst.right - dst.left,
- dst.bottom - dst.top);
- if(transform & HAL_TRANSFORM_ROT_90) {
- swap(adjCrop.w, adjCrop.h);
- }
- downscale = Rotator::getDownscaleFactor(adjCrop.w, adjCrop.h, pos.w,
- pos.h, format, isInterlaced);
- }
- }
- return downscale;
-}
-
-bool isZoomModeEnabled(hwc_rect_t crop) {
- // This does not work for zooming in top left corner of the image
- return(crop.top > 0 || crop.left > 0);
-}
-
-void updateCropAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& crop, int dpy) {
- ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Source crop [%d %d %d %d]", dpy,
- crop.left, crop.top, crop.right, crop.bottom);
- if(isZoomModeEnabled(crop)) {
- Dim srcCrop(crop.left, crop.top,
- crop.right - crop.left,
- crop.bottom - crop.top);
- int extW = ctx->dpyAttr[dpy].xres;
- int extH = ctx->dpyAttr[dpy].yres;
- //Crop the original video in order to fit external display aspect ratio
- if(srcCrop.w * extH < extW * srcCrop.h) {
- int offset = (srcCrop.h - ((srcCrop.w * extH) / extW)) / 2;
- crop.top += offset;
- crop.bottom -= offset;
- } else {
- int offset = (srcCrop.w - ((extW * srcCrop.h) / extH)) / 2;
- crop.left += offset;
- crop.right -= offset;
- }
- ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
- " source crop [%d %d %d %d]", extW, extH, dpy,
- crop.left, crop.top, crop.right, crop.bottom);
- }
-}
-
-void updateDestAIVVideoMode(hwc_context_t *ctx, hwc_rect_t crop,
- hwc_rect_t& dst, int dpy) {
- ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Destination position [%d %d %d %d]", dpy,
- dst.left, dst.top, dst.right, dst.bottom);
- Dim srcCrop(crop.left, crop.top,
- crop.right - crop.left,
- crop.bottom - crop.top);
- int extW = ctx->dpyAttr[dpy].xres;
- int extH = ctx->dpyAttr[dpy].yres;
- // Set the destination coordinates of external display to full screen,
- // when zoom in mode is enabled or the ratio between video aspect ratio
- // and external display aspect ratio is below the minimum tolerance level
- // and above maximum tolerance level
- float videoAspectRatio = ((float)srcCrop.w / (float)srcCrop.h);
- float extDisplayAspectRatio = ((float)extW / (float)extH);
- float videoToExternalRatio = videoAspectRatio / extDisplayAspectRatio;
- if((fabs(1.0f - videoToExternalRatio) <= ctx->mAspectRatioToleranceLevel) ||
- (isZoomModeEnabled(crop))) {
- dst.left = 0;
- dst.top = 0;
- dst.right = extW;
- dst.bottom = extH;
- }
- ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
- " Destination position [%d %d %d %d] Source crop [%d %d %d %d]",
- extW, extH, dpy, dst.left, dst.top, dst.right, dst.bottom,
- crop.left, crop.top, crop.right, crop.bottom);
-}
-
-void updateCoordinates(hwc_context_t *ctx, hwc_rect_t& crop,
- hwc_rect_t& dst, int dpy) {
- updateCropAIVVideoMode(ctx, crop, dpy);
- updateDestAIVVideoMode(ctx, crop, dst, dpy);
-}
-
-int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
- const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
- const eDest& dest, Rotator **rot) {
-
- private_handle_t *hnd = (private_handle_t *)layer->handle;
-
- if(!hnd) {
- if (layer->flags & HWC_COLOR_FILL) {
- // Configure Color layer
- return configColorLayer(ctx, layer, dpy, mdpFlags, z, dest);
- }
- ALOGE("%s: layer handle is NULL", __FUNCTION__);
- return -1;
- }
-
- MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
-
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t dst = layer->displayFrame;
- int transform = layer->transform;
- eTransform orient = static_cast<eTransform>(transform);
- int rotFlags = ovutils::ROT_FLAGS_NONE;
- uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
- Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
-
- // Handle R/B swap
- if (layer->flags & HWC_FORMAT_RB_SWAP) {
- if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
- whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
- else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
- whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
- }
- // update source crop and destination position of AIV video layer.
- if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
- updateCoordinates(ctx, crop, dst, dpy);
- }
- calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
- int downscale = getRotDownscale(ctx, layer);
- setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
-
- //if 90 component or downscale, use rot
- if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
- *rot = ctx->mRotMgr->getNext();
- if(*rot == NULL) return -1;
- ctx->mLayerRotMap[dpy]->add(layer, *rot);
- // BWC is not tested for other formats So enable it only for YUV format
- if(!dpy && isYuvBuffer(hnd))
- BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
- //Configure rotator for pre-rotation
- if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
- ALOGE("%s: configRotator failed!", __FUNCTION__);
- return -1;
- }
- updateSource(orient, whf, crop, *rot);
- rotFlags |= ROT_PREROTATED;
- }
-
- //For the mdp, since either we are pre-rotating or MDP does flips
- orient = OVERLAY_TRANSFORM_0;
- transform = 0;
- PipeArgs parg(mdpFlags, whf, z,
- static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
- (ovutils::eBlending) getBlending(layer->blending));
-
- if(configMdp(ctx->mOverlay, parg, orient, crop, dst, metadata, dest) < 0) {
- ALOGE("%s: commit failed for low res panel", __FUNCTION__);
- return -1;
- }
- return 0;
-}
-
-//Helper to 1) Ensure crops dont have gaps 2) Ensure L and W are even
-void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
- private_handle_t *hnd) {
- if(cropL.right - cropL.left) {
- if(isYuvBuffer(hnd)) {
- //Always safe to even down left
- ovutils::even_floor(cropL.left);
- //If right is even, automatically width is even, since left is
- //already even
- ovutils::even_floor(cropL.right);
- }
- //Make sure there are no gaps between left and right splits if the layer
- //is spread across BOTH halves
- if(cropR.right - cropR.left) {
- cropR.left = cropL.right;
- }
- }
-
- if(cropR.right - cropR.left) {
- if(isYuvBuffer(hnd)) {
- //Always safe to even down left
- ovutils::even_floor(cropR.left);
- //If right is even, automatically width is even, since left is
- //already even
- ovutils::even_floor(cropR.right);
- }
- }
-}
-
-int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
- const int& dpy, eMdpFlags& mdpFlagsL, eZorder& z,
- const eDest& lDest, const eDest& rDest,
- Rotator **rot) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(!hnd) {
- ALOGE("%s: layer handle is NULL", __FUNCTION__);
- return -1;
- }
-
- MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
-
- int hw_w = ctx->dpyAttr[dpy].xres;
- int hw_h = ctx->dpyAttr[dpy].yres;
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t dst = layer->displayFrame;
- int transform = layer->transform;
- eTransform orient = static_cast<eTransform>(transform);
- int rotFlags = ROT_FLAGS_NONE;
- uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
- Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
-
- // Handle R/B swap
- if (layer->flags & HWC_FORMAT_RB_SWAP) {
- if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
- whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
- else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
- whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
- }
-
- // update source crop and destination position of AIV video layer.
- if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
- updateCoordinates(ctx, crop, dst, dpy);
- }
-
- /* Calculate the external display position based on MDP downscale,
- ActionSafe, and extorientation features. */
- calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
- int downscale = getRotDownscale(ctx, layer);
- setMdpFlags(ctx, layer, mdpFlagsL, downscale, transform);
-
- if(lDest != OV_INVALID && rDest != OV_INVALID) {
- //Enable overfetch
- setMdpFlags(mdpFlagsL, OV_MDSS_MDP_DUAL_PIPE);
- }
-
- //Will do something only if feature enabled and conditions suitable
- //hollow call otherwise
- if(ctx->mAD->prepare(ctx, crop, whf, hnd)) {
- overlay::Writeback *wb = overlay::Writeback::getInstance();
- whf.format = wb->getOutputFormat();
- }
-
- if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
- (*rot) = ctx->mRotMgr->getNext();
- if((*rot) == NULL) return -1;
- ctx->mLayerRotMap[dpy]->add(layer, *rot);
- //Configure rotator for pre-rotation
- if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
- ALOGE("%s: configRotator failed!", __FUNCTION__);
- return -1;
- }
- updateSource(orient, whf, crop, *rot);
- rotFlags |= ROT_PREROTATED;
- }
-
- eMdpFlags mdpFlagsR = mdpFlagsL;
- setMdpFlags(mdpFlagsR, OV_MDSS_MDP_RIGHT_MIXER);
-
- hwc_rect_t tmp_cropL = {0}, tmp_dstL = {0};
- hwc_rect_t tmp_cropR = {0}, tmp_dstR = {0};
-
- const int lSplit = getLeftSplit(ctx, dpy);
-
- // Calculate Left rects
- if(dst.left < lSplit) {
- tmp_cropL = crop;
- tmp_dstL = dst;
- hwc_rect_t scissor = {0, 0, lSplit, hw_h };
- scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
- qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0);
- }
-
- // Calculate Right rects
- if(dst.right > lSplit) {
- tmp_cropR = crop;
- tmp_dstR = dst;
- hwc_rect_t scissor = {lSplit, 0, hw_w, hw_h };
- scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
- qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0);
- }
-
- sanitizeSourceCrop(tmp_cropL, tmp_cropR, hnd);
-
- //When buffer is H-flipped, contents of mixer config also needs to swapped
- //Not needed if the layer is confined to one half of the screen.
- //If rotator has been used then it has also done the flips, so ignore them.
- if((orient & OVERLAY_TRANSFORM_FLIP_H) && (dst.left < lSplit) &&
- (dst.right > lSplit) && (*rot) == NULL) {
- hwc_rect_t new_cropR;
- new_cropR.left = tmp_cropL.left;
- new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left);
-
- hwc_rect_t new_cropL;
- new_cropL.left = new_cropR.right;
- new_cropL.right = tmp_cropR.right;
-
- tmp_cropL.left = new_cropL.left;
- tmp_cropL.right = new_cropL.right;
-
- tmp_cropR.left = new_cropR.left;
- tmp_cropR.right = new_cropR.right;
-
- }
-
- //For the mdp, since either we are pre-rotating or MDP does flips
- orient = OVERLAY_TRANSFORM_0;
- transform = 0;
-
- //configure left mixer
- if(lDest != OV_INVALID) {
- PipeArgs pargL(mdpFlagsL, whf, z,
- static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
- (ovutils::eBlending) getBlending(layer->blending));
-
- if(configMdp(ctx->mOverlay, pargL, orient,
- tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
- ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
- return -1;
- }
- }
-
- //configure right mixer
- if(rDest != OV_INVALID) {
- PipeArgs pargR(mdpFlagsR, whf, z,
- static_cast<eRotFlags>(rotFlags),
- layer->planeAlpha,
- (ovutils::eBlending) getBlending(layer->blending));
- tmp_dstR.right = tmp_dstR.right - lSplit;
- tmp_dstR.left = tmp_dstR.left - lSplit;
- if(configMdp(ctx->mOverlay, pargR, orient,
- tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
- ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
- return -1;
- }
- }
-
- return 0;
-}
-
-int configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
- const int& dpy, eMdpFlags& mdpFlagsL, eZorder& z,
- const eDest& lDest, const eDest& rDest,
- Rotator **rot) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(!hnd) {
- ALOGE("%s: layer handle is NULL", __FUNCTION__);
- return -1;
- }
-
- MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
-
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);;
- hwc_rect_t dst = layer->displayFrame;
- int transform = layer->transform;
- eTransform orient = static_cast<eTransform>(transform);
- const int downscale = 0;
- int rotFlags = ROT_FLAGS_NONE;
- //Splitting only YUV layer on primary panel needs different zorders
- //for both layers as both the layers are configured to single mixer
- eZorder lz = z;
- eZorder rz = (eZorder)(z + 1);
-
- Whf whf(getWidth(hnd), getHeight(hnd),
- getMdpFormat(hnd->format), (uint32_t)hnd->size);
-
- // update source crop and destination position of AIV video layer.
- if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
- updateCoordinates(ctx, crop, dst, dpy);
- }
-
- /* Calculate the external display position based on MDP downscale,
- ActionSafe, and extorientation features. */
- calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
-
- setMdpFlags(ctx, layer, mdpFlagsL, 0, transform);
- trimLayer(ctx, dpy, transform, crop, dst);
-
- if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
- (*rot) = ctx->mRotMgr->getNext();
- if((*rot) == NULL) return -1;
- ctx->mLayerRotMap[dpy]->add(layer, *rot);
- // BWC is not tested for other formats So enable it only for YUV format
- if(!dpy && isYuvBuffer(hnd))
- BwcPM::setBwc(crop, dst, transform, downscale, mdpFlagsL);
- //Configure rotator for pre-rotation
- if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
- ALOGE("%s: configRotator failed!", __FUNCTION__);
- return -1;
- }
- updateSource(orient, whf, crop, *rot);
- rotFlags |= ROT_PREROTATED;
- }
-
- eMdpFlags mdpFlagsR = mdpFlagsL;
- int lSplit = dst.left + (dst.right - dst.left)/2;
-
- hwc_rect_t tmp_cropL = {0}, tmp_dstL = {0};
- hwc_rect_t tmp_cropR = {0}, tmp_dstR = {0};
-
- if(lDest != OV_INVALID) {
- tmp_cropL = crop;
- tmp_dstL = dst;
- hwc_rect_t scissor = {dst.left, dst.top, lSplit, dst.bottom };
- qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0);
- }
- if(rDest != OV_INVALID) {
- tmp_cropR = crop;
- tmp_dstR = dst;
- hwc_rect_t scissor = {lSplit, dst.top, dst.right, dst.bottom };
- qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0);
- }
-
- sanitizeSourceCrop(tmp_cropL, tmp_cropR, hnd);
-
- //When buffer is H-flipped, contents of mixer config also needs to swapped
- //Not needed if the layer is confined to one half of the screen.
- //If rotator has been used then it has also done the flips, so ignore them.
- if((orient & OVERLAY_TRANSFORM_FLIP_H) && lDest != OV_INVALID
- && rDest != OV_INVALID && (*rot) == NULL) {
- hwc_rect_t new_cropR;
- new_cropR.left = tmp_cropL.left;
- new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left);
-
- hwc_rect_t new_cropL;
- new_cropL.left = new_cropR.right;
- new_cropL.right = tmp_cropR.right;
-
- tmp_cropL.left = new_cropL.left;
- tmp_cropL.right = new_cropL.right;
-
- tmp_cropR.left = new_cropR.left;
- tmp_cropR.right = new_cropR.right;
-
- }
-
- //For the mdp, since either we are pre-rotating or MDP does flips
- orient = OVERLAY_TRANSFORM_0;
- transform = 0;
-
- //configure left half
- if(lDest != OV_INVALID) {
- PipeArgs pargL(mdpFlagsL, whf, lz,
- static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
- (ovutils::eBlending) getBlending(layer->blending));
-
- if(configMdp(ctx->mOverlay, pargL, orient,
- tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
- ALOGE("%s: commit failed for left half config", __FUNCTION__);
- return -1;
- }
- }
-
- //configure right half
- if(rDest != OV_INVALID) {
- PipeArgs pargR(mdpFlagsR, whf, rz,
- static_cast<eRotFlags>(rotFlags),
- layer->planeAlpha,
- (ovutils::eBlending) getBlending(layer->blending));
- if(configMdp(ctx->mOverlay, pargR, orient,
- tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
- ALOGE("%s: commit failed for right half config", __FUNCTION__);
- return -1;
- }
- }
-
- return 0;
-}
-
-bool canUseRotator(hwc_context_t *ctx, int dpy) {
- if(ctx->mOverlay->isDMAMultiplexingSupported() &&
- isSecondaryConnected(ctx) &&
- !ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause) {
- /* mdss driver on certain targets support multiplexing of DMA pipe
- * in LINE and BLOCK modes for writeback panels.
- */
- if(dpy == HWC_DISPLAY_PRIMARY)
- return false;
- }
- if((ctx->mMDP.version == qdutils::MDP_V3_0_4)
- ||(ctx->mMDP.version == qdutils::MDP_V3_0_5))
- return false;
- return true;
-}
-
-int getLeftSplit(hwc_context_t *ctx, const int& dpy) {
- //Default even split for all displays with high res
- int lSplit = ctx->dpyAttr[dpy].xres / 2;
- if(dpy == HWC_DISPLAY_PRIMARY &&
- qdutils::MDPVersion::getInstance().getLeftSplit()) {
- //Override if split published by driver for primary
- lSplit = qdutils::MDPVersion::getInstance().getLeftSplit();
- }
- return lSplit;
-}
-
-bool isDisplaySplit(hwc_context_t* ctx, int dpy) {
- qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
- if(ctx->dpyAttr[dpy].xres > mdpHw.getMaxMixerWidth()) {
- return true;
- }
- //For testing we could split primary via device tree values
- if(dpy == HWC_DISPLAY_PRIMARY && mdpHw.getRightSplit()) {
- return true;
- }
- return false;
-}
-
-//clear prev layer prop flags and realloc for current frame
-void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
- if(ctx->layerProp[dpy]) {
- delete[] ctx->layerProp[dpy];
- ctx->layerProp[dpy] = NULL;
- }
- ctx->layerProp[dpy] = new LayerProp[numAppLayers];
-}
-
-bool isAbcInUse(hwc_context_t *ctx){
- return (ctx->enableABC && ctx->listStats[0].renderBufIndexforABC == 0);
-}
-
-void dumpBuffer(private_handle_t *ohnd, char *bufferName) {
- if (ohnd != NULL && ohnd->base) {
- char dumpFilename[PATH_MAX];
- bool bResult = false;
- int width = getWidth(ohnd);
- int height = getHeight(ohnd);
- int format = ohnd->format;
- //dummy aligned w & h.
- int alW = 0, alH = 0;
- int size = getBufferSizeAndDimensions(width, height, format, alW, alH);
- snprintf(dumpFilename, sizeof(dumpFilename), "/data/%s.%s.%dx%d.raw",
- bufferName,
- overlay::utils::getFormatString(utils::getMdpFormat(format)),
- width, height);
- FILE* fp = fopen(dumpFilename, "w+");
- if (NULL != fp) {
- bResult = (bool) fwrite((void*)ohnd->base, size, 1, fp);
- fclose(fp);
- }
- ALOGD("Buffer[%s] Dump to %s: %s",
- bufferName, dumpFilename, bResult ? "Success" : "Fail");
- }
-}
-
-bool isGLESComp(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
- for(int index = 0; index < numAppLayers; index++) {
- hwc_layer_1_t* layer = &(list->hwLayers[index]);
- if(layer->compositionType == HWC_FRAMEBUFFER)
- return true;
- }
- return false;
-}
-
-void setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
-#ifdef QTI_BSP
- struct gpu_hint_info *gpuHint = &ctx->mGPUHintInfo;
- if(!gpuHint->mGpuPerfModeEnable || !ctx || !list)
- return;
-
- /* Set the GPU hint flag to high for MIXED/GPU composition only for
- first frame after MDP -> GPU/MIXED mode transition. Set the GPU
- hint to default if the previous composition is GPU or current GPU
- composition is due to idle fallback */
- if(!gpuHint->mEGLDisplay || !gpuHint->mEGLContext) {
- gpuHint->mEGLDisplay = (*(ctx->mpfn_eglGetCurrentDisplay))();
- if(!gpuHint->mEGLDisplay) {
- ALOGW("%s Warning: EGL current display is NULL", __FUNCTION__);
- return;
- }
- gpuHint->mEGLContext = (*(ctx->mpfn_eglGetCurrentContext))();
- if(!gpuHint->mEGLContext) {
- ALOGW("%s Warning: EGL current context is NULL", __FUNCTION__);
- return;
- }
- }
- if(isGLESComp(ctx, list)) {
- if(gpuHint->mCompositionState != COMPOSITION_STATE_GPU
- && !MDPComp::isIdleFallback()) {
- EGLint attr_list[] = {EGL_GPU_HINT_1,
- EGL_GPU_LEVEL_3,
- EGL_NONE };
- if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_3) &&
- !((*(ctx->mpfn_eglGpuPerfHintQCOM))(gpuHint->mEGLDisplay,
- gpuHint->mEGLContext, attr_list))) {
- ALOGW("eglGpuPerfHintQCOM failed for Built in display");
- } else {
- gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_3;
- gpuHint->mCompositionState = COMPOSITION_STATE_GPU;
- }
- } else {
- EGLint attr_list[] = {EGL_GPU_HINT_1,
- EGL_GPU_LEVEL_0,
- EGL_NONE };
- if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
- !((*(ctx->mpfn_eglGpuPerfHintQCOM))(gpuHint->mEGLDisplay,
- gpuHint->mEGLContext, attr_list))) {
- ALOGW("eglGpuPerfHintQCOM failed for Built in display");
- } else {
- gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
- }
- if(MDPComp::isIdleFallback()) {
- gpuHint->mCompositionState = COMPOSITION_STATE_IDLE_FALLBACK;
- }
- }
- } else {
- /* set the GPU hint flag to default for MDP composition */
- EGLint attr_list[] = {EGL_GPU_HINT_1,
- EGL_GPU_LEVEL_0,
- EGL_NONE };
- if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
- !((*(ctx->mpfn_eglGpuPerfHintQCOM))(gpuHint->mEGLDisplay,
- gpuHint->mEGLContext, attr_list))) {
- ALOGW("eglGpuPerfHintQCOM failed for Built in display");
- } else {
- gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
- }
- gpuHint->mCompositionState = COMPOSITION_STATE_MDP;
- }
-#else
- (void) ctx;
- (void) list;
-#endif
-}
-
-bool isPeripheral(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
- // To be peripheral, 3 boundaries should match.
- uint8_t eqBounds = 0;
- if (rect1.left == rect2.left)
- eqBounds++;
- if (rect1.top == rect2.top)
- eqBounds++;
- if (rect1.right == rect2.right)
- eqBounds++;
- if (rect1.bottom == rect2.bottom)
- eqBounds++;
- return (eqBounds == 3);
-}
-
-void processBootAnimCompleted(hwc_context_t *ctx) {
- char value[PROPERTY_VALUE_MAX];
-
- // Applying default mode after bootanimation is finished
- property_get("init.svc.bootanim", value, "running");
-
- if (!strncmp(value,"stopped",strlen("stopped"))) {
- ctx->mBootAnimCompleted = true;
-
- //one-shot action check if bootanimation completed then apply
- //default display mode.
- qdcmApplyDefaultAfterBootAnimationDone(ctx);
- }
-}
-
-void BwcPM::setBwc(const hwc_rect_t& crop, const hwc_rect_t& dst,
- const int& transform,const int& downscale,
- ovutils::eMdpFlags& mdpFlags) {
- //BWC not supported with rot-downscale
- if(downscale) return;
-
- //Target doesnt support Bwc
- qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
- if(!mdpHw.supportsBWC()) {
- return;
- }
- int src_w = crop.right - crop.left;
- int src_h = crop.bottom - crop.top;
- int dst_w = dst.right - dst.left;
- int dst_h = dst.bottom - dst.top;
- if(transform & HAL_TRANSFORM_ROT_90) {
- swap(src_w, src_h);
- }
- //src width > MAX mixer supported dim
- if(src_w > (int) qdutils::MDPVersion::getInstance().getMaxMixerWidth()) {
- return;
- }
- //Decimation necessary, cannot use BWC. H/W requirement.
- if(qdutils::MDPVersion::getInstance().supportsDecimation()) {
- uint8_t horzDeci = 0;
- uint8_t vertDeci = 0;
- ovutils::getDecimationFactor(src_w, src_h, dst_w, dst_h, horzDeci,
- vertDeci);
- if(horzDeci || vertDeci) return;
- }
- //Property
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.disable.bwc", value, "0");
- if(atoi(value)) return;
-
- ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDSS_MDP_BWC_EN);
-}
-
-void LayerRotMap::add(hwc_layer_1_t* layer, Rotator *rot) {
- if(mCount >= RotMgr::MAX_ROT_SESS) return;
- mLayer[mCount] = layer;
- mRot[mCount] = rot;
- mCount++;
-}
-
-void LayerRotMap::reset() {
- for (int i = 0; i < RotMgr::MAX_ROT_SESS; i++) {
- mLayer[i] = 0;
- mRot[i] = 0;
- }
- mCount = 0;
-}
-
-void LayerRotMap::clear() {
- RotMgr::getInstance()->markUnusedTop(mCount);
- reset();
-}
-
-bool LayerRotMap::isRotCached(uint32_t index) const {
- overlay::Rotator* rot = getRot(index);
- hwc_layer_1_t* layer = getLayer(index);
-
- if(rot and layer and layer->handle) {
- private_handle_t *hnd = (private_handle_t *)(layer->handle);
- return (rot->isRotCached(hnd->fd,(uint32_t)(hnd->offset)));
- }
- return false;
-}
-
-void LayerRotMap::setReleaseFd(const int& fence) {
- for(uint32_t i = 0; i < mCount; i++) {
- if(mRot[i] and mLayer[i] and mLayer[i]->handle) {
- /* Ensure that none of the above (Rotator-instance,
- * layer and layer-handle) are NULL*/
- if(isRotCached(i))
- mRot[i]->setPrevBufReleaseFd(dup(fence));
- else
- mRot[i]->setCurrBufReleaseFd(dup(fence));
- }
- }
-}
-
-void resetROI(hwc_context_t *ctx, const int dpy) {
- const int fbXRes = (int)ctx->dpyAttr[dpy].xres;
- const int fbYRes = (int)ctx->dpyAttr[dpy].yres;
- if(isDisplaySplit(ctx, dpy)) {
- const int lSplit = getLeftSplit(ctx, dpy);
- ctx->listStats[dpy].lRoi = (struct hwc_rect){0, 0, lSplit, fbYRes};
- ctx->listStats[dpy].rRoi = (struct hwc_rect){lSplit, 0, fbXRes, fbYRes};
- } else {
- ctx->listStats[dpy].lRoi = (struct hwc_rect){0, 0,fbXRes, fbYRes};
- ctx->listStats[dpy].rRoi = (struct hwc_rect){0, 0, 0, 0};
- }
-}
-
-hwc_rect_t getSanitizeROI(struct hwc_rect roi, hwc_rect boundary)
-{
- if(!isValidRect(roi))
- return roi;
-
- struct hwc_rect t_roi = roi;
-
- const int LEFT_ALIGN = qdutils::MDPVersion::getInstance().getLeftAlign();
- const int WIDTH_ALIGN = qdutils::MDPVersion::getInstance().getWidthAlign();
- const int TOP_ALIGN = qdutils::MDPVersion::getInstance().getTopAlign();
- const int HEIGHT_ALIGN = qdutils::MDPVersion::getInstance().getHeightAlign();
- const int MIN_WIDTH = qdutils::MDPVersion::getInstance().getMinROIWidth();
- const int MIN_HEIGHT = qdutils::MDPVersion::getInstance().getMinROIHeight();
-
- /* Align to minimum width recommended by the panel */
- if((t_roi.right - t_roi.left) < MIN_WIDTH) {
- if((t_roi.left + MIN_WIDTH) > boundary.right)
- t_roi.left = t_roi.right - MIN_WIDTH;
- else
- t_roi.right = t_roi.left + MIN_WIDTH;
- }
-
- /* Align to minimum height recommended by the panel */
- if((t_roi.bottom - t_roi.top) < MIN_HEIGHT) {
- if((t_roi.top + MIN_HEIGHT) > boundary.bottom)
- t_roi.top = t_roi.bottom - MIN_HEIGHT;
- else
- t_roi.bottom = t_roi.top + MIN_HEIGHT;
- }
-
- /* Align left and width to meet panel restrictions */
- if(LEFT_ALIGN)
- t_roi.left = t_roi.left - (t_roi.left % LEFT_ALIGN);
-
- if(WIDTH_ALIGN) {
- int width = t_roi.right - t_roi.left;
- width = WIDTH_ALIGN * ((width + (WIDTH_ALIGN - 1)) / WIDTH_ALIGN);
- t_roi.right = t_roi.left + width;
-
- if(t_roi.right > boundary.right) {
- t_roi.right = boundary.right;
- t_roi.left = t_roi.right - width;
-
- if(LEFT_ALIGN)
- t_roi.left = t_roi.left - (t_roi.left % LEFT_ALIGN);
- }
- }
-
-
- /* Align top and height to meet panel restrictions */
- if(TOP_ALIGN)
- t_roi.top = t_roi.top - (t_roi.top % TOP_ALIGN);
-
- if(HEIGHT_ALIGN) {
- int height = t_roi.bottom - t_roi.top;
- height = HEIGHT_ALIGN * ((height + (HEIGHT_ALIGN - 1)) / HEIGHT_ALIGN);
- t_roi.bottom = t_roi.top + height;
-
- if(t_roi.bottom > boundary.bottom) {
- t_roi.bottom = boundary.bottom;
- t_roi.top = t_roi.bottom - height;
-
- if(TOP_ALIGN)
- t_roi.top = t_roi.top - (t_roi.top % TOP_ALIGN);
- }
- }
-
-
- return t_roi;
-}
-
-void handle_pause(hwc_context_t* ctx, int dpy) {
- if(ctx->dpyAttr[dpy].connected) {
- ctx->mDrawLock.lock();
- ctx->dpyAttr[dpy].isActive = true;
- ctx->dpyAttr[dpy].isPause = true;
- ctx->mDrawLock.unlock();
- ctx->proc->invalidate(ctx->proc);
-
- usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
- * 2 / 1000);
-
- // At this point all the pipes used by External have been
- // marked as UNSET.
- ctx->mDrawLock.lock();
- // Perform commit to unstage the pipes.
- if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
- ALOGE("%s: display commit fail! for %d dpy",
- __FUNCTION__, dpy);
- }
- ctx->mDrawLock.unlock();
- ctx->proc->invalidate(ctx->proc);
- }
- return;
-}
-
-void handle_resume(hwc_context_t* ctx, int dpy) {
- if(ctx->dpyAttr[dpy].connected) {
- ctx->mDrawLock.lock();
- ctx->dpyAttr[dpy].isConfiguring = true;
- ctx->dpyAttr[dpy].isActive = true;
- ctx->mDrawLock.unlock();
- ctx->proc->invalidate(ctx->proc);
-
- usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
- * 2 / 1000);
-
- //At this point external has all the pipes it would need.
- ctx->mDrawLock.lock();
- ctx->dpyAttr[dpy].isPause = false;
- ctx->mDrawLock.unlock();
- ctx->proc->invalidate(ctx->proc);
- }
- return;
-}
-
-void clearPipeResources(hwc_context_t* ctx, int dpy) {
- if(ctx->mOverlay) {
- ctx->mOverlay->configBegin();
- ctx->mOverlay->configDone();
- }
- if(ctx->mRotMgr) {
- ctx->mRotMgr->clear();
- }
- // Call a display commit to ensure that pipes and associated
- // fd's are cleaned up.
- if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
- ALOGE("%s: display commit failed for %d", __FUNCTION__, dpy);
- }
-}
-
-// Handles online events when HDMI is the primary display. In particular,
-// online events for hdmi connected before AND after boot up and HWC init.
-void handle_online(hwc_context_t* ctx, int dpy) {
- // Close the current fd if it was opened earlier on when HWC
- // was initialized.
- if (ctx->dpyAttr[dpy].fd >= 0) {
- close(ctx->dpyAttr[dpy].fd);
- ctx->dpyAttr[dpy].fd = -1;
- }
- // TODO: If HDMI is connected after the display has booted up,
- // and the best configuration is different from the default
- // then we need to deal with this appropriately.
- ctx->mHDMIDisplay->configure();
- updateDisplayInfo(ctx, dpy);
- initCompositionResources(ctx, dpy);
- ctx->dpyAttr[dpy].connected = true;
-}
-
-// Handles offline events for HDMI. This can be used for offline events
-// initiated by the HDMI driver and the CEC framework.
-void handle_offline(hwc_context_t* ctx, int dpy) {
- destroyCompositionResources(ctx, dpy);
- // Clear all pipe resources and call a display commit to ensure
- // that all the fd's are closed. This will ensure that the HDMI
- // core turns off and that we receive an event the next time the
- // cable is connected.
- if (ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
- clearPipeResources(ctx, dpy);
- }
- ctx->mHDMIDisplay->teardown();
- resetDisplayInfo(ctx, dpy);
- ctx->dpyAttr[dpy].connected = false;
- ctx->dpyAttr[dpy].isActive = false;
-}
-
-bool loadEglLib(hwc_context_t* ctx) {
- bool success = false;
-#ifdef QTI_BSP
- dlerror();
-
- ctx->mEglLib = dlopen("libEGL_adreno.so", RTLD_NOW);
- if(ctx->mEglLib) {
- *(void **)&(ctx->mpfn_eglGpuPerfHintQCOM) = dlsym(ctx->mEglLib, "eglGpuPerfHintQCOM");
- *(void **)&(ctx->mpfn_eglGetCurrentDisplay) = dlsym(ctx->mEglLib,"eglGetCurrentDisplay");
- *(void **)&(ctx->mpfn_eglGetCurrentContext) = dlsym(ctx->mEglLib,"eglGetCurrentContext");
- if (!ctx->mpfn_eglGpuPerfHintQCOM ||
- !ctx->mpfn_eglGetCurrentDisplay ||
- !ctx->mpfn_eglGetCurrentContext) {
- ALOGE("Failed to load symbols from libEGL");
- dlclose(ctx->mEglLib);
- ctx->mEglLib = NULL;
- return false;
- }
- success = true;
- ALOGI("Successfully Loaded GPUPerfHint APIs");
- } else {
- ALOGE("Couldn't load libEGL: %s", dlerror());
- }
-#else
- (void) ctx;
-#endif
- return success;
-}
-
-};//namespace qhwc
diff --git a/msm8909/libhwcomposer/hwc_utils.h b/msm8909/libhwcomposer/hwc_utils.h
deleted file mode 100644
index 0b824af..0000000
--- a/msm8909/libhwcomposer/hwc_utils.h
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C)2012-2016, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 HWC_UTILS_H
-#define HWC_UTILS_H
-
-#define DEBUG_MDPDOWNSCALE 0
-#define HWC_REMOVE_DEPRECATED_VERSIONS 1
-
-#include <fcntl.h>
-#include <math.h>
-#include <hardware/hwcomposer.h>
-#include <gr.h>
-#include <gralloc_priv.h>
-#include <utils/String8.h>
-#include "qdMetaData.h"
-#include "mdp_version.h"
-#include <overlayUtils.h>
-#include <overlayRotator.h>
-#include <EGL/egl.h>
-
-
-#define ALIGN_TO(x, align) (((x) + ((align)-1)) & ~((align)-1))
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-#define MAX_NUM_APP_LAYERS 32
-#define MIN_DISPLAY_XRES 200
-#define MIN_DISPLAY_YRES 200
-#define HWC_WFDDISPSYNC_LOG 0
-#define STR(f) #f;
-// Max number of PTOR layers handled
-#define MAX_PTOR_LAYERS 2
-
-#ifdef QTI_BSP
-#include <exhwcomposer_defs.h>
-#endif
-
-//Fwrd decls
-struct hwc_context_t;
-
-namespace ovutils = overlay::utils;
-
-namespace qmode {
-class ModeManager;
-}
-
-namespace overlay {
-class Overlay;
-class Rotator;
-class RotMgr;
-}
-
-namespace qhwc {
-//fwrd decl
-class QueuedBufferStore;
-class HDMIDisplay;
-class VirtualDisplay;
-class IFBUpdate;
-class IVideoOverlay;
-class MDPComp;
-class CopyBit;
-class HwcDebug;
-class AssertiveDisplay;
-class HWCVirtualVDS;
-
-
-struct MDPInfo {
- int version;
- char panel;
- bool hasOverlay;
-};
-
-struct DisplayAttributes {
- uint32_t refreshRate;
- uint32_t dynRefreshRate;
- uint32_t vsync_period; //nanos
- uint32_t xres;
- uint32_t yres;
- uint32_t stride;
- float xdpi;
- float ydpi;
- uint32_t fbformat;
- int fd;
- bool connected; //Applies only to pluggable disp.
- //Connected does not mean it ready to use.
- //It should be active also. (UNBLANKED)
- bool isActive;
- // In pause state, composition is bypassed
- // used for WFD displays and in QDCM calibration mode
- bool isPause;
- // To trigger padding round to clean up mdp
- // pipes
- bool isConfiguring;
- // Indicates whether external/virtual display is in MDP scaling mode
- bool mMDPScalingMode;
- // Ext dst Rect
- hwc_rect_t mDstRect;
- //Action safe attributes
- // Flag to indicate the presence of action safe dimensions for external
- bool mActionSafePresent;
- int mAsWidthRatio;
- int mAsHeightRatio;
-
- //If property fbsize set via adb shell debug.hwc.fbsize = XRESxYRES
- //following fields are used.
- bool customFBSize;
- uint32_t xres_new;
- uint32_t yres_new;
-
-};
-
-struct ListStats {
- int numAppLayers; //Total - 1, excluding FB layer.
- int skipCount;
- int fbLayerIndex; //Always last for now. = numAppLayers
- //Video specific
- int yuvCount;
- int yuvIndices[MAX_NUM_APP_LAYERS];
- bool preMultipliedAlpha;
- int yuv4k2kIndices[MAX_NUM_APP_LAYERS];
- int yuv4k2kCount;
- // Notifies hwcomposer about the start and end of animation
- // This will be set to true during animation, otherwise false.
- bool isDisplayAnimating;
- bool secureUI; // Secure display layer
- bool isSecurePresent;
- hwc_rect_t lRoi; //left ROI
- hwc_rect_t rRoi; //right ROI. Unused in single DSI panels.
- //App Buffer Composition index
- int renderBufIndexforABC;
- // Secure RGB specific
- int secureRGBCount;
- int secureRGBIndices[MAX_NUM_APP_LAYERS];
- //dyn refresh rate-Client requested refreshrate
- uint32_t refreshRateRequest;
- // Flag related to windowboxing feature
- bool mAIVVideoMode;
-};
-
-//PTOR Comp info
-struct PtorInfo {
- int count;
- int layerIndex[MAX_PTOR_LAYERS];
- hwc_rect_t displayFrame[MAX_PTOR_LAYERS];
- bool isActive() { return (count>0); }
- int getPTORArrayIndex(int index) {
- int idx = -1;
- for(int i = 0; i < count; i++) {
- if(index == layerIndex[i])
- idx = i;
- }
- return idx;
- }
-};
-
-struct LayerProp {
- uint32_t mFlags; //qcom specific layer flags
- LayerProp():mFlags(0){};
-};
-
-struct VsyncState {
- bool enable;
- bool fakevsync;
- bool debug;
-};
-
-struct BwcPM {
- static void setBwc(const hwc_rect_t& crop, const hwc_rect_t& dst,
- const int& transform, const int& downscale,
- ovutils::eMdpFlags& mdpFlags);
-};
-
-// LayerProp::flag values
-enum {
- HWC_MDPCOMP = 0x00000001,
- HWC_COPYBIT = 0x00000002,
-};
-
-// AIV specific flags
-enum {
- HWC_AIV_VIDEO = 0x80000000,
- HWC_AIV_CC = 0x40000000,
-};
-
-// HAL specific features
-enum {
- HWC_COLOR_FILL = 0x00000008,
- HWC_FORMAT_RB_SWAP = 0x00000040,
-};
-
-/* External Display states */
-enum {
- EXTERNAL_OFFLINE = 0,
- EXTERNAL_ONLINE,
- EXTERNAL_PAUSE,
- EXTERNAL_RESUME,
- EXTERNAL_MAXSTATES
-};
-
-class LayerRotMap {
-public:
- LayerRotMap() { reset(); }
- void add(hwc_layer_1_t* layer, overlay::Rotator *rot);
- //Resets the mapping of layer to rotator
- void reset();
- //Clears mappings and existing rotator fences
- //Intended to be used during errors
- void clear();
- uint32_t getCount() const;
- hwc_layer_1_t* getLayer(uint32_t index) const;
- overlay::Rotator* getRot(uint32_t index) const;
- bool isRotCached(uint32_t index) const;
- void setReleaseFd(const int& fence);
-private:
- hwc_layer_1_t* mLayer[overlay::RotMgr::MAX_ROT_SESS];
- overlay::Rotator* mRot[overlay::RotMgr::MAX_ROT_SESS];
- uint32_t mCount;
-};
-
-inline uint32_t LayerRotMap::getCount() const {
- return mCount;
-}
-
-inline hwc_layer_1_t* LayerRotMap::getLayer(uint32_t index) const {
- if(index >= mCount) return NULL;
- return mLayer[index];
-}
-
-inline overlay::Rotator* LayerRotMap::getRot(uint32_t index) const {
- if(index >= mCount) return NULL;
- return mRot[index];
-}
-
-inline hwc_rect_t integerizeSourceCrop(const hwc_frect_t& cropF) {
- hwc_rect_t cropI = {0,0,0,0};
- cropI.left = int(ceilf(cropF.left));
- cropI.top = int(ceilf(cropF.top));
- cropI.right = int(floorf(cropF.right));
- cropI.bottom = int(floorf(cropF.bottom));
- return cropI;
-}
-
-inline bool isNonIntegralSourceCrop(const hwc_frect_t& cropF) {
- if(cropF.left - roundf(cropF.left) ||
- cropF.top - roundf(cropF.top) ||
- cropF.right - roundf(cropF.right) ||
- cropF.bottom - roundf(cropF.bottom))
- return true;
- else
- return false;
-}
-
-// -----------------------------------------------------------------------------
-// Utility functions - implemented in hwc_utils.cpp
-void dumpLayer(hwc_layer_1_t const* l);
-void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
- int dpy);
-void initContext(hwc_context_t *ctx);
-void closeContext(hwc_context_t *ctx);
-//Crops source buffer against destination and FB boundaries
-void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
- const hwc_rect_t& scissor, int orient);
-void getNonWormholeRegion(hwc_display_contents_1_t* list,
- hwc_rect_t& nwr);
-bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
-bool isSecureModePolicy(int mdpVersion);
-// Returns true, if the input layer format is supported by rotator
-bool isRotatorSupportedFormat(private_handle_t *hnd);
-//Returns true, if the layer is YUV or the layer has been rendered by CPU
-bool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd);
-bool isExternalActive(hwc_context_t* ctx);
-bool isAlphaScaled(hwc_layer_1_t const* layer);
-bool needsScaling(hwc_layer_1_t const* layer);
-bool isDownscaleRequired(hwc_layer_1_t const* layer);
-bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
- const int& dpy);
-void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
- private_handle_t *hnd);
-bool isAlphaPresent(hwc_layer_1_t const* layer);
-bool isAlphaPresentinFB(hwc_context_t* ctx, int dpy);
-int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
-int getBlending(int blending);
-bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy);
-void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers);
-bool isAbcInUse(hwc_context_t *ctx);
-
-void dumpBuffer(private_handle_t *ohnd, char *bufferName);
-void updateDisplayInfo(hwc_context_t* ctx, int dpy);
-void resetDisplayInfo(hwc_context_t* ctx, int dpy);
-void initCompositionResources(hwc_context_t* ctx, int dpy);
-void destroyCompositionResources(hwc_context_t* ctx, int dpy);
-void clearPipeResources(hwc_context_t* ctx, int dpy);
-
-//Helper function to dump logs
-void dumpsys_log(android::String8& buf, const char* fmt, ...);
-
-int getExtOrientation(hwc_context_t* ctx);
-bool isValidRect(const hwc_rect_t& rect);
-hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
-bool isSameRect(const hwc_rect& rect1, const hwc_rect& rect2);
-hwc_rect_t moveRect(const hwc_rect_t& rect, const int& x_off, const int& y_off);
-hwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
-hwc_rect_t getUnion(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
-void optimizeLayerRects(const hwc_display_contents_1_t *list);
-bool areLayersIntersecting(const hwc_layer_1_t* layer1,
- const hwc_layer_1_t* layer2);
-bool operator ==(const hwc_rect_t& lhs, const hwc_rect_t& rhs);
-bool layerUpdating(const hwc_layer_1_t* layer);
-/* Calculates the dirtyRegion for the given layer */
-hwc_rect_t calculateDirtyRect(const hwc_layer_1_t* layer,
- hwc_rect_t& scissor);
-
-
-// returns true if Action safe dimensions are set and target supports Actionsafe
-bool isActionSafePresent(hwc_context_t *ctx, int dpy);
-
-/* Calculates the destination position based on the action safe rectangle */
-void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& dst);
-
-void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
- hwc_rect_t& inRect, hwc_rect_t& outRect);
-
-uint32_t getRefreshRate(hwc_context_t* ctx, uint32_t requestedRefreshRate);
-
-uint32_t roundOff(uint32_t refreshRate);
-
-void setRefreshRate(hwc_context_t *ctx, int dpy, uint32_t refreshRate);
-
-bool isPrimaryPortrait(hwc_context_t *ctx);
-
-bool isOrientationPortrait(hwc_context_t *ctx);
-
-void calcExtDisplayPosition(hwc_context_t *ctx,
- private_handle_t *hnd,
- int dpy,
- hwc_rect_t& sourceCrop,
- hwc_rect_t& displayFrame,
- int& transform,
- ovutils::eTransform& orient);
-
-// Returns the orientation that needs to be set on external for
-// BufferMirrirMode(Sidesync)
-int getMirrorModeOrientation(hwc_context_t *ctx);
-
-/* Get External State names */
-const char* getExternalDisplayState(uint32_t external_state);
-
-// Resets display ROI to full panel resoluion
-void resetROI(hwc_context_t *ctx, const int dpy);
-
-// Aligns updating ROI to panel restrictions
-hwc_rect_t getSanitizeROI(struct hwc_rect roi, hwc_rect boundary);
-
-// Handles wfd Pause and resume events
-void handle_pause(hwc_context_t *ctx, int dpy);
-void handle_resume(hwc_context_t *ctx, int dpy);
-
-// Handle ONLINE/OFFLINE for HDMI display
-void handle_online(hwc_context_t* ctx, int dpy);
-void handle_offline(hwc_context_t* ctx, int dpy);
-
-//Close acquireFenceFds of all layers of incoming list
-void closeAcquireFds(hwc_display_contents_1_t* list);
-
-//Sync point impl.
-int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
- int fd);
-
-//Sets appropriate mdp flags for a layer.
-void setMdpFlags(hwc_context_t *ctx, hwc_layer_1_t *layer,
- ovutils::eMdpFlags &mdpFlags,
- int rotDownscale, int transform);
-
-int configRotator(overlay::Rotator *rot, ovutils::Whf& whf,
- hwc_rect_t& crop, const ovutils::eMdpFlags& mdpFlags,
- const ovutils::eTransform& orient, const int& downscale);
-
-int configMdp(overlay::Overlay *ov, const ovutils::PipeArgs& parg,
- const ovutils::eTransform& orient, const hwc_rect_t& crop,
- const hwc_rect_t& pos, const MetaData_t *metadata,
- const ovutils::eDest& dest);
-
-int configColorLayer(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
- ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
- const ovutils::eDest& dest);
-
-void updateSource(ovutils::eTransform& orient, ovutils::Whf& whf,
- hwc_rect_t& crop, overlay::Rotator *rot);
-
-bool isZoomModeEnabled(hwc_rect_t crop);
-void updateCropAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& crop, int dpy);
-void updateDestAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& dst, int dpy);
-void updateCoordinates(hwc_context_t *ctx, hwc_rect_t& crop,
- hwc_rect_t& dst, int dpy);
-
-//Routine to configure low resolution panels (<= 2048 width)
-int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
- ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
- const ovutils::eDest& dest,
- overlay::Rotator **rot);
-
-//Routine to configure high resolution panels (> 2048 width)
-int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
- ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
- const ovutils::eDest& lDest,
- const ovutils::eDest& rDest, overlay::Rotator **rot);
-
-//Routine to split and configure high resolution YUV layer (> 2048 width)
-int configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
- const int& dpy,
- ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
- const ovutils::eDest& lDest,
- const ovutils::eDest& rDest, overlay::Rotator **rot);
-
-//On certain targets DMA pipes are used for rotation and they won't be available
-//for line operations. On a per-target basis we can restrict certain use cases
-//from using rotator, since we know before-hand that such scenarios can lead to
-//extreme unavailability of pipes. This can also be done via hybrid calculations
-//also involving many more variables like number of write-back interfaces etc,
-//but the variety of scenarios is too high to warrant that.
-bool canUseRotator(hwc_context_t *ctx, int dpy);
-
-int getLeftSplit(hwc_context_t *ctx, const int& dpy);
-
-bool isDisplaySplit(hwc_context_t* ctx, int dpy);
-
-int getRotDownscale(hwc_context_t *ctx, const hwc_layer_1_t *layer);
-
-// Set the GPU hint flag to high for MIXED/GPU composition only for
-// first frame after MDP to GPU/MIXED mode transition.
-// Set the GPU hint to default if the current composition type is GPU
-// due to idle fallback or MDP composition.
-void setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list);
-
-bool loadEglLib(hwc_context_t* ctx);
-
-// Returns true if rect1 is peripheral to rect2, false otherwise.
-bool isPeripheral(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
-
-// Checks if boot animation has completed and applies default mode
-void processBootAnimCompleted(hwc_context_t *ctx);
-
-// Inline utility functions
-static inline bool isSkipLayer(const hwc_layer_1_t* l) {
- return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
-}
-
-static inline bool isAIVVideoLayer(const hwc_layer_1_t* l) {
- return (UNLIKELY(l && (l->flags & HWC_AIV_VIDEO)));
-}
-
-static inline bool isAIVCCLayer(const hwc_layer_1_t* l) {
- return (UNLIKELY(l && (l->flags & HWC_AIV_CC)));
-}
-
-// Returns true if the buffer is yuv
-static inline bool isYuvBuffer(const private_handle_t* hnd) {
- return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO));
-}
-
-// Returns true if the buffer is yuv and exceeds the mixer width
-static inline bool isYUVSplitNeeded(const private_handle_t* hnd) {
- int maxMixerWidth = qdutils::MDPVersion::getInstance().getMaxMixerWidth();
- return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) &&
- (hnd->width > maxMixerWidth));
-}
-
-// Returns true if the buffer is secure
-static inline bool isSecureBuffer(const private_handle_t* hnd) {
- return (hnd && (private_handle_t::PRIV_FLAGS_SECURE_BUFFER & hnd->flags));
-}
-
-static inline bool isTileRendered(const private_handle_t* hnd) {
- return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
-}
-
-static inline bool isCPURendered(const private_handle_t* hnd) {
- return (hnd && (private_handle_t::PRIV_FLAGS_CPU_RENDERED & hnd->flags));
-}
-
-//Return true if the buffer is intended for Secure Display
-static inline bool isSecureDisplayBuffer(const private_handle_t* hnd) {
- return (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY));
-}
-
-static inline int getWidth(const private_handle_t* hnd) {
- MetaData_t *metadata = reinterpret_cast<MetaData_t*>(hnd->base_metadata);
- if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
- return metadata->bufferDim.sliceWidth;
- }
- return hnd->width;
-}
-
-static inline int getHeight(const private_handle_t* hnd) {
- MetaData_t *metadata = reinterpret_cast<MetaData_t*>(hnd->base_metadata);
- if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
- return metadata->bufferDim.sliceHeight;
- }
- return hnd->height;
-}
-
-template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; }
-template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; }
-
-// Initialize uevent thread
-void init_uevent_thread(hwc_context_t* ctx);
-// Initialize vsync thread
-void init_vsync_thread(hwc_context_t* ctx);
-
-inline void getLayerResolution(const hwc_layer_1_t* layer,
- int& width, int& height) {
- hwc_rect_t displayFrame = layer->displayFrame;
- width = displayFrame.right - displayFrame.left;
- height = displayFrame.bottom - displayFrame.top;
-}
-
-static inline int openFb(int dpy) {
- int fd = -1;
- const char *devtmpl = "/dev/graphics/fb%u";
- char name[64] = {0};
- snprintf(name, 64, devtmpl, dpy);
- fd = open(name, O_RDWR);
- return fd;
-}
-
-template <class T>
-inline void swap(T& a, T& b) {
- T tmp = a;
- a = b;
- b = tmp;
-}
-
-}; //qhwc namespace
-
-enum eAnimationState{
- ANIMATION_STOPPED,
- ANIMATION_STARTED,
-};
-
-enum eCompositionState {
- COMPOSITION_STATE_MDP = 0, // Set if composition type is MDP
- COMPOSITION_STATE_GPU, // Set if composition type is GPU or MIXED
- COMPOSITION_STATE_IDLE_FALLBACK, // Set if it is idlefallback
-};
-
-// Structure holds the information about the GPU hint.
-struct gpu_hint_info {
- // system level flag to enable gpu_perf_mode
- bool mGpuPerfModeEnable;
- // Stores the current GPU performance mode DEFAULT/HIGH
- uint32_t mCurrGPUPerfMode;
- // Stores the compositon state GPU, MDP or IDLE_FALLBACK
- bool mCompositionState;
- // Stores the EGLContext of current process
- EGLContext mEGLContext;
- // Stores the EGLDisplay of current process
- EGLDisplay mEGLDisplay;
-};
-
-//struct holds the information about libmm-qdcm.so
-struct qdcm_info {
- qmode::ModeManager *mQdcmMode;
- void *mQdcmLib;
- bool mBootAnimCompleted;
-};
-
-// -----------------------------------------------------------------------------
-// HWC context
-// This structure contains overall state
-struct hwc_context_t {
- hwc_composer_device_1_t device;
- const hwc_procs_t* proc;
-
- //CopyBit objects
- qhwc::CopyBit *mCopyBit[HWC_NUM_DISPLAY_TYPES];
-
- //Overlay object - NULL for non overlay devices
- overlay::Overlay *mOverlay;
- //Holds a few rot objects
- overlay::RotMgr *mRotMgr;
-
- //Primary and external FB updater
- qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
- // HDMI display related object. Used to configure/teardown
- // HDMI when it is connected as primary or external.
- qhwc::HDMIDisplay *mHDMIDisplay;
- qhwc::MDPInfo mMDP;
- qhwc::VsyncState vstate;
- qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES];
- qhwc::ListStats listStats[HWC_NUM_DISPLAY_TYPES];
- qhwc::LayerProp *layerProp[HWC_NUM_DISPLAY_TYPES];
- qhwc::MDPComp *mMDPComp[HWC_NUM_DISPLAY_TYPES];
- qhwc::HwcDebug *mHwcDebug[HWC_NUM_DISPLAY_TYPES];
- hwc_rect_t mViewFrame[HWC_NUM_DISPLAY_TYPES];
- qhwc::AssertiveDisplay *mAD;
- eAnimationState mAnimationState[HWC_NUM_DISPLAY_TYPES];
- qhwc::HWCVirtualVDS *mHWCVirtual;
-
- // stores the #numHwLayers of the previous frame
- // for each display device
- int mPrevHwLayerCount[HWC_NUM_DISPLAY_TYPES];
-
- // stores the primary device orientation
- int deviceOrientation;
- //Securing in progress indicator
- bool mSecuring;
- //Display in secure mode indicator
- bool mSecureMode;
- //Lock to protect drawing data structures
- mutable Locker mDrawLock;
- //Drawing round when we use GPU
- bool isPaddingRound;
- // External Orientation
- int mExtOrientation;
- //Flags the transition of a video session
- bool mVideoTransFlag;
- //Used for SideSync feature
- //which overrides the mExtOrientation
- bool mBufferMirrorMode;
- // Used to synchronize between WFD and Display modules
- mutable Locker mWfdSyncLock;
-
- qhwc::LayerRotMap *mLayerRotMap[HWC_NUM_DISPLAY_TYPES];
- // Panel reset flag will be set if BTA check fails
- bool mPanelResetStatus;
- // number of active Displays
- int numActiveDisplays;
-#ifdef QTI_BSP
- void *mEglLib;
- EGLBoolean (*mpfn_eglGpuPerfHintQCOM)(EGLDisplay, EGLContext, EGLint *);
- EGLDisplay (*mpfn_eglGetCurrentDisplay)();
- EGLContext (*mpfn_eglGetCurrentContext)();
- struct gpu_hint_info mGPUHintInfo;
-#endif
- //App Buffer Composition
- bool enableABC;
- // PTOR Info
- qhwc::PtorInfo mPtorInfo;
- //Running in Thermal burst mode
- bool mThermalBurstMode;
- //Layers out of ROI
- bool copybitDrop[MAX_NUM_APP_LAYERS];
- // Flag related to windowboxing feature
- bool mWindowboxFeature;
- // This denotes the tolerance between video layer and external display
- // aspect ratio
- float mAspectRatioToleranceLevel;
- //Used to notify that boot has completed
- bool mBootAnimCompleted;
- // Provides a way for OEM's to disable setting dynfps via metadata.
- bool mUseMetaDataRefreshRate;
- //struct holds the information about display tuning service library.
- struct qdcm_info mQdcmInfo;
-};
-
-namespace qhwc {
-static inline bool isSkipPresent (hwc_context_t *ctx, int dpy) {
- return ctx->listStats[dpy].skipCount;
-}
-
-static inline bool isYuvPresent (hwc_context_t *ctx, int dpy) {
- return ctx->listStats[dpy].yuvCount;
-}
-
-static inline bool has90Transform(hwc_layer_1_t const* layer) {
- return ((layer->transform & HWC_TRANSFORM_ROT_90) &&
- !(layer->flags & HWC_COLOR_FILL));
-}
-
-inline bool isSecurePresent(hwc_context_t *ctx, int dpy) {
- return ctx->listStats[dpy].isSecurePresent;
-}
-
-static inline bool isSecondaryConfiguring(hwc_context_t* ctx) {
- return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isConfiguring ||
- ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isConfiguring);
-}
-
-static inline bool isSecondaryConnected(hwc_context_t* ctx) {
- return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected ||
- ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected);
-}
-
-static inline bool isSecondaryAnimating(hwc_context_t* ctx) {
- return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected &&
- (!ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isPause) &&
- ctx->listStats[HWC_DISPLAY_EXTERNAL].isDisplayAnimating)
- ||
- (ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected &&
- (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause) &&
- ctx->listStats[HWC_DISPLAY_VIRTUAL].isDisplayAnimating);
-}
-
-/* Return Virtual Display connection status */
-static inline bool isVDConnected(hwc_context_t* ctx) {
- return ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected;
-}
-
-};
-
-#endif //HWC_UTILS_H
diff --git a/msm8909/libhwcomposer/hwc_virtual.cpp b/msm8909/libhwcomposer/hwc_virtual.cpp
deleted file mode 100644
index 2bfb5e7..0000000
--- a/msm8909/libhwcomposer/hwc_virtual.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 <fcntl.h>
-#include <errno.h>
-
-#include <cutils/log.h>
-#include <overlayWriteback.h>
-#include "hwc_utils.h"
-#include "hwc_fbupdate.h"
-#include "hwc_mdpcomp.h"
-#include "hwc_dump_layers.h"
-#include "hwc_copybit.h"
-#include "hwc_virtual.h"
-#include "sync/sync.h"
-#include <utils/Trace.h>
-
-#define HWCVIRTUAL_LOG 0
-
-using namespace qhwc;
-using namespace overlay;
-
-bool HWCVirtualVDS::sVDDumpEnabled = false;
-
-void HWCVirtualVDS::init(hwc_context_t *ctx) {
- const int dpy = HWC_DISPLAY_VIRTUAL;
- mScalingWidth = 0, mScalingHeight = 0;
- initCompositionResources(ctx, dpy);
-
- if(ctx->mFBUpdate[dpy])
- ctx->mFBUpdate[dpy]->reset();
- if(ctx->mMDPComp[dpy])
- ctx->mMDPComp[dpy]->reset();
-}
-
-void HWCVirtualVDS::destroy(hwc_context_t *ctx, size_t /*numDisplays*/,
- hwc_display_contents_1_t** displays) {
- int dpy = HWC_DISPLAY_VIRTUAL;
-
- //Cleanup virtual display objs, since there is no explicit disconnect
- if(ctx->dpyAttr[dpy].connected && (displays[dpy] == NULL)) {
- ctx->dpyAttr[dpy].connected = false;
- ctx->dpyAttr[dpy].isPause = false;
-
- destroyCompositionResources(ctx, dpy);
-
- // signal synclock to indicate successful wfd teardown
- ctx->mWfdSyncLock.lock();
- ctx->mWfdSyncLock.signal();
- ctx->mWfdSyncLock.unlock();
- }
-}
-
-int HWCVirtualVDS::prepare(hwc_composer_device_1 *dev,
- hwc_display_contents_1_t *list) {
- ATRACE_CALL();
- //XXX: Fix when framework support is added
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- const int dpy = HWC_DISPLAY_VIRTUAL;
-
- if (list && list->outbuf && list->numHwLayers > 0) {
- reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
- uint32_t last = (uint32_t)list->numHwLayers - 1;
- hwc_layer_1_t *fbLayer = &list->hwLayers[last];
- int fbWidth = 0, fbHeight = 0;
- getLayerResolution(fbLayer, fbWidth, fbHeight);
- ctx->dpyAttr[dpy].xres = fbWidth;
- ctx->dpyAttr[dpy].yres = fbHeight;
-
- if(ctx->dpyAttr[dpy].connected == false) {
- ctx->dpyAttr[dpy].connected = true;
- ctx->dpyAttr[dpy].isPause = false;
- // We set the vsync period to the primary refresh rate, leaving
- // it up to the consumer to decide how fast to consume frames.
- ctx->dpyAttr[dpy].vsync_period
- = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period;
- ctx->dpyAttr[dpy].fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
- init(ctx);
- // Do one padding round for cases where primary has all pipes
- // The virtual composition falls back to GPU in such cases.
- ctx->isPaddingRound = true;
- }
- if(!ctx->dpyAttr[dpy].isPause) {
- ctx->dpyAttr[dpy].isConfiguring = false;
- ctx->dpyAttr[dpy].fd = Writeback::getInstance()->getFbFd();
- private_handle_t *ohnd = (private_handle_t *)list->outbuf;
-
- setMDPScalingMode(ctx, ohnd, dpy);
-
- mScalingWidth = getWidth(ohnd);
- mScalingHeight = getHeight(ohnd);
-
- Writeback::getInstance()->configureDpyInfo(mScalingWidth,
- mScalingHeight);
- setListStats(ctx, list, dpy);
-
- if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
- const int fbZ = 0;
- if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
- {
- ctx->mOverlay->clear(dpy);
- ctx->mLayerRotMap[dpy]->clear();
- }
- }
- } else {
- /* Virtual Display is in Pause state.
- * Mark all application layers as OVERLAY so that
- * GPU will not compose.
- */
- Writeback::getInstance(); //Ensure that WB is active during pause
- for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
- hwc_layer_1_t *layer = &list->hwLayers[i];
- layer->compositionType = HWC_OVERLAY;
- }
- }
- }
- return 0;
-}
-
-int HWCVirtualVDS::set(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
- ATRACE_CALL();
- int ret = 0;
- const int dpy = HWC_DISPLAY_VIRTUAL;
-
- if (list && list->outbuf && list->numHwLayers > 0) {
- uint32_t last = (uint32_t)list->numHwLayers - 1;
- hwc_layer_1_t *fbLayer = &list->hwLayers[last];
-
- if(ctx->dpyAttr[dpy].connected
- && (!ctx->dpyAttr[dpy].isPause))
- {
- private_handle_t *ohnd = (private_handle_t *)list->outbuf;
- int format = ohnd->format;
- if (format == HAL_PIXEL_FORMAT_RGBA_8888)
- format = HAL_PIXEL_FORMAT_RGBX_8888;
- Writeback::getInstance()->setOutputFormat(
- utils::getMdpFormat(format));
-
- // Configure WB secure mode based on output buffer handle
- if(! Writeback::getInstance()->setSecure(isSecureBuffer(ohnd)))
- {
- ALOGE("Failed to set WB secure mode: %d for virtual display",
- isSecureBuffer(ohnd));
- return false;
- }
-
- int fd = -1; //FenceFD from the Copybit
- hwc_sync(ctx, list, dpy, fd);
-
- // Dump the layers for virtual
- if(ctx->mHwcDebug[dpy])
- ctx->mHwcDebug[dpy]->dumpLayers(list);
-
- if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
- ALOGE("%s: MDPComp draw failed", __FUNCTION__);
- ret = -1;
- }
- // We need an FB layer handle check to cater for this usecase:
- // Video is playing in landscape on primary, then launch
- // ScreenRecord app.
- // In this scenario, the first VDS draw call will have HWC
- // composition and VDS does nit involve GPU to get eglSwapBuffer
- // to get valid fb handle.
- if (fbLayer->handle && !ctx->mFBUpdate[dpy]->draw(ctx,
- (private_handle_t *)fbLayer->handle)) {
- ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
- ret = -1;
- }
-
- Writeback::getInstance()->queueBuffer(ohnd->fd,
- (uint32_t)ohnd->offset);
- if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
- ALOGE("%s: display commit fail!", __FUNCTION__);
- ret = -1;
- }
-
- if(sVDDumpEnabled) {
- char bufferName[128];
- // Dumping frame buffer
- sync_wait(fbLayer->acquireFenceFd, 1000);
- snprintf(bufferName, sizeof(bufferName), "vds.fb");
- dumpBuffer((private_handle_t *)fbLayer->handle, bufferName);
- // Dumping WB output for non-secure session
- if(!isSecureBuffer(ohnd)) {
- sync_wait(list->retireFenceFd, 1000);
- snprintf(bufferName, sizeof(bufferName), "vds.wb");
- dumpBuffer(ohnd, bufferName);
- }
- }
- } else if(list->outbufAcquireFenceFd >= 0) {
- //If we dont handle the frame, set retireFenceFd to outbufFenceFd,
- //which will make sure, the framework waits on it and closes it.
- //The other way is to wait on outbufFenceFd ourselves, close it and
- //set retireFenceFd to -1. Since we want hwc to be async, choosing
- //the former.
- //Also dup because, the closeAcquireFds() will close the outbufFence
- list->retireFenceFd = dup(list->outbufAcquireFenceFd);
- }
- }
-
- closeAcquireFds(list);
- return ret;
-}
-
-/* We set scaling mode on the VD if the output handle width and height
- differs from the virtual frame buffer width and height. */
-void HWCVirtualVDS::setMDPScalingMode(hwc_context_t* ctx,
- private_handle_t* ohnd, int dpy) {
- bool scalingMode = false;
- int fbWidth = ctx->dpyAttr[dpy].xres;
- int fbHeight = ctx->dpyAttr[dpy].yres;
- if((getWidth(ohnd) != fbWidth) || (getHeight(ohnd) != fbHeight)) {
- scalingMode = true;
- }
- ctx->dpyAttr[dpy].mMDPScalingMode = scalingMode;
-
- ALOGD_IF(HWCVIRTUAL_LOG, "%s fb(%dx%d) outputBuffer(%dx%d) scalingMode=%d",
- __FUNCTION__, fbWidth, fbHeight,
- getWidth(ohnd), getHeight(ohnd), scalingMode);
-}
diff --git a/msm8909/libhwcomposer/hwc_virtual.h b/msm8909/libhwcomposer/hwc_virtual.h
deleted file mode 100644
index bd1833c..0000000
--- a/msm8909/libhwcomposer/hwc_virtual.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 HWC_VIRTUAL
-#define HWC_VIRTUAL
-
-#include <hwc_utils.h>
-
-namespace qhwc {
-
-class HWCVirtualVDS {
-public:
- HWCVirtualVDS(){};
- ~HWCVirtualVDS(){};
- // Chooses composition type and configures pipe for each layer in virtual
- // display list
- int prepare(hwc_composer_device_1 *dev,
- hwc_display_contents_1_t* list);
- // Queues the buffer for each layer in virtual display list and call display
- // commit.
- int set(hwc_context_t *ctx, hwc_display_contents_1_t *list);
- // instantiates mdpcomp, copybit and fbupdate objects and initialize those
- // objects for virtual display during virtual display connect.
- void init(hwc_context_t *ctx);
- // Destroys mdpcomp, copybit and fbupdate objects and for virtual display
- // during virtual display disconnect.
- void destroy(hwc_context_t *ctx, size_t numDisplays,
- hwc_display_contents_1_t** displays);
- int getScalingHeight() const { return mScalingHeight; };
- int getScalingWidth() const { return mScalingWidth; };
- // We can dump the frame buffer and WB
- // output buffer by dynamically enabling
- // dumping via a binder call:
- // adb shell service call display.qservice 15 i32 3 i32 1
- static bool sVDDumpEnabled;
- static void dynamicDebug(bool enable) {sVDDumpEnabled = enable;};
-
-private:
- // These variables store the resolution that WB is being configured to
- // in the current draw cycle.
- int mScalingWidth, mScalingHeight;
- void setMDPScalingMode(hwc_context_t* ctx,
- private_handle_t* ohnd, int dpy);
-};
-
-}; //namespace
-#endif
diff --git a/msm8909/libhwcomposer/hwc_vsync.cpp b/msm8909/libhwcomposer/hwc_vsync.cpp
deleted file mode 100644
index 579f43c..0000000
--- a/msm8909/libhwcomposer/hwc_vsync.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are
- * retained for attribution purposes only.
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 <cutils/properties.h>
-#include <utils/Log.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <linux/msm_mdp.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-#include <poll.h>
-#include "hwc_utils.h"
-#include "hdmi.h"
-#include "qd_utils.h"
-#include "string.h"
-#include "overlay.h"
-#include <inttypes.h>
-
-using namespace qdutils;
-namespace qhwc {
-
-#define HWC_VSYNC_THREAD_NAME "hwcVsyncThread"
-#define PANEL_ON_STR "panel_power_on ="
-#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
-#define MAX_THERMAL_LEVEL 3
-const int MAX_DATA = 64;
-
-int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable)
-{
- int ret = 0;
- if(!ctx->vstate.fakevsync &&
- ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL,
- &enable) < 0) {
- ALOGE("%s: vsync control failed. Dpy=%d, enable=%d : %s",
- __FUNCTION__, dpy, enable, strerror(errno));
- ret = -errno;
- }
- return ret;
-}
-
-static void handle_vsync_event(hwc_context_t* ctx, int dpy, char *data)
-{
- // extract timestamp
- uint64_t timestamp = 0;
- if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) {
- timestamp = strtoull(data + strlen("VSYNC="), NULL, 0);
- }
- // send timestamp to SurfaceFlinger
- ALOGD_IF (ctx->vstate.debug, "%s: timestamp %" PRIu64 " sent to SF for dpy=%d",
- __FUNCTION__, timestamp, dpy);
- ctx->proc->vsync(ctx->proc, dpy, timestamp);
-}
-
-static void handle_blank_event(hwc_context_t* ctx, int dpy, char *data)
-{
- if (!strncmp(data, PANEL_ON_STR, strlen(PANEL_ON_STR))) {
- unsigned long int poweron = strtoul(data + strlen(PANEL_ON_STR), NULL, 0);
- ALOGI("%s: dpy:%d panel power state: %ld", __FUNCTION__, dpy, poweron);
- if (!ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
- ctx->dpyAttr[dpy].isActive = poweron ? true: false;
- }
- }
-}
-
-static void handle_thermal_event(hwc_context_t* ctx, int dpy, char *data)
-{
- // extract thermal level
- uint64_t thermalLevel = 0;
- if (!strncmp(data, "thermal_level=", strlen("thermal_level="))) {
- thermalLevel = strtoull(data + strlen("thermal_level="), NULL, 0);
- }
-
- if (thermalLevel >= MAX_THERMAL_LEVEL) {
- ALOGD("%s: dpy:%d thermal_level=%" PRIu64 "",__FUNCTION__,dpy,thermalLevel);
- ctx->mThermalBurstMode = true;
- } else
- ctx->mThermalBurstMode = false;
-}
-
-struct event {
- const char* name;
- void (*callback)(hwc_context_t* ctx, int dpy, char *data);
-};
-
-struct event event_list[] = {
- { "vsync_event", handle_vsync_event },
- { "show_blank_event", handle_blank_event },
- { "msm_fb_thermal_level", handle_thermal_event },
-};
-
-#define num_events ARRAY_LENGTH(event_list)
-
-static void *vsync_loop(void *param)
-{
- hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);
-
- char thread_name[64] = HWC_VSYNC_THREAD_NAME;
- prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
- setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY +
- android::PRIORITY_MORE_FAVORABLE);
-
- char vdata[MAX_DATA];
- //Number of physical displays
- //We poll on all the nodes.
- int num_displays = HWC_NUM_DISPLAY_TYPES - 1;
- struct pollfd pfd[num_displays][num_events];
-
- char property[PROPERTY_VALUE_MAX];
- if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
- if(atoi(property) == 1)
- ctx->vstate.fakevsync = true;
- }
-
- char node_path[MAX_SYSFS_FILE_PATH];
-
- for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
- for(size_t ev = 0; ev < num_events; ev++) {
- snprintf(node_path, sizeof(node_path),
- "/sys/class/graphics/fb%d/%s",
- dpy == HWC_DISPLAY_PRIMARY ? 0 :
- overlay::Overlay::getInstance()->
- getFbForDpy(HWC_DISPLAY_EXTERNAL),
- event_list[ev].name);
-
- ALOGI("%s: Reading event %zu for dpy %d from %s", __FUNCTION__,
- ev, dpy, node_path);
- pfd[dpy][ev].fd = open(node_path, O_RDONLY);
-
- if (dpy == HWC_DISPLAY_PRIMARY && pfd[dpy][ev].fd < 0) {
- // Make sure fb device is opened before starting
- // this thread so this never happens.
- ALOGE ("%s:unable to open event node for dpy=%d event=%zu, %s",
- __FUNCTION__, dpy, ev, strerror(errno));
- if (ev == 0) {
- ctx->vstate.fakevsync = true;
- //XXX: Blank events don't work with fake vsync,
- //but we shouldn't be running on fake vsync anyway.
- break;
- }
- }
-
- memset(&vdata, '\0', sizeof(vdata));
- // Read once from the fds to clear the first notify
- pread(pfd[dpy][ev].fd, vdata , MAX_DATA - 1, 0);
- if (pfd[dpy][ev].fd >= 0)
- pfd[dpy][ev].events = POLLPRI | POLLERR;
- }
- }
-
- if (LIKELY(!ctx->vstate.fakevsync)) {
- do {
- int err = poll(*pfd, (int)(num_displays * num_events), -1);
- if(err > 0) {
- for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
- for(size_t ev = 0; ev < num_events; ev++) {
- if (pfd[dpy][ev].revents & POLLPRI) {
- // Clear vdata before writing into it
- memset(&vdata, '\0', sizeof(vdata));
- ssize_t len = pread(pfd[dpy][ev].fd, vdata,
- MAX_DATA - 1, 0);
- if (UNLIKELY(len < 0)) {
- // If the read was just interrupted - it is not
- // a fatal error. Just continue in this case
- ALOGE ("%s: Unable to read event:%zu for \
- dpy=%d : %s",
- __FUNCTION__, ev, dpy, strerror(errno));
- continue;
- }
- vdata[len] = '\0';
- event_list[ev].callback(ctx, dpy, vdata);
- }
- }
- }
- } else {
- ALOGE("%s: poll failed errno: %s", __FUNCTION__,
- strerror(errno));
- continue;
- }
- } while (true);
-
- } else {
-
- //Fake vsync is used only when set explicitly through a property or when
- //the vsync timestamp node cannot be opened at bootup. There is no
- //fallback to fake vsync from the true vsync loop, ever, as the
- //condition can easily escape detection.
- //Also, fake vsync is delivered only for the primary display.
- do {
- usleep(16666);
- uint64_t timestamp = systemTime();
- ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, timestamp);
-
- } while (true);
- }
-
- for (int dpy = HWC_DISPLAY_PRIMARY; dpy <= HWC_DISPLAY_EXTERNAL; dpy++ ) {
- for( size_t event = 0; event < num_events; event++) {
- if(pfd[dpy][event].fd >= 0)
- close (pfd[dpy][event].fd);
- }
- }
-
- return NULL;
-}
-
-void init_vsync_thread(hwc_context_t* ctx)
-{
- int ret;
- pthread_t vsync_thread;
- ALOGI("Initializing VSYNC Thread");
- ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx);
- if (ret) {
- ALOGE("%s: failed to create %s: %s", __FUNCTION__,
- HWC_VSYNC_THREAD_NAME, strerror(ret));
- }
-}
-
-}; //namespace
diff --git a/msm8909/liblight/Android.mk b/msm8909/liblight/Android.mk
index 9458a51..bbb076f 100644
--- a/msm8909/liblight/Android.mk
+++ b/msm8909/liblight/Android.mk
@@ -13,19 +13,21 @@
# limitations under the License.
LOCAL_PATH:= $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
# HAL module implemenation stored in
# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := lights.c
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/common/inc
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qdcm/inc
+
+LOCAL_SRC_FILES := lights.c lights_prv.cpp
LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdlights\"
+LOCAL_SHARED_LIBRARIES := liblog libcutils libsdm-disp-vndapis
+LOCAL_HEADER_LIBRARIES := libhardware_headers
+LOCAL_CFLAGS := -DLOG_TAG=\"qdlights\"
LOCAL_CLANG := true
LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS += -Wno-error
+LOCAL_VENDOR_MODULE := true
include $(BUILD_SHARED_LIBRARY)
diff --git a/msm8909/liblight/lights.c b/msm8909/liblight/lights.c
index cf24d50..eed6a25 100644
--- a/msm8909/liblight/lights.c
+++ b/msm8909/liblight/lights.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (C) 2014, 2017 The Linux Foundation. All rights reserved.
+ * Not a contribution
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (C) 2014 The Linux Foundation. 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.
@@ -18,8 +19,8 @@
// #define LOG_NDEBUG 0
-#include <cutils/log.h>
-
+#include <log/log.h>
+#include <cutils/properties.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -32,6 +33,11 @@
#include <sys/types.h>
#include <hardware/lights.h>
+#include "lights_prv.h"
+
+#ifndef DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS
+#define DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS 0x80
+#endif
/******************************************************************************/
@@ -39,7 +45,9 @@
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
static struct light_state_t g_notification;
static struct light_state_t g_battery;
+static int g_last_backlight_mode = BRIGHTNESS_MODE_USER;
static int g_attention = 0;
+static int g_brightness_max = 0;
char const*const RED_LED_FILE
= "/sys/class/leds/red/brightness";
@@ -50,12 +58,12 @@
char const*const BLUE_LED_FILE
= "/sys/class/leds/blue/brightness";
-char const*const BLUETOOTH_LED_FILE
- = "/sys/class/leds/bt/brightness";
-
char const*const LCD_FILE
= "/sys/class/leds/lcd-backlight/brightness";
+char const*const LCD_FILE2
+ = "/sys/class/backlight/panel0-backlight/brightness";
+
char const*const BUTTON_FILE
= "/sys/class/leds/button-backlight/brightness";
@@ -68,6 +76,9 @@
char const*const BLUE_BLINK_FILE
= "/sys/class/leds/blue/blink";
+char const*const PERSISTENCE_FILE
+ = "/sys/class/graphics/fb0/msm_fb_persist_mode";
+
/**
* device methods
*/
@@ -120,16 +131,63 @@
{
int err = 0;
int brightness = rgb_to_brightness(state);
+ unsigned int lpEnabled =
+ state->brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE;
if(!dev) {
return -1;
}
+
pthread_mutex_lock(&g_lock);
- err = write_int(LCD_FILE, brightness);
+ // Toggle low persistence mode state
+ if ((g_last_backlight_mode != state->brightnessMode && lpEnabled) ||
+ (!lpEnabled &&
+ g_last_backlight_mode == BRIGHTNESS_MODE_LOW_PERSISTENCE)) {
+ if ((err = write_int(PERSISTENCE_FILE, lpEnabled)) != 0) {
+ ALOGE("%s: Failed to write to %s: %s\n", __FUNCTION__,
+ PERSISTENCE_FILE, strerror(errno));
+ }
+ if (lpEnabled != 0) {
+ brightness = DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS;
+ }
+ }
+
+ g_last_backlight_mode = state->brightnessMode;
+
+ if (!err) {
+ if (!access(LCD_FILE, F_OK)) {
+ err = write_int(LCD_FILE, brightness);
+ } else {
+ err = write_int(LCD_FILE2, brightness);
+ }
+ }
+
pthread_mutex_unlock(&g_lock);
return err;
}
static int
+set_light_backlight_ext(struct light_device_t* dev,
+ struct light_state_t const* state)
+{
+ int err = 0;
+
+ if(!dev) {
+ return -1;
+ }
+
+ int brightness = state->color & 0x00ffffff;
+ pthread_mutex_lock(&g_lock);
+
+ if (brightness >= 0 && brightness <= g_brightness_max) {
+ set_brightness_ext_level(brightness);
+ }
+
+ pthread_mutex_unlock(&g_lock);
+
+ return err;
+}
+
+static int
set_speaker_light_locked(struct light_device_t* dev,
struct light_state_t const* state)
{
@@ -184,15 +242,15 @@
if (red) {
if (write_int(RED_BLINK_FILE, blink))
write_int(RED_LED_FILE, 0);
- }
+ }
if (green) {
if (write_int(GREEN_BLINK_FILE, blink))
write_int(GREEN_LED_FILE, 0);
- }
+ }
if (blue) {
if (write_int(BLUE_BLINK_FILE, blink))
write_int(BLUE_LED_FILE, 0);
- }
+ }
} else {
write_int(RED_LED_FILE, red);
write_int(GREEN_LED_FILE, green);
@@ -263,20 +321,6 @@
return err;
}
-static int
-set_light_bluetooth(struct light_device_t* dev,
- struct light_state_t const* state)
-{
- int err = 0;
- if(!dev) {
- return -1;
- }
- pthread_mutex_lock(&g_lock);
- err = write_int(BLUETOOTH_LED_FILE, state->color & 0xFF);
- pthread_mutex_unlock(&g_lock);
- return err;
-}
-
/** Close the lights device */
static int
close_lights(struct light_device_t *dev)
@@ -301,18 +345,32 @@
int (*set_light)(struct light_device_t* dev,
struct light_state_t const* state);
- if (0 == strcmp(LIGHT_ID_BACKLIGHT, name))
- set_light = set_light_backlight;
- else if (0 == strcmp(LIGHT_ID_BATTERY, name))
+ if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {
+ char property[PROPERTY_VALUE_MAX];
+ property_get("persist.extend.brightness", property, "0");
+
+ if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
+ !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
+ property_get("persist.display.max_brightness", property, "255");
+ g_brightness_max = atoi(property);
+ set_brightness_ext_init();
+ set_light = set_light_backlight_ext;
+ } else
+ set_light = set_light_backlight;
+ } else if (0 == strcmp(LIGHT_ID_BATTERY, name))
set_light = set_light_battery;
else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
set_light = set_light_notifications;
- else if (0 == strcmp(LIGHT_ID_BUTTONS, name))
- set_light = set_light_buttons;
+ else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {
+ if (!access(BUTTON_FILE, F_OK)) {
+ // enable light button when the file is present
+ set_light = set_light_buttons;
+ } else {
+ return -EINVAL;
+ }
+ }
else if (0 == strcmp(LIGHT_ID_ATTENTION, name))
set_light = set_light_attention;
- else if (0 == strcmp(LIGHT_ID_BLUETOOTH, name))
- set_light = set_light_bluetooth;
else
return -EINVAL;
@@ -326,7 +384,7 @@
memset(dev, 0, sizeof(*dev));
dev->common.tag = HARDWARE_DEVICE_TAG;
- dev->common.version = 0;
+ dev->common.version = LIGHTS_DEVICE_API_VERSION_2_0;
dev->common.module = (struct hw_module_t*)module;
dev->common.close = (int (*)(struct hw_device_t*))close_lights;
dev->set_light = set_light;
diff --git a/sdm845/liblight/lights_prv.cpp b/msm8909/liblight/lights_prv.cpp
similarity index 100%
rename from sdm845/liblight/lights_prv.cpp
rename to msm8909/liblight/lights_prv.cpp
diff --git a/sdm845/liblight/lights_prv.h b/msm8909/liblight/lights_prv.h
similarity index 100%
rename from sdm845/liblight/lights_prv.h
rename to msm8909/liblight/lights_prv.h
diff --git a/msm8909/libmemtrack/Android.mk b/msm8909/libmemtrack/Android.mk
index a73cfd7..10fd40a 100644
--- a/msm8909/libmemtrack/Android.mk
+++ b/msm8909/libmemtrack/Android.mk
@@ -19,12 +19,12 @@
include $(CLEAR_VARS)
LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
+LOCAL_VENDOR_MODULE := true
LOCAL_C_INCLUDES += hardware/libhardware/include
LOCAL_CFLAGS := -Wconversion -Wall -Werror -Wno-sign-conversion
LOCAL_CLANG := true
LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_HEADER_LIBRARIES := libhardware_headers
LOCAL_SRC_FILES := memtrack_msm.c kgsl.c
LOCAL_MODULE := memtrack.$(TARGET_BOARD_PLATFORM)
-LOCAL_CFLAGS += -Wno-error
include $(BUILD_SHARED_LIBRARY)
diff --git a/msm8909/libmemtrack/kgsl.c b/msm8909/libmemtrack/kgsl.c
index ce6a035..69ee901 100644
--- a/msm8909/libmemtrack/kgsl.c
+++ b/msm8909/libmemtrack/kgsl.c
@@ -74,7 +74,7 @@
while (1) {
unsigned long size, mapsize;
char line_type[7];
- char flags[8];
+ char flags[10];
char line_usage[19];
int ret, egl_surface_count = 0, egl_image_count = 0;
@@ -83,12 +83,12 @@
}
/* Format:
- * gpuaddr useraddr size id flags type usage sglen mapsize egLsrf egLimg
- * 545ba000 545ba000 4096 1 -----pY gpumem arraybuffer 1 4096 0 0
+ * gpuaddr useraddr size id flags type usage sglen mapsize eglsrf eglimg
+ * 545ba000 545ba000 4096 1 -----pY gpumem arraybuffer 1 4096 0 0
*/
- ret = sscanf(line, "%*x %*x %lu %*d %6s %6s %18s %*d %lu %6d %6d\n",
- &size, flags, line_type, line_usage, &mapsize,
- &egl_surface_count, &egl_image_count);
+ ret = sscanf(line, "%*x %*x %lu %*d %9s %6s %18s %*d %lu %6d %6d\n",
+ &size, flags, line_type, line_usage, &mapsize,
+ &egl_surface_count, &egl_image_count);
if (ret != 7) {
continue;
}
@@ -110,6 +110,7 @@
fclose(fp);
return -ERANGE;
}
+
accounted_size += mapsize;
if (mapsize > size) {
diff --git a/msm8909/liboverlay/Android.mk b/msm8909/liboverlay/Android.mk
deleted file mode 100644
index 5c59d0f..0000000
--- a/msm8909/liboverlay/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := liboverlay
-LOCAL_MODULE_TAGS := optional
-LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) libqdutils libmemalloc \
- libsync libdl
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdoverlay\"
-LOCAL_CLANG := $(common_clang_flags)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := \
- overlay.cpp \
- overlayUtils.cpp \
- overlayMdp.cpp \
- overlayRotator.cpp \
- overlayMdpRot.cpp \
- overlayMdssRot.cpp \
- overlayWriteback.cpp \
- pipes/overlayGenPipe.cpp
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/msm8909/liboverlay/mdpWrapper.h b/msm8909/liboverlay/mdpWrapper.h
deleted file mode 100644
index f689e45..0000000
--- a/msm8909/liboverlay/mdpWrapper.h
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
-* Copyright (c) 2011, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef MDP_WRAPPER_H
-#define MDP_WRAPPER_H
-
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-
-/*
-* In order to make overlay::mdp_wrapper shorter, please do something like:
-* namespace mdpwrap = overlay::mdp_wrapper;
-* */
-
-#include <linux/msm_mdp.h>
-#include <linux/msm_rotator.h>
-#include <sys/ioctl.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
-#include <errno.h>
-#include "overlayUtils.h"
-#include "overlay.h"
-
-#define IOCTL_DEBUG 0
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-namespace overlay{
-
-namespace mdp_wrapper{
-/* FBIOGET_FSCREENINFO */
-bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo);
-
-/* FBIOGET_VSCREENINFO */
-bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo);
-
-/* FBIOPUT_VSCREENINFO */
-bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo);
-
-/* MSM_ROTATOR_IOCTL_START */
-bool startRotator(int fd, msm_rotator_img_info& rot);
-
-/* MSM_ROTATOR_IOCTL_ROTATE */
-bool rotate(int fd, msm_rotator_data_info& rot);
-
-/* MSMFB_OVERLAY_SET */
-bool setOverlay(int fd, mdp_overlay& ov);
-
-/* MSMFB_OVERLAY_PREPARE */
-int validateAndSet(const int& fd, mdp_overlay_list& list);
-
-/* MSM_ROTATOR_IOCTL_FINISH */
-bool endRotator(int fd, int sessionId);
-
-/* MSMFB_OVERLAY_UNSET */
-bool unsetOverlay(int fd, int ovId);
-
-/* MSMFB_OVERLAY_GET */
-bool getOverlay(int fd, mdp_overlay& ov);
-
-/* MSMFB_OVERLAY_PLAY */
-bool play(int fd, msmfb_overlay_data& od);
-
-/* MSMFB_DISPLAY_COMMIT */
-bool displayCommit(int fd);
-
-/* MSMFB_WRITEBACK_INIT, MSMFB_WRITEBACK_START */
-bool wbInitStart(int fbfd);
-
-/* MSMFB_WRITEBACK_STOP, MSMFB_WRITEBACK_TERMINATE */
-bool wbStopTerminate(int fbfd);
-
-/* MSMFB_WRITEBACK_QUEUE_BUFFER */
-bool wbQueueBuffer(int fbfd, struct msmfb_data& fbData);
-
-/* MSMFB_WRITEBACK_DEQUEUE_BUFFER */
-bool wbDequeueBuffer(int fbfd, struct msmfb_data& fbData);
-
-/* the following are helper functions for dumping
- * msm_mdp and friends*/
-void dump(const char* const s, const msmfb_overlay_data& ov);
-void dump(const char* const s, const msmfb_data& ov);
-void dump(const char* const s, const mdp_overlay& ov);
-void dump(const char* const s, const uint32_t u[], uint32_t cnt);
-void dump(const char* const s, const msmfb_img& ov);
-void dump(const char* const s, const mdp_rect& ov);
-
-/* and rotator */
-void dump(const char* const s, const msm_rotator_img_info& rot);
-void dump(const char* const s, const msm_rotator_data_info& rot);
-
-/* info */
-void dump(const char* const s, const fb_fix_screeninfo& finfo);
-void dump(const char* const s, const fb_var_screeninfo& vinfo);
-
-//---------------Inlines -------------------------------------
-
-inline bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo) {
- ATRACE_CALL();
- if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
- ALOGE("Failed to call ioctl FBIOGET_FSCREENINFO err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
- ATRACE_CALL();
- if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
- ALOGE("Failed to call ioctl FBIOGET_VSCREENINFO err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
- ATRACE_CALL();
- if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo) < 0) {
- ALOGE("Failed to call ioctl FBIOPUT_VSCREENINFO err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool startRotator(int fd, msm_rotator_img_info& rot) {
- ATRACE_CALL();
- if (ioctl(fd, MSM_ROTATOR_IOCTL_START, &rot) < 0){
- ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_START err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool rotate(int fd, msm_rotator_data_info& rot) {
- ATRACE_CALL();
- if (ioctl(fd, MSM_ROTATOR_IOCTL_ROTATE, &rot) < 0) {
- ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_ROTATE err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool setOverlay(int fd, mdp_overlay& ov) {
- ATRACE_CALL();
- if (ioctl(fd, MSMFB_OVERLAY_SET, &ov) < 0) {
- ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline int validateAndSet(const int& fd, mdp_overlay_list& list) {
- ATRACE_CALL();
- uint32_t id = 0;
- if(UNLIKELY(Overlay::isDebugPipeLifecycle())) {
- for(uint32_t i = 0; i < list.num_overlays; i++) {
- if(list.overlay_list[i]->id != (uint32_t)MSMFB_NEW_REQUEST) {
- id |= list.overlay_list[i]->id;
- }
- }
-
- ALOGD("%s Total pipes needed: %d, Exisiting pipe mask 0x%04x",
- __FUNCTION__, list.num_overlays, id);
- id = 0;
- }
-
- if (ioctl(fd, MSMFB_OVERLAY_PREPARE, &list) < 0) {
- ALOGD_IF(IOCTL_DEBUG, "Failed to call ioctl MSMFB_OVERLAY_PREPARE "
- "err=%s", strerror(errno));
- return errno;
- }
-
- if(UNLIKELY(Overlay::isDebugPipeLifecycle())) {
- for(uint32_t i = 0; i < list.num_overlays; i++) {
- id |= list.overlay_list[i]->id;
- }
-
- ALOGD("%s Pipe mask after OVERLAY_PREPARE 0x%04x", __FUNCTION__, id);
- }
-
- return 0;
-}
-
-inline bool endRotator(int fd, uint32_t sessionId) {
- ATRACE_CALL();
- if (ioctl(fd, MSM_ROTATOR_IOCTL_FINISH, &sessionId) < 0) {
- ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_FINISH err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool unsetOverlay(int fd, int ovId) {
- ATRACE_CALL();
- ALOGD_IF(Overlay::isDebugPipeLifecycle(), "%s Unsetting pipe 0x%04x",
- __FUNCTION__, ovId);
-
- if (ioctl(fd, MSMFB_OVERLAY_UNSET, &ovId) < 0) {
- ALOGE("Failed to call ioctl MSMFB_OVERLAY_UNSET err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool getOverlay(int fd, mdp_overlay& ov) {
- ATRACE_CALL();
- if (ioctl(fd, MSMFB_OVERLAY_GET, &ov) < 0) {
- ALOGE("Failed to call ioctl MSMFB_OVERLAY_GET err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool play(int fd, msmfb_overlay_data& od) {
- ATRACE_CALL();
- if (ioctl(fd, MSMFB_OVERLAY_PLAY, &od) < 0) {
- ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool displayCommit(int fd, mdp_display_commit& info) {
- ATRACE_CALL();
- ALOGD_IF(Overlay::isDebugPipeLifecycle(), "%s", __FUNCTION__);
-
- if(ioctl(fd, MSMFB_DISPLAY_COMMIT, &info) == -1) {
- ALOGE("Failed to call ioctl MSMFB_DISPLAY_COMMIT err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool wbInitStart(int fbfd) {
- ATRACE_CALL();
- if(ioctl(fbfd, MSMFB_WRITEBACK_INIT, NULL) < 0) {
- ALOGE("Failed to call ioctl MSMFB_WRITEBACK_INIT err=%s",
- strerror(errno));
- return false;
- }
- if(ioctl(fbfd, MSMFB_WRITEBACK_START, NULL) < 0) {
- ALOGE("Failed to call ioctl MSMFB_WRITEBACK_START err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool wbStopTerminate(int fbfd) {
- ATRACE_CALL();
- if(ioctl(fbfd, MSMFB_WRITEBACK_STOP, NULL) < 0) {
- ALOGE("Failed to call ioctl MSMFB_WRITEBACK_STOP err=%s",
- strerror(errno));
- return false;
- }
- if(ioctl(fbfd, MSMFB_WRITEBACK_TERMINATE, NULL) < 0) {
- ALOGE("Failed to call ioctl MSMFB_WRITEBACK_TERMINATE err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool wbQueueBuffer(int fbfd, struct msmfb_data& fbData) {
- ATRACE_CALL();
- if(ioctl(fbfd, MSMFB_WRITEBACK_QUEUE_BUFFER, &fbData) < 0) {
- ALOGE("Failed to call ioctl MSMFB_WRITEBACK_QUEUE_BUFFER err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-inline bool wbDequeueBuffer(int fbfd, struct msmfb_data& fbData) {
- ATRACE_CALL();
- if(ioctl(fbfd, MSMFB_WRITEBACK_DEQUEUE_BUFFER, &fbData) < 0) {
- ALOGE("Failed to call ioctl MSMFB_WRITEBACK_DEQUEUE_BUFFER err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
-/* dump funcs */
-inline void dump(const char* const s, const msmfb_overlay_data& ov) {
- ALOGE("%s msmfb_overlay_data id=%d",
- s, ov.id);
- dump("data", ov.data);
-}
-inline void dump(const char* const s, const msmfb_data& ov) {
- ALOGE("%s msmfb_data offset=%d memid=%d id=%d flags=0x%x priv=%d",
- s, ov.offset, ov.memory_id, ov.id, ov.flags, ov.priv);
-}
-inline void dump(const char* const s, const mdp_overlay& ov) {
- ALOGE("%s mdp_overlay z=%d alpha=%d mask=%d flags=0x%x id=%d",
- s, ov.z_order, ov.alpha,
- ov.transp_mask, ov.flags, ov.id);
- dump("src", ov.src);
- dump("src_rect", ov.src_rect);
- dump("dst_rect", ov.dst_rect);
- /*
- Commented off to prevent verbose logging, since user_data could have 8 or so
- fields which are mostly 0
- dump("user_data", ov.user_data,
- sizeof(ov.user_data)/sizeof(ov.user_data[0]));
- */
-}
-inline void dump(const char* const s, const msmfb_img& ov) {
- ALOGE("%s msmfb_img w=%d h=%d format=%d %s",
- s, ov.width, ov.height, ov.format,
- overlay::utils::getFormatString(ov.format));
-}
-inline void dump(const char* const s, const mdp_rect& ov) {
- ALOGE("%s mdp_rect x=%d y=%d w=%d h=%d",
- s, ov.x, ov.y, ov.w, ov.h);
-}
-
-inline void dump(const char* const s, const uint32_t u[], uint32_t cnt) {
- ALOGE("%s user_data cnt=%d", s, cnt);
- for(uint32_t i=0; i < cnt; ++i) {
- ALOGE("i=%d val=%d", i, u[i]);
- }
-}
-inline void dump(const char* const s, const msm_rotator_img_info& rot) {
- ALOGE("%s msm_rotator_img_info sessid=%u dstx=%d dsty=%d rot=%d, ena=%d scale=%d",
- s, rot.session_id, rot.dst_x, rot.dst_y,
- rot.rotations, rot.enable, rot.downscale_ratio);
- dump("src", rot.src);
- dump("dst", rot.dst);
- dump("src_rect", rot.src_rect);
-}
-inline void dump(const char* const s, const msm_rotator_data_info& rot) {
- ALOGE("%s msm_rotator_data_info sessid=%u verkey=%d",
- s, rot.session_id, rot.version_key);
- dump("src", rot.src);
- dump("dst", rot.dst);
- dump("src_chroma", rot.src_chroma);
- dump("dst_chroma", rot.dst_chroma);
-}
-inline void dump(const char* const s, const fb_fix_screeninfo& finfo) {
- ALOGE("%s fb_fix_screeninfo type=%d", s, finfo.type);
-}
-inline void dump(const char* const s, const fb_var_screeninfo& vinfo) {
- ALOGE("%s fb_var_screeninfo xres=%d yres=%d",
- s, vinfo.xres, vinfo.yres);
-}
-
-} // mdp_wrapper
-
-} // overlay
-
-#endif // MDP_WRAPPER_H
diff --git a/msm8909/liboverlay/overlay.cpp b/msm8909/liboverlay/overlay.cpp
deleted file mode 100644
index 1a4bf03..0000000
--- a/msm8909/liboverlay/overlay.cpp
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
-* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <dlfcn.h>
-#include "overlay.h"
-#include "pipes/overlayGenPipe.h"
-#include "mdp_version.h"
-#include "qdMetaData.h"
-#include "qd_utils.h"
-
-namespace overlay {
-using namespace utils;
-using namespace qdutils;
-
-Overlay::Overlay() {
- int numPipes = qdutils::MDPVersion::getInstance().getTotalPipes();
- PipeBook::NUM_PIPES = (numPipes <= utils::OV_MAX)? numPipes : utils::OV_MAX;
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- mPipeBook[i].init();
- }
-
- initScalar();
- setDMAMultiplexingSupported();
-}
-
-Overlay::~Overlay() {
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- mPipeBook[i].destroy();
- }
- destroyScalar();
-}
-
-void Overlay::configBegin() {
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- //Mark as available for this round.
- PipeBook::resetUse(i);
- PipeBook::resetAllocation(i);
- }
-}
-
-void Overlay::configDone() {
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if((PipeBook::isNotUsed(i) && !sessionInProgress((eDest)i)) ||
- isSessionEnded((eDest)i)) {
- //Forces UNSET on pipes, flushes rotator memory and session, closes
- //fds
- mPipeBook[i].destroy();
- }
- }
- PipeBook::save();
-}
-
-int Overlay::getPipeId(utils::eDest dest) {
- return mPipeBook[(int)dest].mPipe->getPipeId();
-}
-
-eDest Overlay::getDest(int pipeid) {
- eDest dest = OV_INVALID;
- // finding the dest corresponding to the given pipe
- for(int i=0; i < PipeBook::NUM_PIPES; ++i) {
- if(mPipeBook[i].valid() && mPipeBook[i].mPipe->getPipeId() == pipeid) {
- return (eDest)i;
- }
- }
- return dest;
-}
-
-eDest Overlay::reservePipe(int pipeid) {
- eDest dest = getDest(pipeid);
- PipeBook::setAllocation((int)dest);
- return dest;
-}
-
-eDest Overlay::nextPipe(eMdpPipeType type, const PipeSpecs& pipeSpecs) {
- eDest dest = OV_INVALID;
- int dpy = pipeSpecs.dpy;
- int mixer = pipeSpecs.mixer;
- int formatType = pipeSpecs.formatClass;
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if( (type == OV_MDP_PIPE_ANY || //Pipe type match
- type == PipeBook::getPipeType((eDest)i)) &&
- (mPipeBook[i].mDisplay == DPY_UNUSED || //Free or same display
- mPipeBook[i].mDisplay == dpy) &&
- (mPipeBook[i].mMixer == MIXER_UNUSED || //Free or same mixer
- mPipeBook[i].mMixer == mixer) &&
- (mPipeBook[i].mFormatType == FORMAT_NONE || //Free or same format
- mPipeBook[i].mFormatType == formatType) &&
- PipeBook::isNotAllocated(i) && //Free pipe
- ( (sDMAMultiplexingSupported && dpy) ||
- !(sDMAMode == DMA_BLOCK_MODE && //DMA pipe in Line mode
- PipeBook::getPipeType((eDest)i) == OV_MDP_PIPE_DMA)) ){
- //DMA-Multiplexing is only supported for WB on 8x26
- dest = (eDest)i;
- PipeBook::setAllocation(i);
- break;
- }
- }
-
- if(dest != OV_INVALID) {
- int index = (int)dest;
- mPipeBook[index].mDisplay = dpy;
- mPipeBook[index].mMixer = mixer;
- mPipeBook[index].mFormatType = formatType;
- if(not mPipeBook[index].valid()) {
- mPipeBook[index].mPipe = new GenericPipe(dpy);
- mPipeBook[index].mSession = PipeBook::NONE;
- }
- }
-
- return dest;
-}
-
-utils::eDest Overlay::getPipe(const PipeSpecs& pipeSpecs) {
- if(MDPVersion::getInstance().is8x26()) {
- return getPipe_8x26(pipeSpecs);
- } else if(MDPVersion::getInstance().is8x16()) {
- return getPipe_8x16(pipeSpecs);
- } else if(MDPVersion::getInstance().is8x39()) {
- return getPipe_8x39(pipeSpecs);
- } else if(MDPVersion::getInstance().is8994()) {
- return getPipe_8994(pipeSpecs);
- }
-
- eDest dest = OV_INVALID;
-
- //The default behavior is to assume RGB and VG pipes have scalars
- if(pipeSpecs.formatClass == FORMAT_YUV) {
- return nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- } else if(pipeSpecs.fb == false) { //RGB App layers
- if(not pipeSpecs.needsScaling) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
- }
- if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
- }
- if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- }
- } else { //FB layer
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
- if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- }
- //Some features can cause FB to have scaling as well.
- //If we ever come to this block with FB needing scaling,
- //the screen will be black for a frame, since the FB won't get a pipe
- //but atleast this will prevent a hang
- if(dest == OV_INVALID and (not pipeSpecs.needsScaling)) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
- }
- }
- return dest;
-}
-
-utils::eDest Overlay::getPipe_8x26(const PipeSpecs& pipeSpecs) {
- //Use this to hide all the 8x26 requirements that cannot be humanly
- //described in a generic way
- eDest dest = OV_INVALID;
- if(pipeSpecs.formatClass == FORMAT_YUV) { //video
- return nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- } else if(pipeSpecs.fb == false) { //RGB app layers
- if((not pipeSpecs.needsScaling) and
- (not (pipeSpecs.numActiveDisplays > 1 &&
- pipeSpecs.dpy == DPY_PRIMARY))) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
- }
- if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
- }
- if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- }
- } else { //FB layer
- //For 8x26 Secondary we use DMA always for FB for inline rotation
- if(pipeSpecs.dpy == DPY_PRIMARY) {
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
- if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- }
- }
- if(dest == OV_INVALID and (not pipeSpecs.needsScaling) and
- (not (pipeSpecs.numActiveDisplays > 1 &&
- pipeSpecs.dpy == DPY_PRIMARY))) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
- }
- }
- return dest;
-}
-
-utils::eDest Overlay::getPipe_8x16(const PipeSpecs& pipeSpecs) {
- //Having such functions help keeping the interface generic but code specific
- //and rife with assumptions
- eDest dest = OV_INVALID;
- if(pipeSpecs.formatClass == FORMAT_YUV or pipeSpecs.needsScaling) {
- return nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- } else {
- //Since this is a specific func, we can assume stuff like RGB pipe not
- //having scalar blocks
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
- if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
- }
- if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- }
- }
- return dest;
-}
-
-utils::eDest Overlay::getPipe_8x39(const PipeSpecs& pipeSpecs) {
- //8x16 & 8x36 has same number of pipes, pipe-types & scaling capabilities.
- //Rely on 8x16 until we see a need to change.
- return getPipe_8x16(pipeSpecs);
-}
-
-utils::eDest Overlay::getPipe_8994(const PipeSpecs& pipeSpecs) {
- //If DMA pipes need to be used in block mode for downscale, there could be
- //cases where consecutive rounds need separate modes, which cannot be
- //supported since we at least need 1 round in between where the DMA is
- //unused
- eDest dest = OV_INVALID;
- if(pipeSpecs.formatClass == FORMAT_YUV) {
- return nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- } else {
- dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs);
- if(dest == OV_INVALID) {
- dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs);
- }
- if(dest == OV_INVALID and not pipeSpecs.needsScaling) {
- dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs);
- }
- }
- return dest;
-}
-
-void Overlay::endAllSessions() {
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if(mPipeBook[i].valid() && mPipeBook[i].mSession==PipeBook::START)
- mPipeBook[i].mSession = PipeBook::END;
- }
-}
-
-bool Overlay::isPipeTypeAttached(eMdpPipeType type) {
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if(type == PipeBook::getPipeType((eDest)i) &&
- mPipeBook[i].mDisplay != DPY_UNUSED) {
- return true;
- }
- }
- return false;
-}
-
-int Overlay::comparePipePriority(utils::eDest pipe1Index,
- utils::eDest pipe2Index) {
- validate((int)pipe1Index);
- validate((int)pipe2Index);
- uint8_t pipe1Prio = mPipeBook[(int)pipe1Index].mPipe->getPriority();
- uint8_t pipe2Prio = mPipeBook[(int)pipe2Index].mPipe->getPriority();
- if(pipe1Prio > pipe2Prio)
- return -1;
- if(pipe1Prio < pipe2Prio)
- return 1;
- return 0;
-}
-
-bool Overlay::commit(utils::eDest dest) {
- bool ret = false;
- validate((int)dest);
-
- if(mPipeBook[dest].mPipe->commit()) {
- ret = true;
- PipeBook::setUse((int)dest);
- } else {
- clear(mPipeBook[dest].mDisplay);
- }
- return ret;
-}
-
-bool Overlay::queueBuffer(int fd, uint32_t offset,
- utils::eDest dest) {
- bool ret = false;
- validate((int)dest);
- //Queue only if commit() has succeeded (and the bit set)
- if(PipeBook::isUsed((int)dest)) {
- ret = mPipeBook[dest].mPipe->queueBuffer(fd, offset);
- }
- return ret;
-}
-
-void Overlay::setCrop(const utils::Dim& d,
- utils::eDest dest) {
- validate((int)dest);
- mPipeBook[dest].mPipe->setCrop(d);
-}
-
-void Overlay::setColor(const uint32_t color,
- utils::eDest dest) {
- validate((int)dest);
- mPipeBook[dest].mPipe->setColor(color);
-}
-
-void Overlay::setPosition(const utils::Dim& d,
- utils::eDest dest) {
- validate((int)dest);
- mPipeBook[dest].mPipe->setPosition(d);
-}
-
-void Overlay::setTransform(const int orient,
- utils::eDest dest) {
- validate((int)dest);
-
- utils::eTransform transform =
- static_cast<utils::eTransform>(orient);
- mPipeBook[dest].mPipe->setTransform(transform);
-
-}
-
-void Overlay::setSource(const utils::PipeArgs args,
- utils::eDest dest) {
- validate((int)dest);
-
- setPipeType(dest, PipeBook::getPipeType(dest));
- mPipeBook[dest].mPipe->setSource(args);
-}
-
-void Overlay::setVisualParams(const MetaData_t& metadata, utils::eDest dest) {
- validate((int)dest);
- mPipeBook[dest].mPipe->setVisualParams(metadata);
-}
-
-void Overlay::setPipeType(utils::eDest pipeIndex,
- const utils::eMdpPipeType pType) {
- mPipeBook[pipeIndex].mPipe->setPipeType(pType);
-}
-
-Overlay* Overlay::getInstance() {
- if(sInstance == NULL) {
- sInstance = new Overlay();
- }
- return sInstance;
-}
-
-// Clears any VG pipes allocated to the fb devices
-// Generates a LUT for pipe types.
-int Overlay::initOverlay() {
- int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
- int numPipesXType[OV_MDP_PIPE_ANY] = {0};
- numPipesXType[OV_MDP_PIPE_RGB] =
- qdutils::MDPVersion::getInstance().getRGBPipes();
- numPipesXType[OV_MDP_PIPE_VG] =
- qdutils::MDPVersion::getInstance().getVGPipes();
- numPipesXType[OV_MDP_PIPE_DMA] =
- qdutils::MDPVersion::getInstance().getDMAPipes();
-
- int index = 0;
- for(int X = 0; X < (int)OV_MDP_PIPE_ANY; X++) { //iterate over types
- for(int j = 0; j < numPipesXType[X]; j++) { //iterate over num
- PipeBook::pipeTypeLUT[index] = (utils::eMdpPipeType)X;
- index++;
- }
- }
-
- if (mdpVersion < qdutils::MDSS_V5 && mdpVersion > qdutils::MDP_V3_0_5) {
- msmfb_mixer_info_req req;
- mdp_mixer_info *minfo = NULL;
- char name[64];
- int fd = -1;
- for(int i = 0; i < MAX_FB_DEVICES; i++) {
- snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
- ALOGD("initoverlay:: opening the device:: %s", name);
- fd = ::open(name, O_RDWR, 0);
- if(fd < 0) {
- ALOGE("cannot open framebuffer(%d)", i);
- return -1;
- }
- //Get the mixer configuration */
- req.mixer_num = i;
- if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
- ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
- close(fd);
- return -1;
- }
- minfo = req.info;
- for (int j = 0; j < req.cnt; j++) {
- ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
- minfo->z_order);
- // except the RGB base layer with z_order of -1, clear any
- // other pipes connected to mixer.
- if((minfo->z_order) != -1) {
- int index = minfo->pndx;
- ALOGD("Unset overlay with index: %d at mixer %d", index, i);
- if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
- ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
- close(fd);
- return -1;
- }
- }
- minfo++;
- }
- close(fd);
- fd = -1;
- }
- }
-
- FILE *displayDeviceFP = NULL;
- char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
- char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
- const char *strDtvPanel = "dtv panel";
- const char *strWbPanel = "writeback panel";
-
- for(int num = 1; num < MAX_FB_DEVICES; num++) {
- snprintf (msmFbTypePath, sizeof(msmFbTypePath),
- "/sys/class/graphics/fb%d/msm_fb_type", num);
- displayDeviceFP = fopen(msmFbTypePath, "r");
-
- if(displayDeviceFP){
- fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
- displayDeviceFP);
-
- if(strncmp(fbType, strDtvPanel, strlen(strDtvPanel)) == 0) {
- sDpyFbMap[DPY_EXTERNAL] = num;
- } else if(strncmp(fbType, strWbPanel, strlen(strWbPanel)) == 0) {
- sDpyFbMap[DPY_WRITEBACK] = num;
- }
-
- fclose(displayDeviceFP);
- }
- }
-
- return 0;
-}
-
-bool Overlay::displayCommit(const int& fd) {
- utils::Dim lRoi, rRoi;
- return displayCommit(fd, lRoi, rRoi);
-}
-
-bool Overlay::displayCommit(const int& fd, const utils::Dim& lRoi,
- const utils::Dim& rRoi) {
- //Commit
- struct mdp_display_commit info;
- memset(&info, 0, sizeof(struct mdp_display_commit));
- info.flags = MDP_DISPLAY_COMMIT_OVERLAY;
- info.l_roi.x = lRoi.x;
- info.l_roi.y = lRoi.y;
- info.l_roi.w = lRoi.w;
- info.l_roi.h = lRoi.h;
- info.r_roi.x = rRoi.x;
- info.r_roi.y = rRoi.y;
- info.r_roi.w = rRoi.w;
- info.r_roi.h = rRoi.h;
-
- if(!mdp_wrapper::displayCommit(fd, info)) {
- ALOGE("%s: commit failed", __func__);
- return false;
- }
- return true;
-}
-
-void Overlay::getDump(char *buf, size_t len) {
- int totalPipes = 0;
- const char *str = "\nOverlay State\n\n";
- strlcat(buf, str, len);
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if(mPipeBook[i].valid()) {
- mPipeBook[i].mPipe->getDump(buf, len);
- char str[64] = {'\0'};
- snprintf(str, 64, "Display=%d\n\n", mPipeBook[i].mDisplay);
- strlcat(buf, str, len);
- totalPipes++;
- }
- }
- char str_pipes[64] = {'\0'};
- snprintf(str_pipes, 64, "Pipes=%d\n\n", totalPipes);
- strlcat(buf, str_pipes, len);
-}
-
-void Overlay::clear(int dpy) {
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if (mPipeBook[i].mDisplay == dpy) {
- // Mark as available for this round
- PipeBook::resetUse(i);
- PipeBook::resetAllocation(i);
- if(getPipeId((utils::eDest)i) == -1) {
- mPipeBook[i].destroy();
- }
- }
- }
-}
-
-bool Overlay::validateAndSet(const int& dpy, const int& fbFd) {
- GenericPipe* pipeArray[PipeBook::NUM_PIPES];
- memset(pipeArray, 0, sizeof(GenericPipe*)*(PipeBook::NUM_PIPES));
-
- int num = 0;
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if(PipeBook::isUsed(i) && mPipeBook[i].valid() &&
- mPipeBook[i].mDisplay == dpy) {
- pipeArray[num++] = mPipeBook[i].mPipe;
- }
- }
-
- //Protect against misbehaving clients
- return num ? GenericPipe::validateAndSet(pipeArray, num, fbFd) : true;
-}
-
-void Overlay::initScalar() {
- if(sLibScaleHandle == NULL) {
- sLibScaleHandle = dlopen("libscale.so", RTLD_NOW);
- if(sLibScaleHandle) {
- *(void **) &sFnProgramScale =
- dlsym(sLibScaleHandle, "programScale");
- }
- }
-}
-
-void Overlay::destroyScalar() {
- if(sLibScaleHandle) {
- dlclose(sLibScaleHandle);
- sLibScaleHandle = NULL;
- }
-}
-
-void Overlay::PipeBook::init() {
- mPipe = NULL;
- mDisplay = DPY_UNUSED;
- mMixer = MIXER_UNUSED;
- mFormatType = FORMAT_NONE;
-}
-
-void Overlay::PipeBook::destroy() {
- if(mPipe) {
- delete mPipe;
- mPipe = NULL;
- }
- mDisplay = DPY_UNUSED;
- mMixer = MIXER_UNUSED;
- mFormatType = FORMAT_NONE;
- mSession = NONE;
-}
-
-Overlay* Overlay::sInstance = 0;
-int Overlay::sDpyFbMap[DPY_MAX] = {0, -1, -1, -1};
-int Overlay::sDMAMode = DMA_LINE_MODE;
-bool Overlay::sDMAMultiplexingSupported = false;
-bool Overlay::sDebugPipeLifecycle = false;
-int Overlay::PipeBook::NUM_PIPES = 0;
-int Overlay::PipeBook::sPipeUsageBitmap = 0;
-int Overlay::PipeBook::sLastUsageBitmap = 0;
-int Overlay::PipeBook::sAllocatedBitmap = 0;
-utils::eMdpPipeType Overlay::PipeBook::pipeTypeLUT[utils::OV_MAX] =
- {utils::OV_MDP_PIPE_ANY};
-void *Overlay::sLibScaleHandle = NULL;
-int (*Overlay::sFnProgramScale)(struct mdp_overlay_list *) = NULL;
-
-}; // namespace overlay
diff --git a/msm8909/liboverlay/overlay.h b/msm8909/liboverlay/overlay.h
deleted file mode 100644
index 5c93b23..0000000
--- a/msm8909/liboverlay/overlay.h
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
-* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation. nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef OVERLAY_H
-#define OVERLAY_H
-
-#include "overlayUtils.h"
-#include "mdp_version.h"
-#include "utils/threads.h"
-
-struct MetaData_t;
-
-namespace overlay {
-class GenericPipe;
-
-class Overlay : utils::NoCopy {
-public:
- enum { DMA_BLOCK_MODE, DMA_LINE_MODE };
- //Abstract Display types. Each backed by a LayerMixer,
- //represented by a fb node.
- //High res panels can be backed by 2 layer mixers and a single fb node.
- enum { DPY_PRIMARY, DPY_EXTERNAL, DPY_TERTIARY, DPY_WRITEBACK, DPY_UNUSED };
- enum { DPY_MAX = DPY_UNUSED };
- enum { MIXER_LEFT, MIXER_RIGHT, MIXER_UNUSED };
- enum { MIXER_DEFAULT = MIXER_LEFT, MIXER_MAX = MIXER_UNUSED };
- enum { MAX_FB_DEVICES = DPY_MAX };
- enum { FORMAT_YUV, FORMAT_RGB , FORMAT_NONE };
-
- struct PipeSpecs {
- PipeSpecs() : formatClass(FORMAT_RGB), needsScaling(false), fb(false),
- dpy(DPY_PRIMARY), mixer(MIXER_DEFAULT), numActiveDisplays(1) {}
- int formatClass;
- bool needsScaling;
- bool fb;
- int dpy;
- int mixer;
- int numActiveDisplays;
- };
-
- /* dtor close */
- ~Overlay();
-
- /* Marks the beginning of a drawing round, resets usage bits on pipes
- * Should be called when drawing begins before any pipe config is done.
- */
- void configBegin();
-
- /* Marks the end of config for this drawing round
- * Will do garbage collection of pipe objects and thus calling UNSETs,
- * closing FDs, removing rotator objects and memory, if allocated.
- * Should be called after all pipe configs are done.
- */
- void configDone();
-
- /* Get a pipe that supported the specified format class (yuv, rgb) and has
- * scaling capabilities.
- */
- utils::eDest getPipe(const PipeSpecs& pipeSpecs);
- /* Returns the eDest corresponding to an already allocated pipeid.
- * Useful for the reservation case, when libvpu reserves the pipe at its
- * end, and expect the overlay to allocate a given pipe for a layer.
- */
- utils::eDest reservePipe(int pipeid);
- /* getting dest for the given pipeid */
- utils::eDest getDest(int pipeid);
- /* getting overlay.pipeid for the given dest */
- int getPipeId(utils::eDest dest);
-
- void setSource(const utils::PipeArgs args, utils::eDest dest);
- void setCrop(const utils::Dim& d, utils::eDest dest);
- void setColor(const uint32_t color, utils::eDest dest);
- void setTransform(const int orientation, utils::eDest dest);
- void setPosition(const utils::Dim& dim, utils::eDest dest);
- void setVisualParams(const MetaData_t& data, utils::eDest dest);
- bool commit(utils::eDest dest);
- bool queueBuffer(int fd, uint32_t offset, utils::eDest dest);
-
- /* pipe reservation session is running */
- bool sessionInProgress(utils::eDest dest);
- /* pipe reservation session has ended*/
- bool isSessionEnded(utils::eDest dest);
- /* start session for the pipe reservation */
- void startSession(utils::eDest dest);
- /* end all started sesisons */
- void endAllSessions();
- /* Returns available ("unallocated") pipes for a display's mixer */
- int availablePipes(int dpy, int mixer);
- /* Returns available ("unallocated") pipes for a display */
- int availablePipes(int dpy);
- /* Returns available ("unallocated") pipe of given type for a display */
- int availablePipes(int dpy, utils::eMdpPipeType type);
- /* Returns if any of the requested pipe type is attached to any of the
- * displays
- */
- bool isPipeTypeAttached(utils::eMdpPipeType type);
- /* Compare pipe priorities and return
- * 1 if 1st pipe has a higher priority
- * 0 if both have the same priority
- *-1 if 2nd pipe has a higher priority
- */
- int comparePipePriority(utils::eDest pipe1Index, utils::eDest pipe2Index);
- /* Returns pipe dump. Expects a NULL terminated buffer of big enough size
- * to populate.
- */
- /* Returns if DMA pipe multiplexing is supported by the mdss driver */
- static bool isDMAMultiplexingSupported();
- /* Returns if UI scaling on external is supported on the targets */
- static bool isUIScalingOnExternalSupported();
- void getDump(char *buf, size_t len);
- /* Reset usage and allocation bits on all pipes for given display */
- void clear(int dpy);
- /* Validate the set of pipes for a display and set them in driver */
- bool validateAndSet(const int& dpy, const int& fbFd);
-
- /* Closes open pipes, called during startup */
- static int initOverlay();
- /* Returns the singleton instance of overlay */
- static Overlay* getInstance();
- static void setDMAMode(const int& mode);
- static int getDMAMode();
- /* Returns the framebuffer node backing up the display */
- static int getFbForDpy(const int& dpy);
-
- static bool displayCommit(const int& fd);
- /* Overloads display commit with ROI's of each halves.
- * Single interface panels will only update left ROI. */
- static bool displayCommit(const int& fd, const utils::Dim& lRoi,
- const utils::Dim& rRoi);
- /* Logs pipe lifecycle events like set, unset, commit when enabled */
- static void debugPipeLifecycle(const bool& enable);
- /* Returns true if pipe life cycle logging is enabled */
- static bool isDebugPipeLifecycle();
-
-private:
- /* Ctor setup */
- explicit Overlay();
- /*Validate index range, abort if invalid */
- void validate(int index);
- static void setDMAMultiplexingSupported();
- /* Returns an available pipe based on the type of pipe requested. When ANY
- * is requested, the first available VG or RGB is returned. If no pipe is
- * available for the display "dpy" then INV is returned. Note: If a pipe is
- * assigned to a certain display, then it cannot be assigned to another
- * display without being garbage-collected once. To add if a pipe is
- * asisgned to a mixer within a display it cannot be reused for another
- * mixer without being UNSET once*/
- utils::eDest nextPipe(utils::eMdpPipeType, const PipeSpecs& pipeSpecs);
- /* Helpers that enfore target specific policies while returning pipes */
- utils::eDest getPipe_8x26(const PipeSpecs& pipeSpecs);
- utils::eDest getPipe_8x16(const PipeSpecs& pipeSpecs);
- utils::eDest getPipe_8x39(const PipeSpecs& pipeSpecs);
- utils::eDest getPipe_8994(const PipeSpecs& pipeSpecs);
-
- /* Returns the handle to libscale.so's programScale function */
- static int (*getFnProgramScale())(struct mdp_overlay_list *);
- /* Creates a scalar object using libscale.so */
- static void initScalar();
- /* Destroys the scalar object using libscale.so */
- static void destroyScalar();
- /* Sets the pipe type RGB/VG/DMA*/
- void setPipeType(utils::eDest pipeIndex, const utils::eMdpPipeType pType);
-
- /* Just like a Facebook for pipes, but much less profile info */
- struct PipeBook {
- void init();
- void destroy();
- /* Check if pipe exists and return true, false otherwise */
- bool valid();
-
- /* Hardware pipe wrapper */
- GenericPipe *mPipe;
- /* Display using this pipe. Refer to enums above */
- int mDisplay;
- /* Mixer within a split display this pipe is attached to */
- int mMixer;
- /* Format for which this pipe is attached to the mixer*/
- int mFormatType;
-
- /* operations on bitmap */
- static bool pipeUsageUnchanged();
- static void setUse(int index);
- static void resetUse(int index);
- static bool isUsed(int index);
- static bool isNotUsed(int index);
- static void save();
-
- static void setAllocation(int index);
- static void resetAllocation(int index);
- static bool isAllocated(int index);
- static bool isNotAllocated(int index);
-
- static utils::eMdpPipeType getPipeType(utils::eDest dest);
- static const char* getDestStr(utils::eDest dest);
-
- static int NUM_PIPES;
- static utils::eMdpPipeType pipeTypeLUT[utils::OV_MAX];
- /* Session for reserved pipes */
- enum Session {
- NONE,
- START,
- END
- };
- Session mSession;
-
- private:
- //usage tracks if a successful commit happened. So a pipe could be
- //allocated to a display, but it may not end up using it for various
- //reasons. If one display actually uses a pipe then it amy not be
- //used by another display, without an UNSET in between.
- static int sPipeUsageBitmap;
- static int sLastUsageBitmap;
- //Tracks which pipe objects are allocated. This does not imply that they
- //will actually be used. For example, a display might choose to acquire
- //3 pipe objects in one shot and proceed with config only if it gets all
- //3. The bitmap helps allocate different pipe objects on each request.
- static int sAllocatedBitmap;
- };
-
- PipeBook mPipeBook[utils::OV_INVALID]; //Used as max
-
- /* Singleton Instance*/
- static Overlay *sInstance;
- static int sDpyFbMap[DPY_MAX];
- static int sDMAMode;
- static bool sDMAMultiplexingSupported;
- static void *sLibScaleHandle;
- static int (*sFnProgramScale)(struct mdp_overlay_list *);
- static bool sDebugPipeLifecycle;
-
- friend class MdpCtrl;
-};
-
-inline void Overlay::validate(int index) {
- OVASSERT(index >=0 && index < PipeBook::NUM_PIPES, \
- "%s, Index out of bounds: %d", __FUNCTION__, index);
- OVASSERT(mPipeBook[index].valid(), "Pipe does not exist %s",
- PipeBook::getDestStr((utils::eDest)index));
-}
-
-inline int Overlay::availablePipes(int dpy, int mixer) {
- int avail = 0;
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if( (mPipeBook[i].mDisplay == DPY_UNUSED ||
- mPipeBook[i].mDisplay == dpy) &&
- (mPipeBook[i].mMixer == MIXER_UNUSED ||
- mPipeBook[i].mMixer == mixer) &&
- PipeBook::isNotAllocated(i) &&
- !(Overlay::getDMAMode() == Overlay::DMA_BLOCK_MODE &&
- PipeBook::getPipeType((utils::eDest)i) ==
- utils::OV_MDP_PIPE_DMA)) {
- avail++;
- }
- }
- return avail;
-}
-
-inline int Overlay::availablePipes(int dpy) {
- int avail = 0;
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if( (mPipeBook[i].mDisplay == DPY_UNUSED ||
- mPipeBook[i].mDisplay == dpy) &&
- PipeBook::isNotAllocated(i) &&
- !(Overlay::getDMAMode() == Overlay::DMA_BLOCK_MODE &&
- PipeBook::getPipeType((utils::eDest)i) ==
- utils::OV_MDP_PIPE_DMA)) {
- avail++;
- }
- }
- return avail;
-}
-
-inline int Overlay::availablePipes(int dpy, utils::eMdpPipeType type) {
- int avail = 0;
- for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if((mPipeBook[i].mDisplay == DPY_UNUSED ||
- mPipeBook[i].mDisplay == dpy) &&
- PipeBook::isNotAllocated(i) &&
- type == PipeBook::getPipeType((utils::eDest)i)) {
- avail++;
- }
- }
- return avail;
-}
-
-inline void Overlay::setDMAMode(const int& mode) {
- if(mode == DMA_LINE_MODE || mode == DMA_BLOCK_MODE)
- sDMAMode = mode;
-}
-
-inline void Overlay::setDMAMultiplexingSupported() {
- sDMAMultiplexingSupported = false;
- if(qdutils::MDPVersion::getInstance().is8x26())
- sDMAMultiplexingSupported = true;
-}
-
-inline bool Overlay::isDMAMultiplexingSupported() {
- return sDMAMultiplexingSupported;
-}
-
-inline bool Overlay::isUIScalingOnExternalSupported() {
- if(qdutils::MDPVersion::getInstance().is8x26() or
- qdutils::MDPVersion::getInstance().is8x16() or
- qdutils::MDPVersion::getInstance().is8x39()) {
- return false;
- }
- return true;
-}
-
-inline int Overlay::getDMAMode() {
- return sDMAMode;
-}
-
-inline int Overlay::getFbForDpy(const int& dpy) {
- OVASSERT(dpy >= 0 && dpy < DPY_MAX, "Invalid dpy %d", dpy);
- return sDpyFbMap[dpy];
-}
-
-inline int (*Overlay::getFnProgramScale())(struct mdp_overlay_list *) {
- return sFnProgramScale;
-}
-
-inline void Overlay::debugPipeLifecycle(const bool& enable) {
- sDebugPipeLifecycle = enable;
-}
-
-inline bool Overlay::isDebugPipeLifecycle() {
- return sDebugPipeLifecycle;
-}
-
-inline bool Overlay::PipeBook::valid() {
- return (mPipe != NULL);
-}
-
-inline bool Overlay::PipeBook::pipeUsageUnchanged() {
- return (sPipeUsageBitmap == sLastUsageBitmap);
-}
-
-inline void Overlay::PipeBook::setUse(int index) {
- sPipeUsageBitmap |= (1 << index);
-}
-
-inline void Overlay::PipeBook::resetUse(int index) {
- sPipeUsageBitmap &= ~(1 << index);
-}
-
-inline bool Overlay::PipeBook::isUsed(int index) {
- return sPipeUsageBitmap & (1 << index);
-}
-
-inline bool Overlay::PipeBook::isNotUsed(int index) {
- return !isUsed(index);
-}
-
-inline void Overlay::PipeBook::save() {
- sLastUsageBitmap = sPipeUsageBitmap;
-}
-
-inline void Overlay::PipeBook::setAllocation(int index) {
- sAllocatedBitmap |= (1 << index);
-}
-
-inline void Overlay::PipeBook::resetAllocation(int index) {
- sAllocatedBitmap &= ~(1 << index);
-}
-
-inline bool Overlay::PipeBook::isAllocated(int index) {
- return sAllocatedBitmap & (1 << index);
-}
-
-inline bool Overlay::PipeBook::isNotAllocated(int index) {
- return !isAllocated(index);
-}
-
-inline utils::eMdpPipeType Overlay::PipeBook::getPipeType(utils::eDest dest) {
- return pipeTypeLUT[(int)dest];
-}
-
-inline void Overlay::startSession(utils::eDest dest) {
- mPipeBook[(int)dest].mSession = PipeBook::START;
-}
-
-inline bool Overlay::sessionInProgress(utils::eDest dest) {
- return (mPipeBook[(int)dest].mSession == PipeBook::START);
-}
-
-inline bool Overlay::isSessionEnded(utils::eDest dest) {
- return (mPipeBook[(int)dest].mSession == PipeBook::END);
-}
-
-inline const char* Overlay::PipeBook::getDestStr(utils::eDest dest) {
- switch(getPipeType(dest)) {
- case utils::OV_MDP_PIPE_RGB: return "RGB";
- case utils::OV_MDP_PIPE_VG: return "VG";
- case utils::OV_MDP_PIPE_DMA: return "DMA";
- default: return "Invalid";
- }
- return "Invalid";
-}
-
-}; // overlay
-
-#endif // OVERLAY_H
diff --git a/msm8909/liboverlay/overlayCtrlData.h b/msm8909/liboverlay/overlayCtrlData.h
deleted file mode 100644
index 2eec98c..0000000
--- a/msm8909/liboverlay/overlayCtrlData.h
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
-* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef OVERLAY_CTRLDATA_H
-#define OVERLAY_CTRLDATA_H
-
-#include "overlayUtils.h"
-#include "overlayMdp.h"
-#include "gralloc_priv.h" // INTERLACE_MASK
-
-namespace ovutils = overlay::utils;
-
-namespace overlay {
-
-/*
-* Sequence to use:
-* init
-* start
-* setXXX
-* close
-* */
-class Ctrl : utils::NoCopy {
-public:
-
- /* ctor */
- explicit Ctrl(const int& dpy);
- /* dtor close */
- ~Ctrl();
-
- /* set source using whf, orient and wait flag */
- void setSource(const utils::PipeArgs& args);
- /* set crop info and pass it down to mdp */
- void setCrop(const utils::Dim& d);
- /* set color for mdp pipe */
- void setColor(const uint32_t color);
- /* set orientation */
- void setTransform(const utils::eTransform& p);
- /* set mdp position using dim */
- void setPosition(const utils::Dim& dim);
- /* set mdp visual params using metadata */
- bool setVisualParams(const MetaData_t &metadata);
- /* set pipe type RGB/DMA/VG */
- void setPipeType(const utils::eMdpPipeType& pType);
- /* mdp set overlay/commit changes */
- bool commit();
-
- /* ctrl id */
- int getPipeId() const;
- /* ctrl fd */
- int getFd() const;
- /* retrieve crop data */
- utils::Dim getCrop() const;
- utils::Dim getPosition() const;
- /* Update the src format based on rotator's dest */
- void updateSrcFormat(const uint32_t& rotDstFormat);
- /* return pipe priority */
- uint8_t getPriority() const;
- /* dump the state of the object */
- void dump() const;
- /* Return the dump in the specified buffer */
- void getDump(char *buf, size_t len);
-
- static bool validateAndSet(Ctrl* ctrlArray[], const int& count,
- const int& fbFd);
-private:
- // mdp ctrl struct(info e.g.)
- MdpCtrl *mMdp;
-};
-
-
-class Data : utils::NoCopy {
-public:
- /* init, reset */
- explicit Data(const int& dpy);
- /* calls close */
- ~Data();
- /* set overlay pipe id in the mdp struct */
- void setPipeId(int id);
- /* get overlay id in the mdp struct */
- int getPipeId() const;
- /* queue buffer to the overlay */
- bool queueBuffer(int fd, uint32_t offset);
- /* sump the state of the obj */
- void dump() const;
- /* Return the dump in the specified buffer */
- void getDump(char *buf, size_t len);
-
-private:
- // mdp data struct
- MdpData *mMdp;
-};
-
-//-------------Inlines-------------------------------
-
-inline Ctrl::Ctrl(const int& dpy) : mMdp(new MdpCtrl(dpy)) {
-}
-
-inline Ctrl::~Ctrl() {
- delete mMdp;
-}
-
-inline void Ctrl::setSource(const utils::PipeArgs& args)
-{
- mMdp->setSource(args);
-}
-
-inline void Ctrl::setPosition(const utils::Dim& dim)
-{
- mMdp->setPosition(dim);
-}
-
-inline void Ctrl::setTransform(const utils::eTransform& orient)
-{
- mMdp->setTransform(orient);
-}
-
-inline void Ctrl::setCrop(const utils::Dim& d)
-{
- mMdp->setCrop(d);
-}
-
-inline void Ctrl::setColor(const uint32_t color)
-{
- mMdp->setColor(color);
-}
-
-inline bool Ctrl::setVisualParams(const MetaData_t &metadata)
-{
- if (!mMdp->setVisualParams(metadata)) {
- ALOGE("Ctrl setVisualParams failed in MDP setVisualParams");
- return false;
- }
- return true;
-}
-
-inline void Ctrl::setPipeType(const utils::eMdpPipeType& pType)
-{
- mMdp->setPipeType(pType);
-}
-
-inline void Ctrl::dump() const {
- ALOGE("== Dump Ctrl start ==");
- mMdp->dump();
- ALOGE("== Dump Ctrl end ==");
-}
-
-inline bool Ctrl::commit() {
- if(!mMdp->set()) {
- ALOGE("Ctrl commit failed set overlay");
- return false;
- }
- return true;
-}
-
-inline int Ctrl::getPipeId() const {
- return mMdp->getPipeId();
-}
-
-inline int Ctrl::getFd() const {
- return mMdp->getFd();
-}
-
-inline void Ctrl::updateSrcFormat(const uint32_t& rotDstFmt) {
- mMdp->updateSrcFormat(rotDstFmt);
-}
-
-inline bool Ctrl::validateAndSet(Ctrl* ctrlArray[], const int& count,
- const int& fbFd) {
- MdpCtrl* mdpCtrlArray[count];
- memset(&mdpCtrlArray, 0, sizeof(mdpCtrlArray));
-
- for(int i = 0; i < count; i++) {
- mdpCtrlArray[i] = ctrlArray[i]->mMdp;
- }
-
- bool ret = MdpCtrl::validateAndSet(mdpCtrlArray, count, fbFd);
- return ret;
-}
-
-inline utils::Dim Ctrl::getCrop() const {
- return mMdp->getSrcRectDim();
-}
-
-inline utils::Dim Ctrl::getPosition() const {
- return mMdp->getDstRectDim();
-}
-
-inline uint8_t Ctrl::getPriority() const {
- return mMdp->getPriority();
-}
-
-inline void Ctrl::getDump(char *buf, size_t len) {
- mMdp->getDump(buf, len);
-}
-
-inline Data::Data(const int& dpy) : mMdp(new MdpData(dpy)) {
-}
-
-inline Data::~Data() {
- delete mMdp;
-}
-
-inline void Data::setPipeId(int id) { mMdp->setPipeId(id); }
-
-inline int Data::getPipeId() const { return mMdp->getPipeId(); }
-
-inline bool Data::queueBuffer(int fd, uint32_t offset) {
- return mMdp->play(fd, offset);
-}
-
-inline void Data::dump() const {
- ALOGE("== Dump Data MDP start ==");
- mMdp->dump();
- ALOGE("== Dump Data MDP end ==");
-}
-
-inline void Data::getDump(char *buf, size_t len) {
- mMdp->getDump(buf, len);
-}
-
-} // overlay
-
-#endif
diff --git a/msm8909/liboverlay/overlayMdp.cpp b/msm8909/liboverlay/overlayMdp.cpp
deleted file mode 100644
index d52864e..0000000
--- a/msm8909/liboverlay/overlayMdp.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
-* Copyright (C) 2008 The Android Open Source Project
-* Copyright (c) 2010-2014, The Linux Foundation. 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 <math.h>
-#include <mdp_version.h>
-#include "overlayUtils.h"
-#include "overlayMdp.h"
-#include "mdp_version.h"
-#include <overlay.h>
-
-#define HSIC_SETTINGS_DEBUG 0
-
-using namespace qdutils;
-
-namespace ovutils = overlay::utils;
-namespace overlay {
-
-bool MdpCtrl::init(const int& dpy) {
- int fbnum = Overlay::getFbForDpy(dpy);
- if( fbnum < 0 ) {
- ALOGE("%s: Invalid FB for the display: %d",__FUNCTION__, dpy);
- return false;
- }
-
- // FD init
- if(!utils::openDev(mFd, fbnum,
- Res::fbPath, O_RDWR)){
- ALOGE("Ctrl failed to init fbnum=%d", fbnum);
- return false;
- }
- mDpy = dpy;
- return true;
-}
-
-void MdpCtrl::reset() {
- utils::memset0(mOVInfo);
- mOVInfo.id = MSMFB_NEW_REQUEST;
- mOrientation = utils::OVERLAY_TRANSFORM_0;
- mDpy = 0;
-#ifdef USES_POST_PROCESSING
- memset(&mParams, 0, sizeof(struct compute_params));
- mParams.params.conv_params.order = hsic_order_hsc_i;
- mParams.params.conv_params.interface = interface_rec601;
- mParams.params.conv_params.cc_matrix[0][0] = 1;
- mParams.params.conv_params.cc_matrix[1][1] = 1;
- mParams.params.conv_params.cc_matrix[2][2] = 1;
-#endif
-}
-
-bool MdpCtrl::close() {
- bool result = true;
- if(MSMFB_NEW_REQUEST != static_cast<int>(mOVInfo.id)) {
- if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) {
- ALOGE("MdpCtrl close error in unset");
- result = false;
- }
- }
-#ifdef USES_POST_PROCESSING
- /* free allocated memory in PP */
- if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data)
- free(mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data);
-#endif
- reset();
-
- if(!mFd.close()) {
- result = false;
- }
-
- return result;
-}
-
-void MdpCtrl::setSource(const utils::PipeArgs& args) {
- setSrcWhf(args.whf);
-
- //TODO These are hardcoded. Can be moved out of setSource.
- mOVInfo.transp_mask = 0xffffffff;
-
- //TODO These calls should ideally be a part of setPipeParams API
- setFlags(args.mdpFlags);
- setZ(args.zorder);
- setPlaneAlpha(args.planeAlpha);
- setBlending(args.blending);
-}
-
-void MdpCtrl::setCrop(const utils::Dim& d) {
- setSrcRectDim(d);
-}
-
-void MdpCtrl::setColor(const uint32_t color) {
- mOVInfo.bg_color = color;
-}
-
-void MdpCtrl::setPosition(const overlay::utils::Dim& d) {
- setDstRectDim(d);
-}
-
-void MdpCtrl::setTransform(const utils::eTransform& orient) {
- int rot = utils::getMdpOrient(orient);
- setUserData(rot);
- mOrientation = static_cast<utils::eTransform>(rot);
-}
-
-void MdpCtrl::setPipeType(const utils::eMdpPipeType& pType){
- switch((int) pType){
- case utils::OV_MDP_PIPE_RGB:
- mOVInfo.pipe_type = PIPE_TYPE_RGB;
- break;
- case utils::OV_MDP_PIPE_VG:
- mOVInfo.pipe_type = PIPE_TYPE_VIG;
- break;
- case utils::OV_MDP_PIPE_DMA:
- mOVInfo.pipe_type = PIPE_TYPE_DMA;
- break;
- default:
- mOVInfo.pipe_type = PIPE_TYPE_AUTO;
- break;
- }
-}
-
-void MdpCtrl::doTransform() {
- setRotationFlags();
- utils::Whf whf = getSrcWhf();
- utils::Dim dim = getSrcRectDim();
- utils::preRotateSource(mOrientation, whf, dim);
- setSrcWhf(whf);
- setSrcRectDim(dim);
-}
-
-void MdpCtrl::doDownscale() {
- if(MDPVersion::getInstance().supportsDecimation()) {
- utils::getDecimationFactor(mOVInfo.src_rect.w, mOVInfo.src_rect.h,
- mOVInfo.dst_rect.w, mOVInfo.dst_rect.h, mOVInfo.horz_deci,
- mOVInfo.vert_deci);
- }
-}
-
-bool MdpCtrl::set() {
- int mdpVersion = MDPVersion::getInstance().getMDPVersion();
- //deferred calcs, so APIs could be called in any order.
- doTransform();
- utils::Whf whf = getSrcWhf();
- if(utils::isYuv(whf.format)) {
- utils::normalizeCrop(mOVInfo.src_rect.x, mOVInfo.src_rect.w);
- utils::normalizeCrop(mOVInfo.src_rect.y, mOVInfo.src_rect.h);
- if(mdpVersion < MDSS_V5) {
- utils::even_floor(mOVInfo.dst_rect.w);
- utils::even_floor(mOVInfo.dst_rect.h);
- } else if (mOVInfo.flags & MDP_DEINTERLACE) {
- // For interlaced, crop.h should be 4-aligned
- if (!(mOVInfo.flags & MDP_SOURCE_ROTATED_90) &&
- (mOVInfo.src_rect.h % 4))
- mOVInfo.src_rect.h = utils::aligndown(mOVInfo.src_rect.h, 4);
- // For interlaced, width must be multiple of 4 when rotated 90deg.
- else if ((mOVInfo.flags & MDP_SOURCE_ROTATED_90) &&
- (mOVInfo.src_rect.w % 4))
- mOVInfo.src_rect.w = utils::aligndown(mOVInfo.src_rect.w, 4);
- }
- } else {
- // On 8974 and 8x26, there is a limitation of 1-pixel down-scaling
- if (mdpVersion >= MDSS_V5) {
- if(qdutils::MDPVersion::getInstance().is8x74v2() ||
- qdutils::MDPVersion::getInstance().is8x26()) {
- if (mOVInfo.src_rect.w - mOVInfo.dst_rect.w == 1)
- mOVInfo.src_rect.w -= 1;
- if (mOVInfo.src_rect.h - mOVInfo.dst_rect.h == 1)
- mOVInfo.src_rect.h -= 1;
- }
- }
- }
-
- doDownscale();
- return true;
-}
-
-//Update src format based on rotator's destination format.
-void MdpCtrl::updateSrcFormat(const uint32_t& rotDestFmt) {
- utils::Whf whf = getSrcWhf();
- whf.format = rotDestFmt;
- setSrcWhf(whf);
-}
-
-void MdpCtrl::dump() const {
- ALOGE("== Dump MdpCtrl start ==");
- mFd.dump();
- mdp_wrapper::dump("mOVInfo", mOVInfo);
- ALOGE("== Dump MdpCtrl end ==");
-}
-
-void MdpCtrl::getDump(char *buf, size_t len) {
- ovutils::getDump(buf, len, "Ctrl", mOVInfo);
-}
-
-void MdpData::dump() const {
- ALOGE("== Dump MdpData start ==");
- mFd.dump();
- mdp_wrapper::dump("mOvData", mOvData);
- ALOGE("== Dump MdpData end ==");
-}
-
-void MdpData::getDump(char *buf, size_t len) {
- ovutils::getDump(buf, len, "Data", mOvData);
-}
-
-bool MdpCtrl::setVisualParams(const MetaData_t& data) {
- ALOGD_IF(0, "In %s: data.operation = %d", __FUNCTION__, data.operation);
-
- // Set Color Space for MDP to configure CSC matrix
- mOVInfo.color_space = ITU_R_601;
- if (data.operation & UPDATE_COLOR_SPACE) {
- mOVInfo.color_space = data.colorSpace;
- }
-
-#ifdef USES_POST_PROCESSING
- bool needUpdate = false;
- /* calculate the data */
- if (data.operation & PP_PARAM_HSIC) {
- if (mParams.params.pa_params.hue != data.hsicData.hue) {
- ALOGD_IF(HSIC_SETTINGS_DEBUG,
- "Hue has changed from %d to %d",
- mParams.params.pa_params.hue,data.hsicData.hue);
- needUpdate = true;
- }
-
- if (!isEqual(mParams.params.pa_params.sat,
- data.hsicData.saturation)) {
- ALOGD_IF(HSIC_SETTINGS_DEBUG,
- "Saturation has changed from %f to %f",
- mParams.params.pa_params.sat,
- data.hsicData.saturation);
- needUpdate = true;
- }
-
- if (mParams.params.pa_params.intensity != data.hsicData.intensity) {
- ALOGD_IF(HSIC_SETTINGS_DEBUG,
- "Intensity has changed from %d to %d",
- mParams.params.pa_params.intensity,
- data.hsicData.intensity);
- needUpdate = true;
- }
-
- if (!isEqual(mParams.params.pa_params.contrast,
- data.hsicData.contrast)) {
- ALOGD_IF(HSIC_SETTINGS_DEBUG,
- "Contrast has changed from %f to %f",
- mParams.params.pa_params.contrast,
- data.hsicData.contrast);
- needUpdate = true;
- }
-
- if (needUpdate) {
- mParams.params.pa_params.hue = data.hsicData.hue;
- mParams.params.pa_params.sat = data.hsicData.saturation;
- mParams.params.pa_params.intensity = data.hsicData.intensity;
- mParams.params.pa_params.contrast = data.hsicData.contrast;
- mParams.params.pa_params.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
- mParams.operation |= PP_OP_PA;
- }
- }
-
- if (data.operation & PP_PARAM_SHARP2) {
- if (mParams.params.sharp_params.strength != data.Sharp2Data.strength) {
- needUpdate = true;
- }
- if (mParams.params.sharp_params.edge_thr != data.Sharp2Data.edge_thr) {
- needUpdate = true;
- }
- if (mParams.params.sharp_params.smooth_thr !=
- data.Sharp2Data.smooth_thr) {
- needUpdate = true;
- }
- if (mParams.params.sharp_params.noise_thr !=
- data.Sharp2Data.noise_thr) {
- needUpdate = true;
- }
-
- if (needUpdate) {
- mParams.params.sharp_params.strength = data.Sharp2Data.strength;
- mParams.params.sharp_params.edge_thr = data.Sharp2Data.edge_thr;
- mParams.params.sharp_params.smooth_thr =
- data.Sharp2Data.smooth_thr;
- mParams.params.sharp_params.noise_thr = data.Sharp2Data.noise_thr;
- mParams.params.sharp_params.ops =
- MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
- mParams.operation |= PP_OP_SHARP;
- }
- }
-
- if (data.operation & PP_PARAM_IGC) {
- if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data == NULL){
- uint32_t *igcData
- = (uint32_t *)malloc(2 * MAX_IGC_LUT_ENTRIES * sizeof(uint32_t));
- if (!igcData) {
- ALOGE("IGC storage allocated failed");
- return false;
- }
- mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data = igcData;
- mOVInfo.overlay_pp_cfg.igc_cfg.c2_data
- = igcData + MAX_IGC_LUT_ENTRIES;
- }
-
- memcpy(mParams.params.igc_lut_params.c0,
- data.igcData.c0, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
- memcpy(mParams.params.igc_lut_params.c1,
- data.igcData.c1, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
- memcpy(mParams.params.igc_lut_params.c2,
- data.igcData.c2, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
-
- mParams.params.igc_lut_params.ops
- = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
- mParams.operation |= PP_OP_IGC;
- needUpdate = true;
- }
-
- if (data.operation & PP_PARAM_VID_INTFC) {
- mParams.params.conv_params.interface =
- (interface_type) data.video_interface;
- needUpdate = true;
- }
-
- if (needUpdate) {
- display_pp_compute_params(&mParams, &mOVInfo.overlay_pp_cfg);
- }
-#endif
- return true;
-}
-
-bool MdpCtrl::validateAndSet(MdpCtrl* mdpCtrlArray[], const int& count,
- const int& fbFd) {
- mdp_overlay* ovArray[count];
- memset(&ovArray, 0, sizeof(ovArray));
-
- for(int i = 0; i < count; i++) {
- ovArray[i] = &mdpCtrlArray[i]->mOVInfo;
- }
-
- struct mdp_overlay_list list;
- memset(&list, 0, sizeof(struct mdp_overlay_list));
- list.num_overlays = count;
- list.overlay_list = ovArray;
-
- int (*fnProgramScale)(struct mdp_overlay_list *) =
- Overlay::getFnProgramScale();
- if(fnProgramScale) {
- fnProgramScale(&list);
- }
-
- // Error value is based on file errno-base.h
- // 0 - indicates no error.
- int errVal = mdp_wrapper::validateAndSet(fbFd, list);
- if(errVal) {
- /* No dump for failure due to insufficient resource */
- if(errVal != E2BIG) {
- mdp_wrapper::dump("Bad ov dump: ",
- *list.overlay_list[list.processed_overlays]);
- }
- return false;
- }
-
- return true;
-}
-
-
-//// MdpData ////////////
-bool MdpData::init(const int& dpy) {
- int fbnum = Overlay::getFbForDpy(dpy);
- if( fbnum < 0 ) {
- ALOGE("%s: Invalid FB for the display: %d",__FUNCTION__, dpy);
- return false;
- }
-
- // FD init
- if(!utils::openDev(mFd, fbnum, Res::fbPath, O_RDWR)){
- ALOGE("Ctrl failed to init fbnum=%d", fbnum);
- return false;
- }
- return true;
-}
-
-} // overlay
diff --git a/msm8909/liboverlay/overlayMdp.h b/msm8909/liboverlay/overlayMdp.h
deleted file mode 100644
index faed1ef..0000000
--- a/msm8909/liboverlay/overlayMdp.h
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
-* Copyright (C) 2008 The Android Open Source Project
-* Copyright (c) 2010-2013, The Linux Foundation. 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 OVERLAY_MDP_H
-#define OVERLAY_MDP_H
-
-#include <linux/msm_mdp.h>
-
-#include "overlayUtils.h"
-#include "mdpWrapper.h"
-#include "qdMetaData.h"
-#ifdef USES_POST_PROCESSING
-#include "lib-postproc.h"
-#endif
-
-namespace overlay{
-
-/*
-* Mdp Ctrl holds corresponding fd and MDP related struct.
-* It is simple wrapper to MDP services
-* */
-class MdpCtrl {
-public:
- /* ctor reset */
- explicit MdpCtrl(const int& dpy);
- /* dtor close */
- ~MdpCtrl();
- /* init underlying device using fbnum for dpy */
- bool init(const int& dpy);
- /* unset overlay, reset and close fd */
- bool close();
- /* reset and set ov id to -1 / MSMFB_NEW_REQUEST */
- void reset();
- /* calls overlay set
- * Set would always consult last good known ov instance.
- * Only if it is different, set would actually exectue ioctl.
- * On a sucess ioctl. last good known ov instance is updated */
- bool set();
- /* Sets the source total width, height, format */
- void setSource(const utils::PipeArgs& pargs);
- /*
- * Sets ROI, the unpadded region, for source buffer.
- * Dim - ROI dimensions.
- */
- void setCrop(const utils::Dim& d);
- /* set color for mdp pipe */
- void setColor(const uint32_t color);
- void setTransform(const utils::eTransform& orient);
- /* given a dim and w/h, set overlay dim */
- void setPosition(const utils::Dim& dim);
- /* using user_data, sets/unsets roationvalue in mdp flags */
- void setRotationFlags();
- /* Update the src format with rotator's dest*/
- void updateSrcFormat(const uint32_t& rotDstFormat);
- /* dump state of the object */
- void dump() const;
- /* Return the dump in the specified buffer */
- void getDump(char *buf, size_t len);
- /* returns session id */
- int getPipeId() const;
- /* returns the fd associated to ctrl*/
- int getFd() const;
- /* returns a copy ro dst rect dim */
- utils::Dim getDstRectDim() const;
- /* returns a copy to src rect dim */
- utils::Dim getSrcRectDim() const;
- /* return pipe priority */
- uint8_t getPriority() const;
- /* setVisualParam */
- bool setVisualParams(const MetaData_t& data);
- /* sets pipe type RGB/DMA/VG */
- void setPipeType(const utils::eMdpPipeType& pType);
-
- static bool validateAndSet(MdpCtrl* mdpCtrlArray[], const int& count,
- const int& fbFd);
-private:
- /* Perform transformation calculations */
- void doTransform();
- void doDownscale();
- /* get orient / user_data[0] */
- int getOrient() const;
- /* returns flags from mdp structure */
- int getFlags() const;
- /* set flags to mdp structure */
- void setFlags(int f);
- /* set z order */
- void setZ(utils::eZorder z);
- /* return a copy of src whf*/
- utils::Whf getSrcWhf() const;
- /* set plane alpha */
- void setPlaneAlpha(int planeAlpha);
- /* set blending method */
- void setBlending(overlay::utils::eBlending blending);
-
- /* set src whf */
- void setSrcWhf(const utils::Whf& whf);
- /* set src/dst rect dim */
- void setSrcRectDim(const utils::Dim d);
- void setDstRectDim(const utils::Dim d);
- /* returns user_data[0]*/
- int getUserData() const;
- /* sets user_data[0] */
- void setUserData(int v);
-
- utils::eTransform mOrientation; //Holds requested orientation
- /* Actual overlay mdp structure */
- mdp_overlay mOVInfo;
- /* FD for the mdp fbnum */
- OvFD mFd;
- int mDpy;
-
-#ifdef USES_POST_PROCESSING
- /* PP Compute Params */
- struct compute_params mParams;
-#endif
-};
-
-/* MDP data */
-class MdpData {
-public:
- /* ctor reset data */
- explicit MdpData(const int& dpy);
- /* dtor close*/
- ~MdpData();
- /* init FD */
- bool init(const int& dpy);
- /* memset0 the underlying mdp object */
- void reset();
- /* close fd, and reset */
- bool close();
- /* set id of mdp data */
- void setPipeId(int id);
- /* return ses id of data */
- int getPipeId() const;
- /* get underlying fd*/
- int getFd() const;
- /* get memory_id */
- int getSrcMemoryId() const;
- /* calls wrapper play */
- bool play(int fd, uint32_t offset);
- /* dump state of the object */
- void dump() const;
- /* Return the dump in the specified buffer */
- void getDump(char *buf, size_t len);
-
-private:
-
- /* actual overlay mdp data */
- msmfb_overlay_data mOvData;
- /* fd to mdp fbnum */
- OvFD mFd;
-};
-
-//--------------Inlines---------------------------------
-
-///// MdpCtrl //////
-
-inline MdpCtrl::MdpCtrl(const int& dpy) {
- reset();
- init(dpy);
-}
-
-inline MdpCtrl::~MdpCtrl() {
- close();
-}
-
-inline int MdpCtrl::getOrient() const {
- return getUserData();
-}
-
-inline int MdpCtrl::getPipeId() const {
- return mOVInfo.id;
-}
-
-inline int MdpCtrl::getFd() const {
- return mFd.getFD();
-}
-
-inline int MdpCtrl::getFlags() const {
- return mOVInfo.flags;
-}
-
-inline void MdpCtrl::setFlags(int f) {
- mOVInfo.flags = f;
-}
-
-inline void MdpCtrl::setZ(overlay::utils::eZorder z) {
- mOVInfo.z_order = z;
-}
-
-inline void MdpCtrl::setPlaneAlpha(int planeAlpha) {
- mOVInfo.alpha = planeAlpha;
-}
-
-inline void MdpCtrl::setBlending(overlay::utils::eBlending blending) {
- switch((int) blending) {
- case utils::OVERLAY_BLENDING_OPAQUE:
- mOVInfo.blend_op = BLEND_OP_OPAQUE;
- break;
- case utils::OVERLAY_BLENDING_PREMULT:
- mOVInfo.blend_op = BLEND_OP_PREMULTIPLIED;
- break;
- case utils::OVERLAY_BLENDING_COVERAGE:
- default:
- mOVInfo.blend_op = BLEND_OP_COVERAGE;
- }
-}
-
-inline overlay::utils::Whf MdpCtrl::getSrcWhf() const {
- return utils::Whf( mOVInfo.src.width,
- mOVInfo.src.height,
- mOVInfo.src.format);
-}
-
-inline void MdpCtrl::setSrcWhf(const overlay::utils::Whf& whf) {
- mOVInfo.src.width = whf.w;
- mOVInfo.src.height = whf.h;
- mOVInfo.src.format = whf.format;
-}
-
-inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const {
- return utils::Dim( mOVInfo.src_rect.x,
- mOVInfo.src_rect.y,
- mOVInfo.src_rect.w,
- mOVInfo.src_rect.h);
-}
-
-inline void MdpCtrl::setSrcRectDim(const overlay::utils::Dim d) {
- mOVInfo.src_rect.x = d.x;
- mOVInfo.src_rect.y = d.y;
- mOVInfo.src_rect.w = d.w;
- mOVInfo.src_rect.h = d.h;
-}
-
-inline overlay::utils::Dim MdpCtrl::getDstRectDim() const {
- return utils::Dim( mOVInfo.dst_rect.x,
- mOVInfo.dst_rect.y,
- mOVInfo.dst_rect.w,
- mOVInfo.dst_rect.h);
-}
-
-inline void MdpCtrl::setDstRectDim(const overlay::utils::Dim d) {
- mOVInfo.dst_rect.x = d.x;
- mOVInfo.dst_rect.y = d.y;
- mOVInfo.dst_rect.w = d.w;
- mOVInfo.dst_rect.h = d.h;
-}
-
-inline int MdpCtrl::getUserData() const { return mOVInfo.user_data[0]; }
-
-inline void MdpCtrl::setUserData(int v) { mOVInfo.user_data[0] = v; }
-
-inline void MdpCtrl::setRotationFlags() {
- const int u = getUserData();
- if (u & MDP_ROT_90)
- mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
-}
-
-inline uint8_t MdpCtrl::getPriority() const {
- return mOVInfo.priority;
-}
-
-/////// MdpData //////
-
-inline MdpData::MdpData(const int& dpy) {
- reset();
- init(dpy);
-}
-
-inline MdpData::~MdpData() { close(); }
-
-inline void MdpData::reset() {
- overlay::utils::memset0(mOvData);
- mOvData.data.memory_id = -1;
-}
-
-inline bool MdpData::close() {
- reset();
- return mFd.close();
-}
-
-inline int MdpData::getSrcMemoryId() const { return mOvData.data.memory_id; }
-
-inline void MdpData::setPipeId(int id) { mOvData.id = id; }
-
-inline int MdpData::getPipeId() const { return mOvData.id; }
-
-inline int MdpData::getFd() const { return mFd.getFD(); }
-
-inline bool MdpData::play(int fd, uint32_t offset) {
- mOvData.data.memory_id = fd;
- mOvData.data.offset = offset;
- if(!mdp_wrapper::play(mFd.getFD(), mOvData)){
- ALOGE("MdpData failed to play");
- dump();
- return false;
- }
- return true;
-}
-
-} // overlay
-
-inline bool isEqual(float f1, float f2) {
- return ((int)(f1*100) == (int)(f2*100)) ? true : false;
-}
-
-#endif // OVERLAY_MDP_H
diff --git a/msm8909/liboverlay/overlayMdpRot.cpp b/msm8909/liboverlay/overlayMdpRot.cpp
deleted file mode 100755
index d322897..0000000
--- a/msm8909/liboverlay/overlayMdpRot.cpp
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 <math.h>
-#include "overlayUtils.h"
-#include "overlayRotator.h"
-#include "gr.h"
-
-namespace ovutils = overlay::utils;
-
-namespace overlay {
-
-MdpRot::MdpRot() {
- reset();
- init();
-}
-
-MdpRot::~MdpRot() { close(); }
-
-bool MdpRot::enabled() const { return mRotImgInfo.enable; }
-
-void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = (uint8_t)r; }
-
-int MdpRot::getSrcMemId() const {
- return mRotDataInfo.src.memory_id;
-}
-
-int MdpRot::getDstMemId() const {
- return mRotDataInfo.dst.memory_id;
-}
-
-uint32_t MdpRot::getSrcOffset() const {
- return mRotDataInfo.src.offset;
-}
-
-uint32_t MdpRot::getDstOffset() const {
- return mRotDataInfo.dst.offset;
-}
-
-uint32_t MdpRot::getDstFormat() const {
- return mRotImgInfo.dst.format;
-}
-
-//Added for completeness. Not expected to be called.
-utils::Whf MdpRot::getDstWhf() const {
- int alW = 0, alH = 0;
- int halFormat = ovutils::getHALFormat(mRotImgInfo.dst.format);
- getBufferSizeAndDimensions(mRotImgInfo.dst.width, mRotImgInfo.dst.height,
- halFormat, alW, alH);
- return utils::Whf(alW, alH, mRotImgInfo.dst.format);
-}
-
-//Added for completeness. Not expected to be called.
-utils::Dim MdpRot::getDstDimensions() const {
- int alW = 0, alH = 0;
- int halFormat = ovutils::getHALFormat(mRotImgInfo.dst.format);
- getBufferSizeAndDimensions(mRotImgInfo.dst.width, mRotImgInfo.dst.height,
- halFormat, alW, alH);
- return utils::Dim(0, 0, alW, alH);
-}
-
-uint32_t MdpRot::getSessId() const { return mRotImgInfo.session_id; }
-
-void MdpRot::setDownscale(int ds) {
- if ((utils::ROT_DS_EIGHTH == ds) && (mRotImgInfo.src_rect.h & 0xF)) {
- // Ensure src_rect.h is a multiple of 16 for 1/8 downscaling.
- // This is an undocumented MDP Rotator constraint.
- mRotImgInfo.src_rect.h = utils::aligndown(mRotImgInfo.src_rect.h, 16);
- }
- mRotImgInfo.downscale_ratio = ds;
-}
-
-void MdpRot::save() {
- mLSRotImgInfo = mRotImgInfo;
-}
-
-bool MdpRot::rotConfChanged() const {
- // 0 means same
- if(0 == ::memcmp(&mRotImgInfo, &mLSRotImgInfo,
- sizeof (msm_rotator_img_info))) {
- return false;
- }
- return true;
-}
-
-bool MdpRot::init()
-{
- if(!mFd.open(Res::rotPath, O_RDWR)){
- ALOGE("MdpRot failed to init %s", Res::rotPath);
- return false;
- }
- return true;
-}
-
-void MdpRot::setSource(const overlay::utils::Whf& awhf) {
- utils::Whf whf(awhf);
- mRotImgInfo.src.format = whf.format;
-
- mRotImgInfo.src.width = whf.w;
- mRotImgInfo.src.height = whf.h;
-
- mRotImgInfo.src_rect.w = whf.w;
- mRotImgInfo.src_rect.h = whf.h;
-
- mRotImgInfo.dst.width = whf.w;
- mRotImgInfo.dst.height = whf.h;
-}
-
-void MdpRot::setCrop(const utils::Dim& /*crop*/) {
- // NO-OP for non-mdss rotator due to possible h/w limitations
-}
-
-void MdpRot::setFlags(const utils::eMdpFlags& flags) {
- mRotImgInfo.secure = 0;
- if(flags & utils::OV_MDP_SECURE_OVERLAY_SESSION)
- mRotImgInfo.secure = 1;
-}
-
-void MdpRot::setTransform(const utils::eTransform& rot)
-{
- int r = utils::getMdpOrient(rot);
- setRotations(r);
- mOrientation = static_cast<utils::eTransform>(r);
- ALOGE_IF(DEBUG_OVERLAY, "%s: r=%d", __FUNCTION__, r);
-}
-
-void MdpRot::doTransform() {
- if(mOrientation & utils::OVERLAY_TRANSFORM_ROT_90)
- utils::swap(mRotImgInfo.dst.width, mRotImgInfo.dst.height);
-}
-
-bool MdpRot::commit() {
- doTransform();
- if(rotConfChanged()) {
- mRotImgInfo.enable = 1;
- if(!overlay::mdp_wrapper::startRotator(mFd.getFD(), mRotImgInfo)) {
- ALOGE("MdpRot commit failed");
- dump();
- mRotImgInfo.enable = 0;
- return false;
- }
- mRotDataInfo.session_id = mRotImgInfo.session_id;
- }
- return true;
-}
-
-uint32_t MdpRot::calcOutputBufSize() {
- ovutils::Whf destWhf(mRotImgInfo.dst.width,
- mRotImgInfo.dst.height, mRotImgInfo.dst.format);
- return Rotator::calcOutputBufSize(destWhf);
-}
-
-bool MdpRot::open_i(uint32_t numbufs, uint32_t bufsz)
-{
- OvMem mem;
-
- OVASSERT(MAP_FAILED == mem.addr(), "MAP failed in open_i");
-
- if(!mem.open(numbufs, bufsz, mRotImgInfo.secure)){
- ALOGE("%s: Failed to open", __func__);
- mem.close();
- return false;
- }
-
- OVASSERT(MAP_FAILED != mem.addr(), "MAP failed");
- OVASSERT(mem.getFD() != -1, "getFd is -1");
-
- mRotDataInfo.dst.memory_id = mem.getFD();
- mRotDataInfo.dst.offset = 0;
- mMem.mem = mem;
- return true;
-}
-
-bool MdpRot::close() {
- bool success = true;
- if(mFd.valid() && (getSessId() != 0)) {
- if(!mdp_wrapper::endRotator(mFd.getFD(), getSessId())) {
- ALOGE("Mdp Rot error endRotator, fd=%d sessId=%u",
- mFd.getFD(), getSessId());
- success = false;
- }
- }
- if (!mFd.close()) {
- ALOGE("Mdp Rot error closing fd");
- success = false;
- }
- if (!mMem.close()) {
- ALOGE("Mdp Rot error closing mem");
- success = false;
- }
- reset();
- return success;
-}
-
-bool MdpRot::remap(uint32_t numbufs) {
- // if current size changed, remap
- uint32_t opBufSize = calcOutputBufSize();
- if(opBufSize == mMem.size()) {
- ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, opBufSize);
- return true;
- }
-
- if(!mMem.close()) {
- ALOGE("%s error in closing prev rot mem", __FUNCTION__);
- return false;
- }
-
- ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__);
-
- if(!open_i(numbufs, opBufSize)) {
- ALOGE("%s Error could not open", __FUNCTION__);
- return false;
- }
-
- for (uint32_t i = 0; i < numbufs; ++i) {
- mMem.mRotOffset[i] = i * opBufSize;
- }
-
- return true;
-}
-
-void MdpRot::reset() {
- ovutils::memset0(mRotImgInfo);
- ovutils::memset0(mLSRotImgInfo);
- ovutils::memset0(mRotDataInfo);
- ovutils::memset0(mMem.mRotOffset);
- mMem.mCurrIndex = 0;
- mOrientation = utils::OVERLAY_TRANSFORM_0;
-}
-
-bool MdpRot::queueBuffer(int fd, uint32_t offset) {
- if(enabled() and (not isRotCached(fd,offset))) {
- int prev_fd = getSrcMemId();
- uint32_t prev_offset = getSrcOffset();
-
- mRotDataInfo.src.memory_id = fd;
- mRotDataInfo.src.offset = offset;
-
- if(false == remap(RotMem::ROT_NUM_BUFS)) {
- ALOGE("%s Remap failed, not queueing", __FUNCTION__);
- return false;
- }
-
- mRotDataInfo.dst.offset =
- mMem.mRotOffset[mMem.mCurrIndex];
-
- if(!overlay::mdp_wrapper::rotate(mFd.getFD(), mRotDataInfo)) {
- ALOGE("MdpRot failed rotate");
- dump();
- mRotDataInfo.src.memory_id = prev_fd;
- mRotDataInfo.src.offset = prev_offset;
- return false;
- }
- save();
- mMem.mCurrIndex =
- (mMem.mCurrIndex + 1) % mMem.mem.numBufs();
- }
- return true;
-}
-
-void MdpRot::dump() const {
- ALOGE("== Dump MdpRot start ==");
- mFd.dump();
- mMem.mem.dump();
- mdp_wrapper::dump("mRotImgInfo", mRotImgInfo);
- mdp_wrapper::dump("mRotDataInfo", mRotDataInfo);
- ALOGE("== Dump MdpRot end ==");
-}
-
-void MdpRot::getDump(char *buf, size_t len) const {
- ovutils::getDump(buf, len, "MdpRotCtrl", mRotImgInfo);
- ovutils::getDump(buf, len, "MdpRotData", mRotDataInfo);
-}
-
-int MdpRot::getDownscaleFactor(const int& src_w, const int& src_h,
- const int& dst_w, const int& dst_h, const uint32_t& /*mdpFormat*/,
- const bool& /*isInterlaced*/) {
- int dscale_factor = utils::ROT_DS_NONE;
- // We need this check to engage the rotator whenever possible to assist MDP
- // in performing video downscale.
- // This saves bandwidth and avoids causing the driver to make too many panel
- // -mode switches between BLT (writeback) and non-BLT (Direct) modes.
- // Use-case: Video playback [with downscaling and rotation].
- if (dst_w && dst_h)
- {
- float fDscale = (float)(src_w * src_h) / (float)(dst_w * dst_h);
- uint32_t dscale = (int)sqrtf(fDscale);
-
- if(dscale < 2) {
- // Down-scale to > 50% of orig.
- dscale_factor = utils::ROT_DS_NONE;
- } else if(dscale < 4) {
- // Down-scale to between > 25% to <= 50% of orig.
- dscale_factor = utils::ROT_DS_HALF;
- } else if(dscale < 8) {
- // Down-scale to between > 12.5% to <= 25% of orig.
- dscale_factor = utils::ROT_DS_FOURTH;
- } else {
- // Down-scale to <= 12.5% of orig.
- dscale_factor = utils::ROT_DS_EIGHTH;
- }
- }
- return dscale_factor;
-}
-
-} // namespace overlay
diff --git a/msm8909/liboverlay/overlayMdssRot.cpp b/msm8909/liboverlay/overlayMdssRot.cpp
deleted file mode 100644
index 87e134a..0000000
--- a/msm8909/liboverlay/overlayMdssRot.cpp
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 <math.h>
-#include "overlayUtils.h"
-#include "overlayRotator.h"
-
-#define DEBUG_MDSS_ROT 0
-
-#ifdef VENUS_COLOR_FORMAT
-#include <media/msm_media_info.h>
-#else
-#define VENUS_BUFFER_SIZE(args...) 0
-#endif
-
-#ifndef MDSS_MDP_ROT_ONLY
-#define MDSS_MDP_ROT_ONLY 0x80
-#endif
-
-#define MDSS_ROT_MASK (MDP_ROT_90 | MDP_FLIP_UD | MDP_FLIP_LR)
-
-namespace ovutils = overlay::utils;
-
-namespace overlay {
-using namespace utils;
-
-MdssRot::MdssRot() {
- reset();
- init();
-}
-
-MdssRot::~MdssRot() { close(); }
-
-bool MdssRot::enabled() const { return mEnabled; }
-
-void MdssRot::setRotations(uint32_t flags) { mRotInfo.flags |= flags; }
-
-int MdssRot::getSrcMemId() const {
- return mRotData.data.memory_id;
-}
-
-int MdssRot::getDstMemId() const {
- return mRotData.dst_data.memory_id;
-}
-
-uint32_t MdssRot::getSrcOffset() const {
- return mRotData.data.offset;
-}
-
-uint32_t MdssRot::getDstOffset() const {
- return mRotData.dst_data.offset;
-}
-
-uint32_t MdssRot::getDstFormat() const {
- //For mdss src and dst formats are same
- return mRotInfo.src.format;
-}
-
-utils::Whf MdssRot::getDstWhf() const {
- //For Mdss dst_rect itself represents buffer dimensions. We ignore actual
- //aligned values during buffer allocation. Also the driver overwrites the
- //src.format field if destination format is different.
- //This implementation detail makes it possible to retrieve w,h even before
- //buffer allocation, which happens in queueBuffer.
- return utils::Whf(mRotInfo.dst_rect.w, mRotInfo.dst_rect.h,
- mRotInfo.src.format);
-}
-
-utils::Dim MdssRot::getDstDimensions() const {
- return utils::Dim(mRotInfo.dst_rect.x, mRotInfo.dst_rect.y,
- mRotInfo.dst_rect.w, mRotInfo.dst_rect.h);
-}
-
-uint32_t MdssRot::getSessId() const { return mRotInfo.id; }
-
-void MdssRot::save() {
- mLSRotInfo = mRotInfo;
-}
-
-bool MdssRot::rotConfChanged() const {
- // 0 means same
- if(0 == ::memcmp(&mRotInfo, &mLSRotInfo,
- sizeof (mdp_overlay))) {
- return false;
- }
- return true;
-}
-
-bool MdssRot::init() {
- if(!utils::openDev(mFd, 0, Res::fbPath, O_RDWR)) {
- ALOGE("MdssRot failed to init fb0");
- return false;
- }
- return true;
-}
-
-void MdssRot::setSource(const overlay::utils::Whf& awhf) {
- utils::Whf whf(awhf);
-
- mRotInfo.src.format = whf.format;
- mRotInfo.src.width = whf.w;
- mRotInfo.src.height = whf.h;
-}
-
-void MdssRot::setCrop(const utils::Dim& crop) {
- mRotInfo.src_rect.x = crop.x;
- mRotInfo.src_rect.y = crop.y;
- mRotInfo.src_rect.w = crop.w;
- mRotInfo.src_rect.h = crop.h;
-}
-
-void MdssRot::setDownscale(int downscale) {
- mDownscale = downscale;
-}
-
-void MdssRot::setFlags(const utils::eMdpFlags& flags) {
- mRotInfo.flags = flags;
-}
-
-void MdssRot::setTransform(const utils::eTransform& rot)
-{
- // reset rotation flags to avoid stale orientation values
- mRotInfo.flags &= ~MDSS_ROT_MASK;
- int flags = utils::getMdpOrient(rot);
- if (flags != -1)
- setRotations(flags);
- mOrientation = static_cast<utils::eTransform>(flags);
- ALOGE_IF(DEBUG_OVERLAY, "%s: rot=%d", __FUNCTION__, flags);
-}
-
-void MdssRot::doTransform() {
- mRotInfo.flags |= mOrientation;
- if(mOrientation & utils::OVERLAY_TRANSFORM_ROT_90)
- utils::swap(mRotInfo.dst_rect.w, mRotInfo.dst_rect.h);
-}
-
-bool MdssRot::commit() {
- Dim adjCrop(mRotInfo.src_rect.x,mRotInfo.src_rect.y,
- mRotInfo.src_rect.w,mRotInfo.src_rect.h);
- adjCrop = getFormatAdjustedCrop(adjCrop, mRotInfo.src.format,
- mRotInfo.flags & utils::OV_MDP_DEINTERLACE);
- adjCrop = getDownscaleAdjustedCrop(adjCrop, mDownscale);
-
- mRotInfo.src_rect.x = adjCrop.x;
- mRotInfo.src_rect.y = adjCrop.y;
- mRotInfo.src_rect.w = adjCrop.w;
- mRotInfo.src_rect.h = adjCrop.h;
-
- mRotInfo.dst_rect.x = 0;
- mRotInfo.dst_rect.y = 0;
- mRotInfo.dst_rect.w = mDownscale ?
- mRotInfo.src_rect.w / mDownscale : mRotInfo.src_rect.w;
- mRotInfo.dst_rect.h = mDownscale ?
- mRotInfo.src_rect.h / mDownscale : mRotInfo.src_rect.h;
- //Clear for next round
- mDownscale = 0;
-
- doTransform();
-
- mRotInfo.flags |= MDSS_MDP_ROT_ONLY;
- mEnabled = true;
- if(!overlay::mdp_wrapper::setOverlay(mFd.getFD(), mRotInfo)) {
- ALOGE("MdssRot commit failed!");
- dump();
- return (mEnabled = false);
- }
- mRotData.id = mRotInfo.id;
- return true;
-}
-
-bool MdssRot::queueBuffer(int fd, uint32_t offset) {
- if(enabled() and (not isRotCached(fd,offset))) {
- int prev_fd = getSrcMemId();
- uint32_t prev_offset = getSrcOffset();
-
- mRotData.data.memory_id = fd;
- mRotData.data.offset = offset;
-
- if(false == remap(RotMem::ROT_NUM_BUFS)) {
- ALOGE("%s Remap failed, not queuing", __FUNCTION__);
- return false;
- }
-
- mRotData.dst_data.offset =
- mMem.mRotOffset[mMem.mCurrIndex];
-
- if(!overlay::mdp_wrapper::play(mFd.getFD(), mRotData)) {
- ALOGE("MdssRot play failed!");
- dump();
- mRotData.data.memory_id = prev_fd;
- mRotData.data.offset = prev_offset;
- return false;
- }
- save();
- mMem.mCurrIndex =
- (mMem.mCurrIndex + 1) % mMem.mem.numBufs();
- }
- return true;
-}
-
-bool MdssRot::open_i(uint32_t numbufs, uint32_t bufsz)
-{
- OvMem mem;
- OVASSERT(MAP_FAILED == mem.addr(), "MAP failed in open_i");
- bool isSecure = mRotInfo.flags & utils::OV_MDP_SECURE_OVERLAY_SESSION;
-
- if(!mem.open(numbufs, bufsz, isSecure)){
- ALOGE("%s: Failed to open", __func__);
- mem.close();
- return false;
- }
-
- OVASSERT(MAP_FAILED != mem.addr(), "MAP failed");
- OVASSERT(mem.getFD() != -1, "getFd is -1");
-
- mRotData.dst_data.memory_id = mem.getFD();
- mRotData.dst_data.offset = 0;
- mMem.mem = mem;
- return true;
-}
-
-bool MdssRot::remap(uint32_t numbufs) {
- // Calculate the size based on rotator's dst format, w and h.
- uint32_t opBufSize = calcOutputBufSize();
- // If current size changed, remap
- if(opBufSize == mMem.size()) {
- ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, opBufSize);
- return true;
- }
-
- ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__);
-
- if(!mMem.close()) {
- ALOGE("%s error in closing prev rot mem", __FUNCTION__);
- return false;
- }
-
- if(!open_i(numbufs, opBufSize)) {
- ALOGE("%s Error could not open", __FUNCTION__);
- return false;
- }
-
- for (uint32_t i = 0; i < numbufs; ++i) {
- mMem.mRotOffset[i] = i * opBufSize;
- }
-
- return true;
-}
-
-bool MdssRot::close() {
- bool success = true;
- if(mFd.valid() && (getSessId() != (uint32_t) MSMFB_NEW_REQUEST)) {
- if(!mdp_wrapper::unsetOverlay(mFd.getFD(), getSessId())) {
- ALOGE("MdssRot::close unsetOverlay failed, fd=%d sessId=%d",
- mFd.getFD(), getSessId());
- success = false;
- }
- }
-
- if (!mFd.close()) {
- ALOGE("Mdss Rot error closing fd");
- success = false;
- }
- if (!mMem.close()) {
- ALOGE("Mdss Rot error closing mem");
- success = false;
- }
- reset();
- return success;
-}
-
-void MdssRot::reset() {
- ovutils::memset0(mRotInfo);
- ovutils::memset0(mLSRotInfo);
- ovutils::memset0(mRotData);
- mRotData.data.memory_id = -1;
- mRotInfo.id = MSMFB_NEW_REQUEST;
- ovutils::memset0(mMem.mRotOffset);
- mMem.mCurrIndex = 0;
- mOrientation = utils::OVERLAY_TRANSFORM_0;
- mDownscale = 0;
-}
-
-void MdssRot::dump() const {
- ALOGE("== Dump MdssRot start ==");
- mFd.dump();
- mMem.mem.dump();
- mdp_wrapper::dump("mRotInfo", mRotInfo);
- mdp_wrapper::dump("mRotData", mRotData);
- ALOGE("== Dump MdssRot end ==");
-}
-
-uint32_t MdssRot::calcOutputBufSize() {
- uint32_t opBufSize = 0;
- ovutils::Whf destWhf(mRotInfo.dst_rect.w, mRotInfo.dst_rect.h,
- mRotInfo.src.format); //mdss src and dst formats are same.
-
- if (mRotInfo.flags & ovutils::OV_MDSS_MDP_BWC_EN) {
- opBufSize = calcCompressedBufSize(destWhf);
- } else {
- opBufSize = Rotator::calcOutputBufSize(destWhf);
- }
-
- return opBufSize;
-}
-
-void MdssRot::getDump(char *buf, size_t len) const {
- ovutils::getDump(buf, len, "MdssRotCtrl", mRotInfo);
- ovutils::getDump(buf, len, "MdssRotData", mRotData);
-}
-
-// Calculate the compressed o/p buffer size for BWC
-uint32_t MdssRot::calcCompressedBufSize(const ovutils::Whf& destWhf) {
- uint32_t bufSize = 0;
- //Worst case alignments
- int aWidth = ovutils::align(destWhf.w, 64);
- int aHeight = ovutils::align(destWhf.h, 4);
- /*
- Format | RAU size (width x height)
- ----------------------------------------------
- ARGB | 32 pixel x 4 line
- RGB888 | 32 pixel x 4 line
- Y (Luma) | 64 pixel x 4 line
- CRCB 420 | 32 pixel x 2 line
- CRCB 422 H2V1 | 32 pixel x 4 line
- CRCB 422 H1V2 | 64 pixel x 2 line
-
- Metadata requirements:-
- 1 byte meta data for every 8 RAUs
- 2 byte meta data per RAU
- */
-
- //These blocks attempt to allocate for the worst case in each of the
- //respective format classes, yuv/rgb. The table above is for reference
- if(utils::isYuv(destWhf.format)) {
- int yRauCount = aWidth / 64; //Y
- int cRauCount = aWidth / 32; //C
- int yStride = (64 * 4 * yRauCount) + alignup(yRauCount, 8) / 8;
- int cStride = ((32 * 2 * cRauCount) + alignup(cRauCount, 8) / 8) * 2;
- int yStrideOffset = (aHeight / 4);
- int cStrideOffset = (aHeight / 2);
- bufSize = (yStride * yStrideOffset + cStride * cStrideOffset) +
- (yRauCount * yStrideOffset * 2) +
- (cRauCount * cStrideOffset * 2) * 2;
- ALOGD_IF(DEBUG_MDSS_ROT, "%s:YUV Y RAU Count = %d C RAU Count = %d",
- __FUNCTION__, yRauCount, cRauCount);
- } else {
- int rauCount = aWidth / 32;
- //Single plane
- int stride = (32 * 4 * rauCount) + alignup(rauCount, 8) / 8;
- int strideOffset = (aHeight / 4);
- bufSize = (stride * strideOffset * 4 /*bpp*/) +
- (rauCount * strideOffset * 2);
- ALOGD_IF(DEBUG_MDSS_ROT, "%s:RGB RAU count = %d", __FUNCTION__,
- rauCount);
- }
-
- ALOGD_IF(DEBUG_MDSS_ROT, "%s: aligned width = %d, aligned height = %d "
- "Buf Size = %d", __FUNCTION__, aWidth, aHeight, bufSize);
-
- return bufSize;
-}
-
-int MdssRot::getDownscaleFactor(const int& srcW, const int& srcH,
- const int& dstW, const int& dstH, const uint32_t& mdpFormat,
- const bool& isInterlaced) {
- if(not srcW or not srcH or not dstW or not dstH or isInterlaced) return 0;
-
- Dim crop(0, 0, srcW, srcH);
- Dim adjCrop = getFormatAdjustedCrop(crop, mdpFormat,
- false /*isInterlaced */);
-
- uint32_t downscale = min((adjCrop.w / dstW), (adjCrop.h / dstH));
- //Reduced to a power of 2
- downscale = (uint32_t) powf(2.0f, floorf(log2f((float)downscale)));
-
- if(downscale < 2 or downscale > 32) return 0;
-
- //Allow only 1 line or pixel to be chopped off since the source needs to
- //be aligned to downscale. Progressively try with smaller downscale to see
- //if we can satisfy the threshold
- //For YUV the loop shouldnt be needed, unless in exceptional cases
- Dim dsAdjCrop = getDownscaleAdjustedCrop(adjCrop, downscale);
- while(downscale > 2 and (adjCrop.w > dsAdjCrop.w or
- adjCrop.h > dsAdjCrop.h)) {
- downscale /= 2;
- dsAdjCrop = getDownscaleAdjustedCrop(adjCrop, downscale);
- }
-
- if(not dsAdjCrop.w or not dsAdjCrop.h) return 0;
- return downscale;
-}
-
-Dim MdssRot::getFormatAdjustedCrop(const Dim& crop,
- const uint32_t& mdpFormat, const bool& isInterlaced) {
- Dim adjCrop = crop;
- if (isYuv(mdpFormat)) {
- normalizeCrop(adjCrop.x, adjCrop.w);
- normalizeCrop(adjCrop.y, adjCrop.h);
- // For interlaced, crop.h should be 4-aligned
- if (isInterlaced and (adjCrop.h % 4))
- adjCrop.h = aligndown(adjCrop.h, 4);
- }
- return adjCrop;
-}
-
-Dim MdssRot::getDownscaleAdjustedCrop(const Dim& crop,
- const uint32_t& downscale) {
- uint32_t alignedSrcW = aligndown(crop.w, downscale * 2);
- uint32_t alignedSrcH = aligndown(crop.h, downscale * 2);
- return Dim(crop.x, crop.y, alignedSrcW, alignedSrcH);
-}
-
-} // namespace overlay
diff --git a/msm8909/liboverlay/overlayMem.h b/msm8909/liboverlay/overlayMem.h
deleted file mode 100644
index f0a1922..0000000
--- a/msm8909/liboverlay/overlayMem.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
-* Copyright (c) 2011, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#ifndef OVERLAY_MEM_H
-#define OVERLAY_MEM_H
-
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <alloc_controller.h>
-#include <memalloc.h>
-
-#include "gralloc_priv.h"
-#include "overlayUtils.h"
-#define SIZE_1M 0x00100000
-
-namespace overlay {
-
-/*
-* Holds base address, offset and the fd
-* */
-class OvMem {
-public:
- /* ctor init*/
- explicit OvMem();
-
- /* dtor DO NOT call close so it can be copied */
- ~OvMem();
-
- /* Use libgralloc to retrieve fd, base addr, alloc type */
- bool open(uint32_t numbufs,
- uint32_t bufSz, bool isSecure);
-
- /* close fd. assign base address to invalid*/
- bool close();
-
- /* return underlying fd */
- int getFD() const;
-
- /* return true if fd is valid and base address is valid */
- bool valid() const;
-
- /* dump the state of the object */
- void dump() const;
-
- /* return underlying address */
- void* addr() const;
-
- /* return underlying offset */
- uint32_t bufSz() const;
-
- /* return number of bufs */
- uint32_t numBufs() const ;
-
-private:
- /* actual os fd */
- int mFd;
-
- /* points to base addr (mmap)*/
- void* mBaseAddr;
-
- /* allocated buffer type determined by gralloc (ashmem, ion, etc) */
- int mAllocType;
-
- /* holds buf size sent down by the client */
- uint32_t mBufSz;
-
- /* num of bufs */
- uint32_t mNumBuffers;
-
- /* gralloc alloc controller */
- gralloc::IAllocController* mAlloc;
-
- /*Holds the aligned buffer size used for actual allocation*/
- uint32_t mBufSzAligned;
-};
-
-//-------------------Inlines-----------------------------------
-
-using gralloc::IMemAlloc;
-using gralloc::alloc_data;
-
-inline OvMem::OvMem() {
- mFd = -1;
- mBaseAddr = MAP_FAILED;
- mAllocType = 0;
- mBufSz = 0;
- mNumBuffers = 0;
- mAlloc = gralloc::IAllocController::getInstance();
-}
-
-inline OvMem::~OvMem() { }
-
-inline bool OvMem::open(uint32_t numbufs,
- uint32_t bufSz, bool isSecure)
-{
- alloc_data data;
- int allocFlags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
- int err = 0;
- OVASSERT(numbufs && bufSz, "numbufs=%d bufSz=%d", numbufs, bufSz);
- mBufSz = bufSz;
-
- if(isSecure) {
- allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP;
- allocFlags |= GRALLOC_USAGE_PROTECTED;
- mBufSzAligned = utils::align(bufSz, SIZE_1M);
- data.align = SIZE_1M;
- } else {
- mBufSzAligned = bufSz;
- data.align = getpagesize();
- }
-
- // Allocate uncached rotator buffers
- allocFlags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
-
- mNumBuffers = numbufs;
-
- data.base = 0;
- data.fd = -1;
- data.offset = 0;
- data.size = mBufSzAligned * mNumBuffers;
- data.uncached = true;
-
- err = mAlloc->allocate(data, allocFlags);
- if (err != 0) {
- ALOGE("OvMem: Error allocating memory");
- return false;
- }
-
- mFd = data.fd;
- mBaseAddr = data.base;
- mAllocType = data.allocType;
-
- return true;
-}
-
-inline bool OvMem::close()
-{
- int ret = 0;
-
- if(!valid()) {
- return true;
- }
-
- IMemAlloc* memalloc = mAlloc->getAllocator(mAllocType);
- ret = memalloc->free_buffer(mBaseAddr, mBufSzAligned * mNumBuffers, 0, mFd);
- if (ret != 0) {
- ALOGE("OvMem: error freeing buffer");
- return false;
- }
-
- mFd = -1;
- mBaseAddr = MAP_FAILED;
- mAllocType = 0;
- mBufSz = 0;
- mBufSzAligned = 0;
- mNumBuffers = 0;
- return true;
-}
-
-inline bool OvMem::valid() const
-{
- return (mFd != -1) && (mBaseAddr != MAP_FAILED);
-}
-
-inline int OvMem::getFD() const
-{
- return mFd;
-}
-
-inline void* OvMem::addr() const
-{
- return mBaseAddr;
-}
-
-inline uint32_t OvMem::bufSz() const
-{
- return mBufSz;
-}
-
-inline uint32_t OvMem::numBufs() const
-{
- return mNumBuffers;
-}
-
-inline void OvMem::dump() const
-{
- ALOGE("== Dump OvMem start ==");
- ALOGE("fd=%d addr=%p type=%d bufsz=%u AlignedBufSz=%u",
- mFd, mBaseAddr, mAllocType, mBufSz, mBufSzAligned);
- ALOGE("== Dump OvMem end ==");
-}
-
-} // overlay
-
-#endif // OVERLAY_MEM_H
diff --git a/msm8909/liboverlay/overlayRotator.cpp b/msm8909/liboverlay/overlayRotator.cpp
deleted file mode 100644
index b55f06a..0000000
--- a/msm8909/liboverlay/overlayRotator.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 "overlayRotator.h"
-#include "overlayUtils.h"
-#include "mdp_version.h"
-#include "sync/sync.h"
-#include "gr.h"
-
-namespace ovutils = overlay::utils;
-
-namespace overlay {
-
-//============Rotator=========================
-
-Rotator::Rotator() {
- char property[PROPERTY_VALUE_MAX];
- mRotCacheDisabled = false;
- if((property_get("debug.rotcache.disable", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- /* Used in debugging to turnoff rotator caching */
- mRotCacheDisabled = true;
- }
-}
-
-Rotator::~Rotator() {}
-
-Rotator* Rotator::getRotator() {
- int type = getRotatorHwType();
- if(type == TYPE_MDP) {
- return new MdpRot(); //will do reset
- } else if(type == TYPE_MDSS) {
- return new MdssRot();
- } else {
- ALOGE("%s Unknown h/w type %d", __FUNCTION__, type);
- return NULL;
- }
-}
-
-int Rotator::getDownscaleFactor(const int& srcW, const int& srcH,
- const int& dstW, const int& dstH, const uint32_t& mdpFormat,
- const bool& isInterlaced) {
- if(getRotatorHwType() == TYPE_MDSS) {
- return MdssRot::getDownscaleFactor(srcW, srcH, dstW, dstH,
- mdpFormat, isInterlaced);
- }
- return MdpRot::getDownscaleFactor(srcW, srcH, dstW, dstH,
- mdpFormat, isInterlaced);
-}
-
-uint32_t Rotator::calcOutputBufSize(const utils::Whf& destWhf) {
- //dummy aligned w & h.
- int alW = 0, alH = 0;
- int halFormat = ovutils::getHALFormat(destWhf.format);
- //A call into gralloc/memalloc
- return getBufferSizeAndDimensions(
- destWhf.w, destWhf.h, halFormat, alW, alH);
-}
-
-int Rotator::getRotatorHwType() {
- int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
- if (mdpVersion == qdutils::MDSS_V5)
- return TYPE_MDSS;
- return TYPE_MDP;
-}
-
-bool Rotator::isRotCached(int fd, uint32_t offset) const {
- if(mRotCacheDisabled or rotConfChanged() or rotDataChanged(fd,offset))
- return false;
- return true;
-}
-
-bool Rotator::rotDataChanged(int fd, uint32_t offset) const {
- /* fd and offset are the attributes of the current rotator input buffer.
- * At this instance, getSrcMemId() and getSrcOffset() return the
- * attributes of the previous rotator input buffer */
- if( (fd == getSrcMemId()) and (offset == getSrcOffset()) )
- return false;
- return true;
-}
-
-//============RotMem=========================
-
-bool RotMem::close() {
- bool ret = true;
- if(valid()) {
- if(mem.close() == false) {
- ALOGE("%s error in closing rot mem", __FUNCTION__);
- ret = false;
- }
- }
- return ret;
-}
-
-RotMem::RotMem() : mCurrIndex(0) {
- utils::memset0(mRotOffset);
- for(int i = 0; i < ROT_NUM_BUFS; i++) {
- mRelFence[i] = -1;
- }
-}
-
-RotMem::~RotMem() {
- for(int i = 0; i < ROT_NUM_BUFS; i++) {
- ::close(mRelFence[i]);
- mRelFence[i] = -1;
- }
-}
-
-void RotMem::setCurrBufReleaseFd(const int& fence) {
- int ret = 0;
-
- if(mRelFence[mCurrIndex] >= 0) {
- //Wait for previous usage of this buffer to be over.
- //Can happen if rotation takes > vsync and a fast producer. i.e queue
- //happens in subsequent vsyncs either because content is 60fps or
- //because the producer is hasty sometimes.
- ret = sync_wait(mRelFence[mCurrIndex], 1000);
- if(ret < 0) {
- ALOGE("%s: sync_wait error!! error no = %d err str = %s",
- __FUNCTION__, errno, strerror(errno));
- }
- ::close(mRelFence[mCurrIndex]);
- }
- mRelFence[mCurrIndex] = fence;
-}
-
-void RotMem::setPrevBufReleaseFd(const int& fence) {
- uint32_t numRotBufs = mem.numBufs();
- uint32_t prevIndex = (mCurrIndex + numRotBufs - 1) % (numRotBufs);
-
- if(mRelFence[prevIndex] >= 0) {
- /* No need of any wait as nothing will be written into this
- * buffer by the rotator (this func is called when rotator is
- * in cache mode) */
- ::close(mRelFence[prevIndex]);
- }
-
- mRelFence[prevIndex] = fence;
-}
-
-//============RotMgr=========================
-RotMgr * RotMgr::sRotMgr = NULL;
-
-RotMgr* RotMgr::getInstance() {
- if(sRotMgr == NULL) {
- sRotMgr = new RotMgr();
- }
- return sRotMgr;
-}
-
-RotMgr::RotMgr() {
- for(int i = 0; i < MAX_ROT_SESS; i++) {
- mRot[i] = 0;
- }
- mUseCount = 0;
- mRotDevFd = -1;
-}
-
-RotMgr::~RotMgr() {
- clear();
-}
-
-void RotMgr::configBegin() {
- //Reset the number of objects used
- mUseCount = 0;
-}
-
-void RotMgr::configDone() {
- //Remove the top most unused objects. Videos come and go.
- for(int i = mUseCount; i < MAX_ROT_SESS; i++) {
- if(mRot[i]) {
- delete mRot[i];
- mRot[i] = 0;
- }
- }
-}
-
-Rotator* RotMgr::getNext() {
- //Return a rot object, creating one if necessary
- overlay::Rotator *rot = NULL;
- if(mUseCount >= MAX_ROT_SESS) {
- ALOGW("%s, MAX rotator sessions reached, request rejected", __func__);
- } else {
- if(mRot[mUseCount] == NULL)
- mRot[mUseCount] = overlay::Rotator::getRotator();
- rot = mRot[mUseCount++];
- }
- return rot;
-}
-
-void RotMgr::clear() {
- //Brute force obj destruction, helpful in suspend.
- for(int i = 0; i < MAX_ROT_SESS; i++) {
- if(mRot[i]) {
- delete mRot[i];
- mRot[i] = 0;
- }
- }
- mUseCount = 0;
- ::close(mRotDevFd);
- mRotDevFd = -1;
-}
-
-void RotMgr::getDump(char *buf, size_t len) {
- for(int i = 0; i < MAX_ROT_SESS; i++) {
- if(mRot[i]) {
- mRot[i]->getDump(buf, len);
- }
- }
- char str[4] = {'\0'};
- snprintf(str, 4, "\n");
- strlcat(buf, str, len);
-}
-
-int RotMgr::getRotDevFd() {
- if(mRotDevFd < 0 && Rotator::getRotatorHwType() == Rotator::TYPE_MDSS) {
- mRotDevFd = ::open("/dev/graphics/fb0", O_RDWR, 0);
- if(mRotDevFd < 0) {
- ALOGE("%s failed to open fb0", __FUNCTION__);
- }
- }
- return mRotDevFd;
-}
-
-}
diff --git a/msm8909/liboverlay/overlayRotator.h b/msm8909/liboverlay/overlayRotator.h
deleted file mode 100644
index e045b44..0000000
--- a/msm8909/liboverlay/overlayRotator.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
-* Copyright (c) 2011,2013 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation. nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef OVERlAY_ROTATOR_H
-#define OVERlAY_ROTATOR_H
-
-#include <stdlib.h>
-
-#include "mdpWrapper.h"
-#include "overlayUtils.h"
-#include "overlayMem.h"
-
-namespace overlay {
-
-/*
- Manages the case where new rotator memory needs to be
- allocated, before previous is freed, due to resolution change etc. If we make
- rotator memory to be always max size, irrespctive of source resolution then
- we don't need this RotMem wrapper. The inner class is sufficient.
-*/
-struct RotMem {
- // Max rotator buffers
- enum { ROT_NUM_BUFS = 2 };
- RotMem();
- ~RotMem();
- bool close();
- bool valid() { return mem.valid(); }
- uint32_t size() const { return mem.bufSz(); }
- void setCurrBufReleaseFd(const int& fence);
- void setPrevBufReleaseFd(const int& fence);
-
- // rotator data info dst offset
- uint32_t mRotOffset[ROT_NUM_BUFS];
- int mRelFence[ROT_NUM_BUFS];
- // current slot being used
- uint32_t mCurrIndex;
- OvMem mem;
-};
-
-class Rotator
-{
-public:
- enum { TYPE_MDP, TYPE_MDSS };
- virtual ~Rotator();
- virtual void setSource(const utils::Whf& wfh) = 0;
- virtual void setCrop(const utils::Dim& crop) = 0;
- virtual void setFlags(const utils::eMdpFlags& flags) = 0;
- virtual void setTransform(const utils::eTransform& rot) = 0;
- virtual bool commit() = 0;
- /* return true if the current rotator state is cached */
- virtual bool isRotCached(int fd, uint32_t offset) const;
- /* return true if current rotator config is same as the last round*/
- virtual bool rotConfChanged() const = 0;
- /* return true if the current rotator input buffer fd and offset
- * are same as the last round */
- virtual bool rotDataChanged(int fd, uint32_t offset) const;
- virtual void setDownscale(int ds) = 0;
- /* returns the src buffer of the rotator for the previous/current round,
- * depending on when it is called(before/after the queuebuffer)*/
- virtual int getSrcMemId() const = 0;
- //Mem id and offset should be retrieved only after rotator kickoff
- virtual int getDstMemId() const = 0;
- virtual uint32_t getSrcOffset() const = 0;
- virtual uint32_t getDstOffset() const = 0;
- //Destination width, height, format, position should be retrieved only after
- //rotator configuration is committed via commit API
- virtual uint32_t getDstFormat() const = 0;
- virtual utils::Whf getDstWhf() const = 0;
- virtual utils::Dim getDstDimensions() const = 0;
- virtual uint32_t getSessId() const = 0;
- virtual bool queueBuffer(int fd, uint32_t offset) = 0;
- virtual void dump() const = 0;
- virtual void getDump(char *buf, size_t len) const = 0;
- inline void setCurrBufReleaseFd(const int& fence) {
- mMem.setCurrBufReleaseFd(fence);
- }
- inline void setPrevBufReleaseFd(const int& fence) {
- mMem.setPrevBufReleaseFd(fence);
- }
- static Rotator *getRotator();
- /* Returns downscale by successfully applying constraints
- * Returns 0 if target doesnt support rotator downscaling
- * or if any of the constraints are not met
- */
- static int getDownscaleFactor(const int& srcW, const int& srcH,
- const int& dstW, const int& dstH, const uint32_t& mdpFormat,
- const bool& isInterlaced);
-
-protected:
- /* Rotator memory manager */
- RotMem mMem;
- Rotator();
- static uint32_t calcOutputBufSize(const utils::Whf& destWhf);
-
-private:
- bool mRotCacheDisabled;
- /*Returns rotator h/w type */
- static int getRotatorHwType();
- friend class RotMgr;
-};
-
-/*
-* MDP rot holds MDP's rotation related structures.
-*
-* */
-class MdpRot : public Rotator {
-public:
- virtual ~MdpRot();
- virtual void setSource(const utils::Whf& wfh);
- virtual void setCrop(const utils::Dim& crop);
- virtual void setFlags(const utils::eMdpFlags& flags);
- virtual void setTransform(const utils::eTransform& rot);
- virtual bool commit();
- virtual bool rotConfChanged() const;
- virtual void setDownscale(int ds);
- virtual int getSrcMemId() const;
- virtual int getDstMemId() const;
- virtual uint32_t getSrcOffset() const;
- virtual uint32_t getDstOffset() const;
- virtual uint32_t getDstFormat() const;
- virtual utils::Whf getDstWhf() const;
- virtual utils::Dim getDstDimensions() const;
- virtual uint32_t getSessId() const;
- virtual bool queueBuffer(int fd, uint32_t offset);
- virtual void dump() const;
- virtual void getDump(char *buf, size_t len) const;
-
-private:
- explicit MdpRot();
- bool init();
- bool close();
- void setRotations(uint32_t r);
- bool enabled () const;
- /* remap rot buffers */
- bool remap(uint32_t numbufs);
- bool open_i(uint32_t numbufs, uint32_t bufsz);
- /* Deferred transform calculations */
- void doTransform();
- /* reset underlying data, basically memset 0 */
- void reset();
- /* save mRotImgInfo to be last known good config*/
- void save();
- /* Calculates the rotator's o/p buffer size post the transform calcs and
- * knowing the o/p format depending on whether fastYuv is enabled or not */
- uint32_t calcOutputBufSize();
-
- /* Applies downscale by taking areas
- * Returns a log(downscale)
- * Constraints applied:
- * - downscale should be a power of 2
- * - Max downscale is 1/8
- */
- static int getDownscaleFactor(const int& srcW, const int& srcH,
- const int& dstW, const int& dstH, const uint32_t& mdpFormat,
- const bool& isInterlaced);
-
- /* rot info*/
- msm_rotator_img_info mRotImgInfo;
- /* Last saved rot info*/
- msm_rotator_img_info mLSRotImgInfo;
- /* rot data */
- msm_rotator_data_info mRotDataInfo;
- /* Orientation */
- utils::eTransform mOrientation;
- /* rotator fd */
- OvFD mFd;
-
- friend Rotator* Rotator::getRotator();
- friend int Rotator::getDownscaleFactor(const int& srcW, const int& srcH,
- const int& dstW, const int& dstH, const uint32_t& mdpFormat,
- const bool& isInterlaced);
-};
-
-/*
-+* MDSS Rot holds MDSS's rotation related structures.
-+*
-+* */
-class MdssRot : public Rotator {
-public:
- virtual ~MdssRot();
- virtual void setSource(const utils::Whf& wfh);
- virtual void setCrop(const utils::Dim& crop);
- virtual void setFlags(const utils::eMdpFlags& flags);
- virtual void setTransform(const utils::eTransform& rot);
- virtual bool commit();
- virtual bool rotConfChanged() const;
- virtual void setDownscale(int ds);
- virtual int getSrcMemId() const;
- virtual int getDstMemId() const;
- virtual uint32_t getSrcOffset() const;
- virtual uint32_t getDstOffset() const;
- virtual uint32_t getDstFormat() const;
- virtual utils::Whf getDstWhf() const;
- virtual utils::Dim getDstDimensions() const;
- virtual uint32_t getSessId() const;
- virtual bool queueBuffer(int fd, uint32_t offset);
- virtual void dump() const;
- virtual void getDump(char *buf, size_t len) const;
-
-private:
- explicit MdssRot();
- bool init();
- bool close();
- void setRotations(uint32_t r);
- bool enabled () const;
- /* remap rot buffers */
- bool remap(uint32_t numbufs);
- bool open_i(uint32_t numbufs, uint32_t bufsz);
- /* Deferred transform calculations */
- void doTransform();
- /* reset underlying data, basically memset 0 */
- void reset();
- /* save mRotInfo to be last known good config*/
- void save();
- /* Calculates the rotator's o/p buffer size post the transform calcs and
- * knowing the o/p format depending on whether fastYuv is enabled or not */
- uint32_t calcOutputBufSize();
- // Calculate the compressed o/p buffer size for BWC
- uint32_t calcCompressedBufSize(const utils::Whf& destWhf);
-
- /* Caller's responsibility to swap srcW, srcH if there is a 90 transform
- * Returns actual downscale (not a log value)
- * Constraints applied:
- * - downscale should be a power of 2
- * - Max downscale is 1/32
- * - Equal downscale is applied in both directions
- * - {srcW, srcH} mod downscale = 0
- * - Interlaced content is not supported
- */
- static int getDownscaleFactor(const int& srcW, const int& srcH,
- const int& dstW, const int& dstH, const uint32_t& mdpFormat,
- const bool& isInterlaced);
-
- static utils::Dim getFormatAdjustedCrop(const utils::Dim& crop,
- const uint32_t& mdpFormat, const bool& isInterlaced);
-
- static utils::Dim getDownscaleAdjustedCrop(const utils::Dim& crop,
- const uint32_t& downscale);
-
- /* MdssRot info structure */
- mdp_overlay mRotInfo;
- /* Last saved MdssRot info structure*/
- mdp_overlay mLSRotInfo;
- /* MdssRot data structure */
- msmfb_overlay_data mRotData;
- /* Orientation */
- utils::eTransform mOrientation;
- /* rotator fd */
- OvFD mFd;
- /* Enable/Disable Mdss Rot*/
- bool mEnabled;
- int mDownscale;
-
- friend Rotator* Rotator::getRotator();
- friend int Rotator::getDownscaleFactor(const int& srcW, const int& srcH,
- const int& dstW, const int& dstH, const uint32_t& mdpFormat,
- const bool& isInterlaced);
-};
-
-// Holder of rotator objects. Manages lifetimes
-class RotMgr {
-public:
- //Virtually we can support as many rotator sessions as possible, However
- // more number of rotator sessions leads to performance issues, so
- // restricting the max rotator session to 4
- enum { MAX_ROT_SESS = 4 };
-
- ~RotMgr();
- void configBegin();
- void configDone();
- overlay::Rotator *getNext();
- void clear(); //Removes all instances
- //Resets the usage of top count objects, making them available for reuse
- void markUnusedTop(const uint32_t& count) { mUseCount -= count; }
- /* Returns rot dump.
- * Expects a NULL terminated buffer of big enough size.
- */
- void getDump(char *buf, size_t len);
- int getRotDevFd();
- int getNumActiveSessions() { return mUseCount; }
-
- static RotMgr *getInstance();
-
-private:
- RotMgr();
- static RotMgr *sRotMgr;
-
- overlay::Rotator *mRot[MAX_ROT_SESS];
- uint32_t mUseCount;
- int mRotDevFd;
-};
-
-
-} // overlay
-
-#endif // OVERlAY_ROTATOR_H
diff --git a/msm8909/liboverlay/overlayUtils.cpp b/msm8909/liboverlay/overlayUtils.cpp
deleted file mode 100644
index cbd52ae..0000000
--- a/msm8909/liboverlay/overlayUtils.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
-* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdlib.h>
-#include <math.h>
-#include <utils/Log.h>
-#include <linux/msm_mdp.h>
-#include <cutils/properties.h>
-#include "gralloc_priv.h"
-#include "overlayUtils.h"
-#include "mdpWrapper.h"
-#include "mdp_version.h"
-#include <hardware/hwcomposer_defs.h>
-
-// just a helper static thingy
-namespace {
-struct IOFile {
- IOFile(const char* s, const char* mode) : fp(0) {
- fp = ::fopen(s, mode);
- if(!fp) {
- ALOGE("Failed open %s", s);
- }
- }
- template <class T>
- size_t read(T& r, size_t elem) {
- if(fp) {
- return ::fread(&r, sizeof(T), elem, fp);
- }
- return 0;
- }
- size_t write(const char* s, uint32_t val) {
- if(fp) {
- return ::fprintf(fp, s, val);
- }
- return 0;
- }
- bool valid() const { return fp != 0; }
- ~IOFile() {
- if(fp) ::fclose(fp);
- fp=0;
- }
- FILE* fp;
-};
-}
-
-namespace overlay {
-
-//----------From class Res ------------------------------
-const char* const Res::fbPath = "/dev/graphics/fb%u";
-const char* const Res::rotPath = "/dev/msm_rotator";
-//--------------------------------------------------------
-
-
-
-namespace utils {
-
-//--------------------------------------------------------
-//Refer to graphics.h, gralloc_priv.h, msm_mdp.h
-int getMdpFormat(int format) {
- switch (format) {
- //From graphics.h
- case HAL_PIXEL_FORMAT_RGBA_8888 :
- return MDP_RGBA_8888;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- return MDP_RGBX_8888;
- case HAL_PIXEL_FORMAT_RGB_888:
- return MDP_RGB_888;
- case HAL_PIXEL_FORMAT_RGB_565:
- return MDP_RGB_565;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return MDP_BGRA_8888;
- case HAL_PIXEL_FORMAT_BGRX_8888:
- return MDP_BGRX_8888;
- case HAL_PIXEL_FORMAT_YV12:
- return MDP_Y_CR_CB_GH2V2;
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- return MDP_Y_CBCR_H2V1;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- return MDP_Y_CRCB_H2V2;
-
- //From gralloc_priv.h
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- return MDP_Y_CBCR_H2V2_TILE;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- return MDP_Y_CBCR_H2V2;
- case HAL_PIXEL_FORMAT_YCrCb_422_SP:
- return MDP_Y_CRCB_H2V1;
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- return MDP_YCBYCR_H2V1;
- case HAL_PIXEL_FORMAT_YCrCb_422_I:
- return MDP_YCRYCB_H2V1;
- case HAL_PIXEL_FORMAT_YCbCr_444_SP:
- return MDP_Y_CBCR_H1V1;
- case HAL_PIXEL_FORMAT_YCrCb_444_SP:
- return MDP_Y_CRCB_H1V1;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- //NV12 encodeable format maps to the venus format on
- //B-Family targets
- return MDP_Y_CBCR_H2V2_VENUS;
- default:
- //Unsupported by MDP
- //---graphics.h--------
- //HAL_PIXEL_FORMAT_RGBA_5551
- //HAL_PIXEL_FORMAT_RGBA_4444
- //---gralloc_priv.h-----
- //HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x7FA30C01
- //HAL_PIXEL_FORMAT_R_8 = 0x10D
- //HAL_PIXEL_FORMAT_RG_88 = 0x10E
- ALOGE("%s: Unsupported HAL format = 0x%x", __func__, format);
- return -1;
- }
- // not reached
- return -1;
-}
-
-// This function returns corresponding tile format
-// MDSS support following RGB tile formats
-// 32 bit formats
-// 16 bit formats
-int getMdpFormat(int format, bool tileEnabled)
-{
- if(!tileEnabled) {
- return getMdpFormat(format);
- }
- switch (format) {
- case HAL_PIXEL_FORMAT_RGBA_8888 :
- return MDP_RGBA_8888_TILE;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- return MDP_RGBX_8888_TILE;
- case HAL_PIXEL_FORMAT_RGB_565:
- return MDP_RGB_565_TILE;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return MDP_BGRA_8888_TILE;
- case HAL_PIXEL_FORMAT_BGRX_8888:
- return MDP_BGRX_8888_TILE;
- default:
- return getMdpFormat(format);
- }
-}
-
-
-
-//Takes mdp format as input and translates to equivalent HAL format
-//Refer to graphics.h, gralloc_priv.h, msm_mdp.h for formats.
-int getHALFormat(int mdpFormat) {
- switch (mdpFormat) {
- //From graphics.h
- case MDP_RGBA_8888:
- return HAL_PIXEL_FORMAT_RGBA_8888;
- case MDP_RGBX_8888:
- return HAL_PIXEL_FORMAT_RGBX_8888;
- case MDP_RGB_888:
- return HAL_PIXEL_FORMAT_RGB_888;
- case MDP_RGB_565:
- return HAL_PIXEL_FORMAT_RGB_565;
- case MDP_BGRA_8888:
- return HAL_PIXEL_FORMAT_BGRA_8888;
- case MDP_Y_CR_CB_GH2V2:
- return HAL_PIXEL_FORMAT_YV12;
- case MDP_Y_CBCR_H2V1:
- return HAL_PIXEL_FORMAT_YCbCr_422_SP;
- case MDP_Y_CRCB_H2V2:
- return HAL_PIXEL_FORMAT_YCrCb_420_SP;
-
- //From gralloc_priv.h
- case MDP_Y_CBCR_H2V2_TILE:
- return HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
- case MDP_Y_CBCR_H2V2:
- return HAL_PIXEL_FORMAT_YCbCr_420_SP;
- case MDP_Y_CRCB_H2V1:
- return HAL_PIXEL_FORMAT_YCrCb_422_SP;
- case MDP_YCBYCR_H2V1:
- return HAL_PIXEL_FORMAT_YCbCr_422_I;
- case MDP_YCRYCB_H2V1:
- return HAL_PIXEL_FORMAT_YCrCb_422_I;
- case MDP_Y_CBCR_H1V1:
- return HAL_PIXEL_FORMAT_YCbCr_444_SP;
- case MDP_Y_CRCB_H1V1:
- return HAL_PIXEL_FORMAT_YCrCb_444_SP;
- case MDP_Y_CBCR_H2V2_VENUS:
- return HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
- default:
- ALOGE("%s: Unsupported MDP format = 0x%x", __func__, mdpFormat);
- return -1;
- }
- // not reached
- return -1;
-}
-
-int getMdpOrient(eTransform rotation) {
- int retTrans = 0;
- bool trans90 = false;
- int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
- bool aFamily = (mdpVersion < qdutils::MDSS_V5);
-
- ALOGD_IF(DEBUG_OVERLAY, "%s: In rotation = %d", __FUNCTION__, rotation);
- if(rotation & OVERLAY_TRANSFORM_ROT_90) {
- retTrans |= MDP_ROT_90;
- trans90 = true;
- }
-
- if(rotation & OVERLAY_TRANSFORM_FLIP_H) {
- if(trans90 && aFamily) {
- //Swap for a-family, since its driver does 90 first
- retTrans |= MDP_FLIP_UD;
- } else {
- retTrans |= MDP_FLIP_LR;
- }
- }
-
- if(rotation & OVERLAY_TRANSFORM_FLIP_V) {
- if(trans90 && aFamily) {
- //Swap for a-family, since its driver does 90 first
- retTrans |= MDP_FLIP_LR;
- } else {
- retTrans |= MDP_FLIP_UD;
- }
- }
-
- ALOGD_IF(DEBUG_OVERLAY, "%s: Out rotation = %d", __FUNCTION__, retTrans);
- return retTrans;
-}
-
-void getDecimationFactor(const int& src_w, const int& src_h,
- const int& dst_w, const int& dst_h, uint8_t& horzDeci,
- uint8_t& vertDeci) {
- horzDeci = 0;
- vertDeci = 0;
- float horDscale = ceilf((float)src_w / (float)dst_w);
- float verDscale = ceilf((float)src_h / (float)dst_h);
- qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
-
- //Next power of 2, if not already
- horDscale = powf(2.0f, ceilf(log2f(horDscale)));
- verDscale = powf(2.0f, ceilf(log2f(verDscale)));
-
- //Since MDP can do downscale and has better quality, split the task
- //between decimator and MDP downscale
- horDscale /= (float)mdpHw.getMaxMDPDownscale();
- verDscale /= (float)mdpHw.getMaxMDPDownscale();
-
- if((int)horDscale)
- horzDeci = (uint8_t)log2f(horDscale);
-
- if((int)verDscale)
- vertDeci = (uint8_t)log2f(verDscale);
-
- if(src_w > (int) mdpHw.getMaxMixerWidth()) {
- //If the client sends us something > what a layer mixer supports
- //then it means it doesn't want to use split-pipe but wants us to
- //decimate. A minimum decimation of 2 will ensure that the width is
- //always within layer mixer limits.
- if(horzDeci < 2)
- horzDeci = 2;
- }
-}
-
-static inline int compute(const uint32_t& x, const uint32_t& y,
- const uint32_t& z) {
- return x - ( y + z );
-}
-
-void preRotateSource(const eTransform& tr, Whf& whf, Dim& srcCrop) {
- if(tr & OVERLAY_TRANSFORM_FLIP_H) {
- srcCrop.x = compute(whf.w, srcCrop.x, srcCrop.w);
- }
- if(tr & OVERLAY_TRANSFORM_FLIP_V) {
- srcCrop.y = compute(whf.h, srcCrop.y, srcCrop.h);
- }
- if(tr & OVERLAY_TRANSFORM_ROT_90) {
- int tmp = srcCrop.x;
- srcCrop.x = compute(whf.h,
- srcCrop.y,
- srcCrop.h);
- srcCrop.y = tmp;
- swap(whf.w, whf.h);
- swap(srcCrop.w, srcCrop.h);
- }
-}
-
-void getDump(char *buf, size_t len, const char *prefix,
- const mdp_overlay& ov) {
- char str[256] = {'\0'};
- snprintf(str, 256,
- "%s id=%d z=%d alpha=%d mask=%d flags=0x%x H.Deci=%d,"
- "V.Deci=%d\n",
- prefix, ov.id, ov.z_order, ov.alpha,
- ov.transp_mask, ov.flags, ov.horz_deci, ov.vert_deci);
- strlcat(buf, str, len);
- getDump(buf, len, "\tsrc", ov.src);
- getDump(buf, len, "\tsrc_rect", ov.src_rect);
- getDump(buf, len, "\tdst_rect", ov.dst_rect);
-}
-
-void getDump(char *buf, size_t len, const char *prefix,
- const msmfb_img& ov) {
- char str_src[256] = {'\0'};
- snprintf(str_src, 256,
- "%s w=%d h=%d format=%d %s\n",
- prefix, ov.width, ov.height, ov.format,
- overlay::utils::getFormatString(ov.format));
- strlcat(buf, str_src, len);
-}
-
-void getDump(char *buf, size_t len, const char *prefix,
- const mdp_rect& ov) {
- char str_rect[256] = {'\0'};
- snprintf(str_rect, 256,
- "%s x=%d y=%d w=%d h=%d\n",
- prefix, ov.x, ov.y, ov.w, ov.h);
- strlcat(buf, str_rect, len);
-}
-
-void getDump(char *buf, size_t len, const char *prefix,
- const msmfb_overlay_data& ov) {
- char str[256] = {'\0'};
- snprintf(str, 256,
- "%s id=%d\n",
- prefix, ov.id);
- strlcat(buf, str, len);
- getDump(buf, len, "\tdata", ov.data);
-}
-
-void getDump(char *buf, size_t len, const char *prefix,
- const msmfb_data& ov) {
- char str_data[256] = {'\0'};
- snprintf(str_data, 256,
- "%s offset=%d memid=%d id=%d flags=0x%x\n",
- prefix, ov.offset, ov.memory_id, ov.id, ov.flags);
- strlcat(buf, str_data, len);
-}
-
-void getDump(char *buf, size_t len, const char *prefix,
- const msm_rotator_img_info& rot) {
- char str[256] = {'\0'};
- snprintf(str, 256, "%s sessid=%u rot=%d, enable=%d downscale=%d\n",
- prefix, rot.session_id, rot.rotations, rot.enable,
- rot.downscale_ratio);
- strlcat(buf, str, len);
- getDump(buf, len, "\tsrc", rot.src);
- getDump(buf, len, "\tdst", rot.dst);
- getDump(buf, len, "\tsrc_rect", rot.src_rect);
-}
-
-void getDump(char *buf, size_t len, const char *prefix,
- const msm_rotator_data_info& rot) {
- char str[256] = {'\0'};
- snprintf(str, 256,
- "%s sessid=%u\n",
- prefix, rot.session_id);
- strlcat(buf, str, len);
- getDump(buf, len, "\tsrc", rot.src);
- getDump(buf, len, "\tdst", rot.dst);
-}
-
-//Helper to even out x,w and y,h pairs
-//x,y are always evened to ceil and w,h are evened to floor
-void normalizeCrop(uint32_t& xy, uint32_t& wh) {
- if(xy & 1) {
- even_ceil(xy);
- if(wh & 1)
- even_floor(wh);
- else
- wh -= 2;
- } else {
- even_floor(wh);
- }
-}
-
-} // utils
-
-} // overlay
diff --git a/msm8909/liboverlay/overlayUtils.h b/msm8909/liboverlay/overlayUtils.h
deleted file mode 100644
index 2b8e303..0000000
--- a/msm8909/liboverlay/overlayUtils.h
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
-* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef OVERLAY_UTILS_H
-#define OVERLAY_UTILS_H
-
-#include <cutils/log.h> // ALOGE, etc
-#include <errno.h>
-#include <fcntl.h> // open, O_RDWR, etc
-#include <hardware/hardware.h>
-#include <hardware/gralloc.h> // buffer_handle_t
-#include <linux/msm_mdp.h> // flags
-#include <linux/msm_rotator.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <utils/Log.h>
-#include "gralloc_priv.h" //for interlace
-
-// Older platforms do not support Venus
-#ifndef VENUS_COLOR_FORMAT
-#define MDP_Y_CBCR_H2V2_VENUS MDP_IMGTYPE_LIMIT
-#endif
-
-/*
-*
-* Collection of utilities functions/structs/enums etc...
-*
-* */
-
-// comment that out if you want to remove asserts
-// or put it as -D in Android.mk. your choice.
-#define OVERLAY_HAS_ASSERT
-
-#ifdef OVERLAY_HAS_ASSERT
-# define OVASSERT(x, ...) if(!(x)) { ALOGE(__VA_ARGS__); abort(); }
-#else
-# define OVASSERT(x, ...) ALOGE_IF(!(x), __VA_ARGS__)
-#endif // OVERLAY_HAS_ASSERT
-
-#define DEBUG_OVERLAY 0
-#define PROFILE_OVERLAY 0
-
-#ifndef MDSS_MDP_RIGHT_MIXER
-#define MDSS_MDP_RIGHT_MIXER 0x100
-#endif
-
-#ifndef MDP_OV_PIPE_FORCE_DMA
-#define MDP_OV_PIPE_FORCE_DMA 0x4000
-#endif
-
-#ifndef MDSS_MDP_DUAL_PIPE
-#define MDSS_MDP_DUAL_PIPE 0x200
-#endif
-
-#define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u"
-
-namespace overlay {
-
-// fwd
-class Overlay;
-class OvFD;
-
-/* helper function to open by using fbnum */
-bool open(OvFD& fd, uint32_t fbnum, const char* const dev,
- int flags = O_RDWR);
-
-namespace utils {
-struct Whf;
-struct Dim;
-
-inline uint32_t setBit(uint32_t x, uint32_t mask) {
- return (x | mask);
-}
-
-inline uint32_t clrBit(uint32_t x, uint32_t mask) {
- return (x & ~mask);
-}
-
-/* Utility class to help avoid copying instances by making the copy ctor
-* and assignment operator private
-*
-* Usage:
-* class SomeClass : utils::NoCopy {...};
-*/
-class NoCopy {
-protected:
- NoCopy(){}
- ~NoCopy() {}
-private:
- NoCopy(const NoCopy&);
- const NoCopy& operator=(const NoCopy&);
-};
-
-bool isMdssRotator();
-void normalizeCrop(uint32_t& xy, uint32_t& wh);
-
-template <class Type>
-void swapWidthHeight(Type& width, Type& height);
-
-struct Dim {
- Dim () : x(0), y(0),
- w(0), h(0),
- o(0) {}
- Dim(uint32_t _x, uint32_t _y, uint32_t _w, uint32_t _h) :
- x(_x), y(_y),
- w(_w), h(_h) {}
- Dim(uint32_t _x, uint32_t _y, uint32_t _w, uint32_t _h, uint32_t _o) :
- x(_x), y(_y),
- w(_w), h(_h),
- o(_o) {}
- bool check(uint32_t _w, uint32_t _h) const {
- return (x+w <= _w && y+h <= _h);
-
- }
-
- bool operator==(const Dim& d) const {
- return d.x == x && d.y == y &&
- d.w == w && d.h == h &&
- d.o == o;
- }
-
- bool operator!=(const Dim& d) const {
- return !operator==(d);
- }
-
- void dump() const;
- uint32_t x;
- uint32_t y;
- uint32_t w;
- uint32_t h;
- uint32_t o;
-};
-
-// TODO have Whfz
-
-struct Whf {
- Whf() : w(0), h(0), format(0), size(0) {}
- Whf(uint32_t wi, uint32_t he, uint32_t f) :
- w(wi), h(he), format(f), size(0) {}
- Whf(uint32_t wi, uint32_t he, uint32_t f, uint32_t s) :
- w(wi), h(he), format(f), size(s) {}
- // FIXME not comparing size at the moment
- bool operator==(const Whf& whf) const {
- return whf.w == w && whf.h == h &&
- whf.format == format;
- }
- bool operator!=(const Whf& whf) const {
- return !operator==(whf);
- }
- void dump() const;
- uint32_t w;
- uint32_t h;
- uint32_t format;
- uint32_t size;
-};
-
-enum { MAX_PATH_LEN = 256 };
-
-enum { DEFAULT_PLANE_ALPHA = 0xFF };
-
-/**
- * Rotator flags: not to be confused with orientation flags.
- * Usually, you want to open the rotator to make sure it is
- * ready for business.
- * */
- enum eRotFlags {
- ROT_FLAGS_NONE = 0,
- //Use rotator for 0 rotation. It is used anyway for others.
- ROT_0_ENABLED = 1 << 0,
- //Enable rotator downscale optimization for hardware bugs not handled in
- //driver. If downscale optimizatation is required,
- //then rotator will be used even if its 0 rotation case.
- ROT_DOWNSCALE_ENABLED = 1 << 1,
- ROT_PREROTATED = 1 << 2,
-};
-
-enum eRotDownscale {
- ROT_DS_NONE = 0,
- ROT_DS_HALF = 1,
- ROT_DS_FOURTH = 2,
- ROT_DS_EIGHTH = 3,
-};
-
-/*
- * Various mdp flags like PIPE SHARE, DEINTERLACE etc...
- * kernel/common/linux/msm_mdp.h
- * INTERLACE_MASK: hardware/qcom/display/libgralloc/badger/fb_priv.h
- * */
-enum eMdpFlags {
- OV_MDP_FLAGS_NONE = 0,
- OV_MDP_PIPE_SHARE = MDP_OV_PIPE_SHARE,
- OV_MDP_PIPE_FORCE_DMA = MDP_OV_PIPE_FORCE_DMA,
- OV_MDP_DEINTERLACE = MDP_DEINTERLACE,
- OV_MDP_SECURE_OVERLAY_SESSION = MDP_SECURE_OVERLAY_SESSION,
- OV_MDP_SECURE_DISPLAY_OVERLAY_SESSION = MDP_SECURE_DISPLAY_OVERLAY_SESSION,
- OV_MDP_SOURCE_ROTATED_90 = MDP_SOURCE_ROTATED_90,
- OV_MDP_BACKEND_COMPOSITION = MDP_BACKEND_COMPOSITION,
- OV_MDP_BLEND_FG_PREMULT = MDP_BLEND_FG_PREMULT,
- OV_MDP_FLIP_H = MDP_FLIP_LR,
- OV_MDP_FLIP_V = MDP_FLIP_UD,
- OV_MDSS_MDP_RIGHT_MIXER = MDSS_MDP_RIGHT_MIXER,
- OV_MDP_PP_EN = MDP_OVERLAY_PP_CFG_EN,
- OV_MDSS_MDP_BWC_EN = MDP_BWC_EN,
- OV_MDSS_MDP_DUAL_PIPE = MDSS_MDP_DUAL_PIPE,
- OV_MDP_SOLID_FILL = MDP_SOLID_FILL,
-};
-
-enum eZorder {
- ZORDER_0 = 0,
- ZORDER_1,
- ZORDER_2,
- ZORDER_3,
- Z_SYSTEM_ALLOC = 0xFFFF
-};
-
-enum eMdpPipeType {
- OV_MDP_PIPE_RGB = 0,
- OV_MDP_PIPE_VG,
- OV_MDP_PIPE_DMA,
- OV_MDP_PIPE_ANY, //Any
-};
-
-// Identify destination pipes
-// TODO Names useless, replace with int and change all interfaces
-enum eDest {
- OV_P0 = 0,
- OV_P1,
- OV_P2,
- OV_P3,
- OV_P4,
- OV_P5,
- OV_P6,
- OV_P7,
- OV_P8,
- OV_P9,
- OV_INVALID,
- OV_MAX = OV_INVALID,
-};
-
-/* Used when a buffer is split over 2 pipes and sent to display */
-enum {
- OV_LEFT_SPLIT = 0,
- OV_RIGHT_SPLIT,
-};
-
-/* values for copybit_set_parameter(OVERLAY_TRANSFORM) */
-enum eTransform {
- /* No rot */
- OVERLAY_TRANSFORM_0 = 0x0,
- /* flip source image horizontally 0x1 */
- OVERLAY_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H,
- /* flip source image vertically 0x2 */
- OVERLAY_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
- /* rotate source image 180 degrees
- * It is basically bit-or-ed H | V == 0x3 */
- OVERLAY_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
- /* rotate source image 90 degrees 0x4 */
- OVERLAY_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
- /* rotate source image 90 degrees and flip horizontally 0x5 */
- OVERLAY_TRANSFORM_ROT_90_FLIP_H = HAL_TRANSFORM_ROT_90 |
- HAL_TRANSFORM_FLIP_H,
- /* rotate source image 90 degrees and flip vertically 0x6 */
- OVERLAY_TRANSFORM_ROT_90_FLIP_V = HAL_TRANSFORM_ROT_90 |
- HAL_TRANSFORM_FLIP_V,
- /* rotate source image 270 degrees
- * Basically 180 | 90 == 0x7 */
- OVERLAY_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
- /* rotate invalid like in Transform.h */
- OVERLAY_TRANSFORM_INV = 0x80
-};
-
-enum eBlending {
- OVERLAY_BLENDING_UNDEFINED = 0x0,
- /* No blending */
- OVERLAY_BLENDING_OPAQUE,
- /* src.rgb + dst.rgb*(1-src_alpha) */
- OVERLAY_BLENDING_PREMULT,
- /* src.rgb * src_alpha + dst.rgb (1 - src_alpha) */
- OVERLAY_BLENDING_COVERAGE,
-};
-
-// Used to consolidate pipe params
-struct PipeArgs {
- PipeArgs() : mdpFlags(OV_MDP_FLAGS_NONE),
- zorder(Z_SYSTEM_ALLOC),
- rotFlags(ROT_FLAGS_NONE),
- planeAlpha(DEFAULT_PLANE_ALPHA),
- blending(OVERLAY_BLENDING_COVERAGE){
- }
-
- PipeArgs(eMdpFlags f, Whf _whf,
- eZorder z, eRotFlags r,
- int pA = DEFAULT_PLANE_ALPHA, eBlending b = OVERLAY_BLENDING_COVERAGE) :
- mdpFlags(f),
- whf(_whf),
- zorder(z),
- rotFlags(r),
- planeAlpha(pA),
- blending(b){
- }
-
- eMdpFlags mdpFlags; // for mdp_overlay flags
- Whf whf;
- eZorder zorder; // stage number
- eRotFlags rotFlags;
- int planeAlpha;
- eBlending blending;
-};
-
-// Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time
-// of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define
-enum { HW_OV_MAGNIFICATION_LIMIT = 20,
- HW_OV_MINIFICATION_LIMIT = 8
-};
-
-inline void setMdpFlags(eMdpFlags& f, eMdpFlags v) {
- f = static_cast<eMdpFlags>(setBit(f, v));
-}
-
-inline void clearMdpFlags(eMdpFlags& f, eMdpFlags v) {
- f = static_cast<eMdpFlags>(clrBit(f, v));
-}
-
-enum { FB0, FB1, FB2 };
-
-struct ScreenInfo {
- ScreenInfo() : mFBWidth(0),
- mFBHeight(0),
- mFBbpp(0),
- mFBystride(0) {}
- void dump(const char* const s) const;
- uint32_t mFBWidth;
- uint32_t mFBHeight;
- uint32_t mFBbpp;
- uint32_t mFBystride;
-};
-
-int getMdpFormat(int format);
-int getMdpFormat(int format, bool tileEnabled);
-int getHALFormat(int mdpFormat);
-void getDecimationFactor(const int& src_w, const int& src_h,
- const int& dst_w, const int& dst_h, uint8_t& horzDeci,
- uint8_t& vertDeci);
-
-/* flip is upside down and such. V, H flip
- * rotation is 90, 180 etc
- * It returns MDP related enum/define that match rot+flip*/
-int getMdpOrient(eTransform rotation);
-const char* getFormatString(int format);
-
-template <class T>
-inline void memset0(T& t) { ::memset(&t, 0, sizeof(t)); }
-
-template <class T> inline void swap ( T& a, T& b )
-{
- T c(a); a=b; b=c;
-}
-
-template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; }
-
-template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; }
-
-inline int alignup(int value, int a) {
- //if align = 0, return the value. Else, do alignment.
- return a ? ((((value - 1) / a) + 1) * a) : value;
-}
-
-inline int aligndown(int value, int a) {
- //if align = 0, return the value. Else, do alignment.
- return a ? ((value) & ~(a-1)) : value;
-}
-
-// FIXME that align should replace the upper one.
-inline int align(int value, int a) {
- //if align = 0, return the value. Else, do alignment.
- return a ? ((value + (a-1)) & ~(a-1)) : value;
-}
-
-inline bool isYuv(uint32_t format) {
- switch(format){
- case MDP_Y_CBCR_H2V1:
- case MDP_Y_CBCR_H2V2:
- case MDP_Y_CRCB_H2V2:
- case MDP_Y_CRCB_H1V1:
- case MDP_Y_CRCB_H2V1:
- case MDP_Y_CRCB_H2V2_TILE:
- case MDP_Y_CBCR_H2V2_TILE:
- case MDP_Y_CR_CB_H2V2:
- case MDP_Y_CR_CB_GH2V2:
- case MDP_Y_CBCR_H2V2_VENUS:
- case MDP_YCBYCR_H2V1:
- case MDP_YCRYCB_H2V1:
- return true;
- default:
- return false;
- }
- return false;
-}
-
-inline bool isRgb(uint32_t format) {
- switch(format) {
- case MDP_RGBA_8888:
- case MDP_BGRA_8888:
- case MDP_RGBX_8888:
- case MDP_RGB_565:
- return true;
- default:
- return false;
- }
- return false;
-}
-
-inline const char* getFormatString(int format){
- #define STR(f) #f;
- static const char* formats[MDP_IMGTYPE_LIMIT + 1] = {0};
- formats[MDP_RGB_565] = STR(MDP_RGB_565);
- formats[MDP_XRGB_8888] = STR(MDP_XRGB_8888);
- formats[MDP_Y_CBCR_H2V2] = STR(MDP_Y_CBCR_H2V2);
- formats[MDP_Y_CBCR_H2V2_ADRENO] = STR(MDP_Y_CBCR_H2V2_ADRENO);
- formats[MDP_ARGB_8888] = STR(MDP_ARGB_8888);
- formats[MDP_RGB_888] = STR(MDP_RGB_888);
- formats[MDP_Y_CRCB_H2V2] = STR(MDP_Y_CRCB_H2V2);
- formats[MDP_YCBYCR_H2V1] = STR(MDP_YCBYCR_H2V1);
- formats[MDP_YCRYCB_H2V1] = STR(MDP_YCRYCB_H2V1);
- formats[MDP_CBYCRY_H2V1] = STR(MDP_CBYCRY_H2V1);
- formats[MDP_Y_CRCB_H2V1] = STR(MDP_Y_CRCB_H2V1);
- formats[MDP_Y_CBCR_H2V1] = STR(MDP_Y_CBCR_H2V1);
- formats[MDP_Y_CRCB_H1V2] = STR(MDP_Y_CRCB_H1V2);
- formats[MDP_Y_CBCR_H1V2] = STR(MDP_Y_CBCR_H1V2);
- formats[MDP_RGBA_8888] = STR(MDP_RGBA_8888);
- formats[MDP_BGRA_8888] = STR(MDP_BGRA_8888);
- formats[MDP_RGBX_8888] = STR(MDP_RGBX_8888);
- formats[MDP_Y_CRCB_H2V2_TILE] = STR(MDP_Y_CRCB_H2V2_TILE);
- formats[MDP_Y_CBCR_H2V2_TILE] = STR(MDP_Y_CBCR_H2V2_TILE);
- formats[MDP_Y_CR_CB_H2V2] = STR(MDP_Y_CR_CB_H2V2);
- formats[MDP_Y_CR_CB_GH2V2] = STR(MDP_Y_CR_CB_GH2V2);
- formats[MDP_Y_CB_CR_H2V2] = STR(MDP_Y_CB_CR_H2V2);
- formats[MDP_Y_CRCB_H1V1] = STR(MDP_Y_CRCB_H1V1);
- formats[MDP_Y_CBCR_H1V1] = STR(MDP_Y_CBCR_H1V1);
- formats[MDP_YCRCB_H1V1] = STR(MDP_YCRCB_H1V1);
- formats[MDP_YCBCR_H1V1] = STR(MDP_YCBCR_H1V1);
- formats[MDP_BGR_565] = STR(MDP_BGR_565);
- formats[MDP_BGR_888] = STR(MDP_BGR_888);
- formats[MDP_Y_CBCR_H2V2_VENUS] = STR(MDP_Y_CBCR_H2V2_VENUS);
- formats[MDP_BGRX_8888] = STR(MDP_BGRX_8888);
- formats[MDP_RGBA_8888_TILE] = STR(MDP_RGBA_8888_TILE);
- formats[MDP_ARGB_8888_TILE] = STR(MDP_ARGB_8888_TILE);
- formats[MDP_ABGR_8888_TILE] = STR(MDP_ABGR_8888_TILE);
- formats[MDP_BGRA_8888_TILE] = STR(MDP_BGRA_8888_TILE);
- formats[MDP_RGBX_8888_TILE] = STR(MDP_RGBX_8888_TILE);
- formats[MDP_XRGB_8888_TILE] = STR(MDP_XRGB_8888_TILE);
- formats[MDP_XBGR_8888_TILE] = STR(MDP_XBGR_8888_TILE);
- formats[MDP_BGRX_8888_TILE] = STR(MDP_BGRX_8888_TILE);
- formats[MDP_RGB_565_TILE] = STR(MDP_RGB_565_TILE);
- formats[MDP_IMGTYPE_LIMIT] = STR(MDP_IMGTYPE_LIMIT);
-
- if(format < 0 || format >= MDP_IMGTYPE_LIMIT) {
- ALOGE("%s wrong fmt %d", __FUNCTION__, format);
- return "Unsupported format";
- }
- if(formats[format] == 0) {
- ALOGE("%s: table missing format %d from header", __FUNCTION__, format);
- return "";
- }
- return formats[format];
-}
-
-inline void Whf::dump() const {
- ALOGE("== Dump WHF w=%d h=%d f=%d s=%d start/end ==",
- w, h, format, size);
-}
-
-inline void Dim::dump() const {
- ALOGE("== Dump Dim x=%d y=%d w=%d h=%d start/end ==", x, y, w, h);
-}
-
-template <class Type>
-void swapWidthHeight(Type& width, Type& height) {
- Type tmp = width;
- width = height;
- height = tmp;
-}
-
-inline void ScreenInfo::dump(const char* const s) const {
- ALOGE("== Dump %s ScreenInfo w=%d h=%d"
- " bpp=%d stride=%d start/end ==",
- s, mFBWidth, mFBHeight, mFBbpp, mFBystride);
-}
-
-inline bool openDev(OvFD& fd, int fbnum,
- const char* const devpath, int flags) {
- return overlay::open(fd, fbnum, devpath, flags);
-}
-
-template <class T>
-inline void even_ceil(T& value) {
- if(value & 1)
- value++;
-}
-
-template <class T>
-inline void even_floor(T& value) {
- if(value & 1)
- value--;
-}
-
-/* Prerotation adjusts crop co-ordinates to the new transformed values within
- * destination buffer. This is necessary only when the entire buffer is rotated
- * irrespective of crop (A-family). If only the crop portion of the buffer is
- * rotated into a destination buffer matching the size of crop, we don't need to
- * use this helper (B-family).
- * @Deprecated as of now, retained for the case where a full buffer needs
- * transform and also as a reference.
- */
-void preRotateSource(const eTransform& tr, Whf& whf, Dim& srcCrop);
-void getDump(char *buf, size_t len, const char *prefix, const mdp_overlay& ov);
-void getDump(char *buf, size_t len, const char *prefix, const msmfb_img& ov);
-void getDump(char *buf, size_t len, const char *prefix, const mdp_rect& ov);
-void getDump(char *buf, size_t len, const char *prefix,
- const msmfb_overlay_data& ov);
-void getDump(char *buf, size_t len, const char *prefix, const msmfb_data& ov);
-void getDump(char *buf, size_t len, const char *prefix,
- const msm_rotator_img_info& ov);
-void getDump(char *buf, size_t len, const char *prefix,
- const msm_rotator_data_info& ov);
-
-} // namespace utils ends
-
-//--------------------Class Res stuff (namespace overlay only) -----------
-
-class Res {
-public:
- // /dev/graphics/fb%u
- static const char* const fbPath;
- // /dev/msm_rotator
- static const char* const rotPath;
-};
-
-
-//--------------------Class OvFD stuff (namespace overlay only) -----------
-
-/*
-* Holds one FD
-* Dtor will NOT close the underlying FD.
-* That enables us to copy that object around
-* */
-class OvFD {
-public:
- /* Ctor */
- explicit OvFD();
-
- /* dtor will NOT close the underlying FD */
- ~OvFD();
-
- /* Open fd using the path given by dev.
- * return false in failure */
- bool open(const char* const dev,
- int flags = O_RDWR);
-
- /* populate path */
- void setPath(const char* const dev);
-
- /* Close fd if we have a valid fd. */
- bool close();
-
- /* returns underlying fd.*/
- int getFD() const;
-
- /* returns true if fd is valid */
- bool valid() const;
-
- /* like operator= */
- void copy(int fd);
-
- /* dump the state of the instance */
- void dump() const;
-private:
- /* helper enum for determine valid/invalid fd */
- enum { INVAL = -1 };
-
- /* actual os fd */
- int mFD;
-
- /* path, for debugging */
- char mPath[utils::MAX_PATH_LEN];
-};
-
-//-------------------Inlines--------------------------
-
-inline bool open(OvFD& fd, uint32_t fbnum, const char* const dev, int flags)
-{
- char dev_name[64] = {0};
- snprintf(dev_name, sizeof(dev_name), dev, fbnum);
- return fd.open(dev_name, flags);
-}
-
-inline OvFD::OvFD() : mFD (INVAL) {
- mPath[0] = 0;
-}
-
-inline OvFD::~OvFD() {
- //no op since copy() can be used to share fd, in 3d cases.
-}
-
-inline bool OvFD::open(const char* const dev, int flags)
-{
- mFD = ::open(dev, flags, 0);
- if (mFD < 0) {
- // FIXME errno, strerror in bionic?
- ALOGE("Cant open device %s err=%d", dev, errno);
- return false;
- }
- setPath(dev);
- return true;
-}
-
-inline void OvFD::setPath(const char* const dev)
-{
- ::strlcpy(mPath, dev, sizeof(mPath));
-}
-
-inline bool OvFD::close()
-{
- int ret = 0;
- if(valid()) {
- ret = ::close(mFD);
- mFD = INVAL;
- }
- return (ret == 0);
-}
-
-inline bool OvFD::valid() const
-{
- return (mFD != INVAL);
-}
-
-inline int OvFD::getFD() const { return mFD; }
-
-inline void OvFD::copy(int fd) {
- mFD = fd;
-}
-
-inline void OvFD::dump() const
-{
- ALOGE("== Dump OvFD fd=%d path=%s start/end ==",
- mFD, mPath);
-}
-
-//--------------- class OvFD stuff ends ---------------------
-
-} // overlay
-
-
-#endif // OVERLAY_UTILS_H
diff --git a/msm8909/liboverlay/overlayWriteback.cpp b/msm8909/liboverlay/overlayWriteback.cpp
deleted file mode 100644
index ed42a9f..0000000
--- a/msm8909/liboverlay/overlayWriteback.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
-* Copyright (c) 2013 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation. nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "overlay.h"
-#include "overlayWriteback.h"
-#include "mdpWrapper.h"
-
-#define SIZE_1M 0x00100000
-
-namespace overlay {
-
-//=========== class WritebackMem ==============================================
-bool WritebackMem::manageMem(uint32_t size, bool isSecure) {
- if(mBuf.bufSz() == size) {
- return true;
- }
- if(mBuf.valid()) {
- if(!mBuf.close()) {
- ALOGE("%s error closing mem", __func__);
- return false;
- }
- }
- return alloc(size, isSecure);
-}
-
-bool WritebackMem::alloc(uint32_t size, bool isSecure) {
- if(!mBuf.open(NUM_BUFS, size, isSecure)){
- ALOGE("%s: Failed to open", __func__);
- mBuf.close();
- return false;
- }
-
- OVASSERT(MAP_FAILED != mBuf.addr(), "MAP failed");
- OVASSERT(mBuf.getFD() != -1, "getFd is -1");
-
- mCurrOffsetIndex = 0;
- for (uint32_t i = 0; i < NUM_BUFS; i++) {
- mOffsets[i] = i * size;
- }
- return true;
-}
-
-bool WritebackMem::dealloc() {
- bool ret = true;
- if(mBuf.valid()) {
- ret = mBuf.close();
- }
- return ret;
-}
-
-//=========== class Writeback =================================================
-Writeback::Writeback() : mXres(0), mYres(0), mOpFmt(-1), mSecure(false) {
- int fbNum = Overlay::getFbForDpy(Overlay::DPY_WRITEBACK);
- if(!utils::openDev(mFd, fbNum, Res::fbPath, O_RDWR)) {
- ALOGE("%s failed to init %s", __func__, Res::fbPath);
- return;
- }
- startSession();
-}
-
-Writeback::~Writeback() {
- stopSession();
- if (!mFd.close()) {
- ALOGE("%s error closing fd", __func__);
- }
-}
-
-bool Writeback::startSession() {
- if(!mdp_wrapper::wbInitStart(mFd.getFD())) {
- ALOGE("%s failed", __func__);
- return false;
- }
- return true;
-}
-
-bool Writeback::stopSession() {
- if(mFd.valid()) {
- if(!Overlay::displayCommit(mFd.getFD())) {
- ALOGE("%s: displayCommit failed", __func__);
- return false;
- }
- if(!mdp_wrapper::wbStopTerminate(mFd.getFD())) {
- ALOGE("%s: wbStopTerminate failed", __func__);
- return false;
- }
- } else {
- ALOGE("%s Invalid fd", __func__);
- return false;
- }
- return true;
-}
-
-bool Writeback::configureDpyInfo(int xres, int yres) {
- if(mXres != xres || mYres != yres) {
- fb_var_screeninfo vinfo;
- memset(&vinfo, 0, sizeof(fb_var_screeninfo));
- if(!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
- ALOGE("%s failed", __func__);
- return false;
- }
- vinfo.xres = xres;
- vinfo.yres = yres;
- vinfo.xres_virtual = xres;
- vinfo.yres_virtual = yres;
- vinfo.xoffset = 0;
- vinfo.yoffset = 0;
- if(!mdp_wrapper::setVScreenInfo(mFd.getFD(), vinfo)) {
- ALOGE("%s failed", __func__);
- return false;
- }
- mXres = xres;
- mYres = yres;
- }
- return true;
-}
-
-bool Writeback::configureMemory(uint32_t size) {
- if(!mWbMem.manageMem(size, mSecure)) {
- ALOGE("%s failed, memory failure", __func__);
- return false;
- }
- return true;
-}
-
-bool Writeback::queueBuffer(int opFd, uint32_t opOffset) {
- memset(&mFbData, 0, sizeof(struct msmfb_data));
- //Queue
- mFbData.offset = opOffset;
- mFbData.memory_id = opFd;
- mFbData.id = 0;
- mFbData.flags = 0;
- if(!mdp_wrapper::wbQueueBuffer(mFd.getFD(), mFbData)) {
- ALOGE("%s: queuebuffer failed", __func__);
- return false;
- }
- return true;
-}
-
-bool Writeback::dequeueBuffer() {
- //Dequeue
- mFbData.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
- if(!mdp_wrapper::wbDequeueBuffer(mFd.getFD(), mFbData)) {
- ALOGE("%s: dequeuebuffer failed", __func__);
- return false;
- }
- return true;
-}
-
-bool Writeback::writeSync(int opFd, uint32_t opOffset) {
- if(!queueBuffer(opFd, opOffset)) {
- return false;
- }
- if(!Overlay::displayCommit(mFd.getFD())) {
- return false;
- }
- if(!dequeueBuffer()) {
- return false;
- }
- return true;
-}
-
-bool Writeback::writeSync() {
- mWbMem.useNextBuffer();
- return writeSync(mWbMem.getDstFd(), mWbMem.getOffset());
-}
-
-bool Writeback::setOutputFormat(int mdpFormat) {
- if(mdpFormat != mOpFmt) {
- struct msmfb_metadata metadata;
- memset(&metadata, 0 , sizeof(metadata));
- metadata.op = metadata_op_wb_format;
- metadata.data.mixer_cfg.writeback_format = mdpFormat;
- if (ioctl(mFd.getFD(), MSMFB_METADATA_SET, &metadata) < 0) {
- ALOGE("Error setting MDP Writeback format");
- return false;
- }
- mOpFmt = mdpFormat;
- }
- return true;
-}
-
-int Writeback::getOutputFormat() {
- if(mOpFmt < 0) {
- struct msmfb_metadata metadata;
- memset(&metadata, 0 , sizeof(metadata));
- metadata.op = metadata_op_wb_format;
- if (ioctl(mFd.getFD(), MSMFB_METADATA_GET, &metadata) < 0) {
- ALOGE("Error retrieving MDP Writeback format");
- return -1;
- }
- mOpFmt = metadata.data.mixer_cfg.writeback_format;
- }
- return mOpFmt;
-}
-
-bool Writeback::setSecure(bool isSecure) {
- if(isSecure != mSecure) {
- // Call IOCTL to set WB interface as secure
- struct msmfb_metadata metadata;
- memset(&metadata, 0 , sizeof(metadata));
- metadata.op = metadata_op_wb_secure;
- metadata.data.secure_en = isSecure;
- if (ioctl(mFd.getFD(), MSMFB_METADATA_SET, &metadata) < 0) {
- ALOGE("Error setting MDP WB secure");
- return false;
- }
- mSecure = isSecure;
- }
- return true;
-}
-
-//static
-
-Writeback *Writeback::getInstance() {
- if(sWb == NULL) {
- sWb = new Writeback();
- }
- sUsed = true;
- return sWb;
-}
-
-void Writeback::configDone() {
- if(sUsed == false && sWb) {
- delete sWb;
- sWb = NULL;
- }
-}
-
-void Writeback::clear() {
- sUsed = false;
- if(sWb) {
- delete sWb;
- sWb = NULL;
- }
-}
-
-bool Writeback::getDump(char *buf, size_t len) {
- if(sWb) {
- utils::getDump(buf, len, "WBData", sWb->mFbData);
- char outputBufferInfo[256];
- snprintf(outputBufferInfo, sizeof(outputBufferInfo),
- "OutputBuffer xres=%d yres=%d format=%s\n\n",
- sWb->getWidth(), sWb->getHeight(),
- utils::getFormatString(sWb->getOutputFormat()));
- strlcat(buf, outputBufferInfo, len);
- return true;
- }
- return false;
-}
-
-Writeback *Writeback::sWb = 0;
-bool Writeback::sUsed = false;
-
-} //namespace overlay
diff --git a/msm8909/liboverlay/overlayWriteback.h b/msm8909/liboverlay/overlayWriteback.h
deleted file mode 100644
index 21186e6..0000000
--- a/msm8909/liboverlay/overlayWriteback.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-* Copyright (c) 2013 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation. nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef OVERLAY_WRITEBACK_H
-#define OVERLAY_WRITEBACK_H
-
-#include "overlayMem.h"
-
-namespace overlay {
-
-class WritebackMgr;
-
-class WritebackMem {
-public:
- explicit WritebackMem() : mCurrOffsetIndex(0) {
- memset(&mOffsets, 0, sizeof(mOffsets));
- }
- ~WritebackMem() { dealloc(); }
- bool manageMem(uint32_t size, bool isSecure);
- void useNextBuffer() {
- mCurrOffsetIndex = (mCurrOffsetIndex + 1) % NUM_BUFS;
- }
- uint32_t getOffset() const { return mOffsets[mCurrOffsetIndex]; }
- int getDstFd() const { return mBuf.getFD(); }
-private:
- bool alloc(uint32_t size, bool isSecure);
- bool dealloc();
- enum { NUM_BUFS = 2 };
- OvMem mBuf;
- uint32_t mOffsets[NUM_BUFS];
- uint32_t mCurrOffsetIndex;
-};
-
-//Abstracts the WB2 interface of MDP
-//Has modes to either manage memory or work with memory allocated elsewhere
-class Writeback {
-public:
- ~Writeback();
- bool configureDpyInfo(int xres, int yres);
- bool configureMemory(uint32_t size);
- /* Blocking write. (queue, commit, dequeue)
- * This class will do writeback memory management.
- * This class will call display-commit on writeback mixer.
- */
- bool writeSync();
- /* Blocking write. (queue, commit, dequeue)
- * Client must do writeback memory management.
- * Client must not call display-commit on writeback mixer.
- */
- bool writeSync(int opFd, uint32_t opOffset);
- /* Async queue. (Does not write)
- * Client must do writeback memory management.
- * Client must call display-commit on their own.
- * Client must use sync mechanism e.g sync pt.
- */
- bool queueBuffer(int opFd, uint32_t opOffset);
- uint32_t getOffset() const { return mWbMem.getOffset(); }
- int getDstFd() const { return mWbMem.getDstFd(); }
- int getWidth() const { return mXres; }
- int getHeight() const { return mYres; }
- /* Subject to GC if writeback isnt used for a drawing round.
- * Get always if caching the value.
- */
- int getFbFd() const { return mFd.getFD(); }
- int getOutputFormat();
- bool setOutputFormat(int mdpFormat);
- bool setSecure(bool isSecure);
-
- static Writeback* getInstance();
- static void configBegin() { sUsed = false; }
- static void configDone();
- static void clear();
- //Will take a dump of data structure only if there is an instance existing
- //Returns true if dump is added to the input buffer, false otherwise
- static bool getDump(char *buf, size_t len);
-
-private:
- explicit Writeback();
- bool startSession();
- bool stopSession();
- //Actually block_until_write_done for the usage here.
- bool dequeueBuffer();
- OvFD mFd;
- WritebackMem mWbMem;
- struct msmfb_data mFbData;
- int mXres;
- int mYres;
- int mOpFmt;
- bool mSecure;
-
- static bool sUsed;
- static Writeback *sWb;
-};
-
-}
-
-#endif
diff --git a/msm8909/liboverlay/pipes/overlayGenPipe.cpp b/msm8909/liboverlay/pipes/overlayGenPipe.cpp
deleted file mode 100644
index aebaebf..0000000
--- a/msm8909/liboverlay/pipes/overlayGenPipe.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "overlayGenPipe.h"
-#include "mdp_version.h"
-
-namespace overlay {
-
-GenericPipe::GenericPipe(const int& dpy) : mDpy(dpy),
- mCtrl(new Ctrl(dpy)), mData(new Data(dpy)) {
-}
-
-GenericPipe::~GenericPipe() {
- delete mCtrl;
- delete mData;
-}
-
-void GenericPipe::setSource(const utils::PipeArgs& args) {
- mCtrl->setSource(args);
-}
-
-void GenericPipe::setCrop(const overlay::utils::Dim& d) {
- mCtrl->setCrop(d);
-}
-
-void GenericPipe::setColor(const uint32_t color) {
- mCtrl->setColor(color);
-}
-
-void GenericPipe::setTransform(const utils::eTransform& orient) {
- mCtrl->setTransform(orient);
-}
-
-void GenericPipe::setPosition(const utils::Dim& d) {
- mCtrl->setPosition(d);
-}
-
-bool GenericPipe::setVisualParams(const MetaData_t &metadata)
-{
- return mCtrl->setVisualParams(metadata);
-}
-
-void GenericPipe::setPipeType(const utils::eMdpPipeType& pType) {
- mCtrl->setPipeType(pType);
-}
-
-bool GenericPipe::commit() {
- return mCtrl->commit();
-}
-
-bool GenericPipe::queueBuffer(int fd, uint32_t offset) {
- int pipeId = mCtrl->getPipeId();
- OVASSERT(-1 != pipeId, "Ctrl ID should not be -1");
- // set pipe id from ctrl to data
- mData->setPipeId(pipeId);
-
- return mData->queueBuffer(fd, offset);
-}
-
-utils::Dim GenericPipe::getCrop() const
-{
- return mCtrl->getCrop();
-}
-
-uint8_t GenericPipe::getPriority() const {
- return mCtrl->getPriority();
-}
-
-void GenericPipe::dump() const
-{
- ALOGE("== Dump Generic pipe start ==");
- mCtrl->dump();
- mData->dump();
- ALOGE("== Dump Generic pipe end ==");
-}
-
-void GenericPipe::getDump(char *buf, size_t len) {
- mCtrl->getDump(buf, len);
- mData->getDump(buf, len);
-}
-
-int GenericPipe::getPipeId() {
- return mCtrl->getPipeId();
-}
-
-bool GenericPipe::validateAndSet(GenericPipe* pipeArray[], const int& count,
- const int& fbFd) {
- Ctrl* ctrlArray[count];
- memset(&ctrlArray, 0, sizeof(ctrlArray));
-
- for(int i = 0; i < count; i++) {
- ctrlArray[i] = pipeArray[i]->mCtrl;
- }
-
- return Ctrl::validateAndSet(ctrlArray, count, fbFd);
-}
-
-} //namespace overlay
diff --git a/msm8909/liboverlay/pipes/overlayGenPipe.h b/msm8909/liboverlay/pipes/overlayGenPipe.h
deleted file mode 100644
index 0a2639a..0000000
--- a/msm8909/liboverlay/pipes/overlayGenPipe.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef OVERLAY_GENERIC_PIPE_H
-#define OVERLAY_GENERIC_PIPE_H
-
-#include "overlayUtils.h"
-#include "overlayCtrlData.h"
-
-namespace overlay {
-
-class GenericPipe : utils::NoCopy {
-public:
- /* ctor */
- explicit GenericPipe(const int& dpy);
- /* dtor */
- ~GenericPipe();
- /* Control APIs */
- /* set source using whf, orient and wait flag */
- void setSource(const utils::PipeArgs& args);
- /* set crop a.k.a the region of interest */
- void setCrop(const utils::Dim& d);
- /* set color for mdp pipe */
- void setColor(const uint32_t color);
- /* set orientation*/
- void setTransform(const utils::eTransform& param);
- /* set mdp posision using dim */
- void setPosition(const utils::Dim& dim);
- /* set visual param */
- bool setVisualParams(const MetaData_t &metadata);
- /* set pipe type RGB/DMA/VG */
- void setPipeType(const utils::eMdpPipeType& pType);
- /* commit changes to the overlay "set"*/
- bool commit();
- /* Data APIs */
- /* queue buffer to the overlay */
- bool queueBuffer(int fd, uint32_t offset);
- /* return cached startup args */
- const utils::PipeArgs& getArgs() const;
- /* retrieve cached crop data */
- utils::Dim getCrop() const;
- /* return pipe priority */
- uint8_t getPriority() const;
- /* dump the state of the object */
- void dump() const;
- /* Return the dump in the specified buffer */
- void getDump(char *buf, size_t len);
- int getPipeId();
-
- static bool validateAndSet(GenericPipe* pipeArray[], const int& count,
- const int& fbFd);
-private:
- int mDpy;
- Ctrl *mCtrl;
- Data *mData;
-};
-
-} //namespace overlay
-
-#endif // OVERLAY_GENERIC_PIPE_H
diff --git a/msm8909/libqdutils/Android.bp b/msm8909/libqdutils/Android.bp
new file mode 100644
index 0000000..3166e8d
--- /dev/null
+++ b/msm8909/libqdutils/Android.bp
@@ -0,0 +1,42 @@
+cc_library_shared {
+ name: "libqdutils",
+ vendor: true,
+ defaults: ["display_defaults"],
+ header_libs: ["libhardware_headers", "libutils_headers"],
+ shared_libs: [
+ "libbinder",
+ "libqservice",
+ ],
+ cflags: [
+ "-DDEBUG_CALC_FPS",
+ "-DLOG_TAG=\"qdutils\"",
+ "-Wno-sign-conversion",
+ ],
+ srcs: [
+ "qd_utils.cpp",
+ "display_config.cpp",
+ "profiler.cpp"
+ ],
+}
+
+cc_library_shared {
+ name: "libqdMetaData",
+ vendor: true,
+ defaults: ["display_defaults"],
+ cflags: [
+ "-Wno-sign-conversion",
+ "-DLOG_TAG=\"qdmetadata\"",
+ ],
+ srcs: ["qdMetaData.cpp","qd_utils.cpp"],
+}
+
+// Remove after WFD moves to use libqdMetaData directly
+cc_library_shared {
+ name: "libqdMetaData.system",
+ defaults: ["display_defaults"],
+ cflags: [
+ "-Wno-sign-conversion",
+ "-DLOG_TAG=\"qdmetadata\"",
+ ],
+ srcs: ["qdMetaData.cpp","qd_utils.cpp"],
+}
diff --git a/msm8909/libqdutils/Android.mk b/msm8909/libqdutils/Android.mk
deleted file mode 100644
index 444ca32..0000000
--- a/msm8909/libqdutils/Android.mk
+++ /dev/null
@@ -1,40 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libqdutils
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := $(common_libs) libui libbinder libqservice
-LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdutils\" -Wno-float-conversion
-LOCAL_CLANG := $(common_clang_flags)
-
-ifeq ($(TARGET_SUPPORTS_WEARABLES),true)
-LOCAL_CFLAGS += -DHDMI_STUB
-endif
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
-LOCAL_COPY_HEADERS := display_config.h mdp_version.h
-LOCAL_SRC_FILES := profiler.cpp mdp_version.cpp \
- idle_invalidator.cpp \
- comptype.cpp qd_utils.cpp \
- cb_utils.cpp display_config.cpp \
- cb_swap_rect.cpp
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
-LOCAL_COPY_HEADERS := qdMetaData.h
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_C_INCLUDES := $(common_includes)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := qdMetaData.cpp
-LOCAL_CFLAGS := $(common_flags)
-LOCAL_CFLAGS += -DLOG_TAG=\"DisplayMetaData\"
-LOCAL_CLANG := $(common_clang_flags)
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := libqdMetaData
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/sdm845/libqdutils/Makefile.am b/msm8909/libqdutils/Makefile.am
similarity index 100%
rename from sdm845/libqdutils/Makefile.am
rename to msm8909/libqdutils/Makefile.am
diff --git a/msm8909/libqdutils/cb_swap_rect.cpp b/msm8909/libqdutils/cb_swap_rect.cpp
deleted file mode 100644
index 8c8efec..0000000
--- a/msm8909/libqdutils/cb_swap_rect.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2014, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation or the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "cb_swap_rect.h"
-
-ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::cb_swap_rect);
-
-namespace qdutils {
-
-cb_swap_rect:: cb_swap_rect(){
- swap_rect_feature_on = false ;
-}
-void cb_swap_rect::setSwapRectFeature_on( bool value){
- swap_rect_feature_on = value ;
-}
-bool cb_swap_rect::checkSwapRectFeature_on(){
- return swap_rect_feature_on;
-}
-
-};
diff --git a/msm8909/libqdutils/cb_swap_rect.h b/msm8909/libqdutils/cb_swap_rect.h
deleted file mode 100644
index daaeb37..0000000
--- a/msm8909/libqdutils/cb_swap_rect.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
-* Redistribution and use in source and binary forms, with or without
-* * modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyrigh
-* notice, this list of conditions and the following disclaimer
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#ifndef CB_SWAP_RECT
-#define CB_SWAP_RECT
-
-#include <stdint.h>
-#include <utils/Singleton.h>
-#include <cutils/log.h>
-
-using namespace android;
-namespace qdutils {
-enum {
-HWC_SKIP_HWC_COMPOSITION = 0x00040000,
-};
-
-class cb_swap_rect : public Singleton <cb_swap_rect>
-{
- bool swap_rect_feature_on;
- public :
- cb_swap_rect();
- void setSwapRectFeature_on( bool value);
- bool checkSwapRectFeature_on();
-};
-} // namespace qdutils
-#endif
diff --git a/msm8909/libqdutils/cb_utils.cpp b/msm8909/libqdutils/cb_utils.cpp
deleted file mode 100644
index ddad35d..0000000
--- a/msm8909/libqdutils/cb_utils.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
-* Redistribution and use in source and binary forms, with or without
-* * modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyrigh
-* notice, this list of conditions and the following disclaimer
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "cb_utils.h"
-#include "cb_swap_rect.h"
-#include <ui/Region.h>
-/* get union of two rects into 3rd rect */
-void getUnion(hwc_rect_t& rect1,hwc_rect_t& rect2, hwc_rect_t& irect) {
-
- irect.left = min(rect1.left, rect2.left);
- irect.top = min(rect1.top, rect2.top);
- irect.right = max(rect1.right, rect2.right);
- irect.bottom = max(rect1.bottom, rect2.bottom);
-}
-
-int clear (copybit_device_t *copybit, private_handle_t* hnd, hwc_rect_t& rect)
-{
- int ret = 0;
- copybit_rect_t clear_rect = {rect.left, rect.top,rect.right,rect.bottom};
-
- copybit_image_t buf;
- buf.w = ALIGN(getWidth(hnd),32);
- buf.h = getHeight(hnd);
- buf.format = hnd->format;
- buf.base = (void *)hnd->base;
- buf.handle = (native_handle_t *)hnd;
-
- ret = copybit->clear(copybit, &buf, &clear_rect);
- return ret;
-}
-using namespace android;
-using namespace qhwc;
-namespace qdutils {
-
-int CBUtils::uiClearRegion(hwc_display_contents_1_t* list,
- int version, LayerProp *layerProp, hwc_rect_t dirtyRect,
- copybit_device_t *copybit, private_handle_t *renderBuffer) {
-
- size_t last = list->numHwLayers - 1;
- hwc_rect_t fbFrame = list->hwLayers[last].displayFrame;
- Rect fbFrameRect(fbFrame.left,fbFrame.top,fbFrame.right,fbFrame.bottom);
- Region wormholeRegion(fbFrameRect);
-
- if ((dirtyRect.right - dirtyRect.left > 0) &&
- (dirtyRect.bottom - dirtyRect.top > 0)) {
-#ifdef QTI_BSP
- Rect tmpRect(dirtyRect.left,dirtyRect.top,dirtyRect.right,
- dirtyRect.bottom);
- Region tmpRegion(tmpRect);
- wormholeRegion = wormholeRegion.intersect(tmpRegion);
-#endif
- }
- if(cb_swap_rect::getInstance().checkSwapRectFeature_on() == true){
- wormholeRegion.set(0,0);
- for(size_t i = 0 ; i < last; i++) {
- if(((list->hwLayers[i].blending == HWC_BLENDING_NONE) &&
- (list->hwLayers[i].planeAlpha == 0xFF)) ||
- !(layerProp[i].mFlags & HWC_COPYBIT) ||
- (list->hwLayers[i].flags & HWC_SKIP_HWC_COMPOSITION))
- continue ;
- hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
- Rect tmpRect(displayFrame.left,displayFrame.top,
- displayFrame.right,displayFrame.bottom);
- wormholeRegion.set(tmpRect);
- }
- }else{
- for (size_t i = 0 ; i < last; i++) {
- // need to take care only in per pixel blending.
- // Restrict calculation only for copybit layers.
- if((list->hwLayers[i].blending != HWC_BLENDING_NONE) ||
- (list->hwLayers[i].planeAlpha != 0xFF) ||
- !(layerProp[i].mFlags & HWC_COPYBIT))
- continue ;
- hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
- Rect tmpRect(displayFrame.left,displayFrame.top,displayFrame.right,
- displayFrame.bottom);
- Region tmpRegion(tmpRect);
- wormholeRegion.subtractSelf(wormholeRegion.intersect(tmpRegion));
- }
- }
- if(wormholeRegion.isEmpty()){
- return 1;
- }
- //TO DO :- 1. remove union and call clear for each rect.
- Region::const_iterator it = wormholeRegion.begin();
- Region::const_iterator const end = wormholeRegion.end();
- while (it != end) {
- const Rect& r = *it++;
- hwc_rect_t tmpWormRect = {r.left,r.top,r.right,r.bottom};
- if (version == qdutils::MDP_V3_0_4 ||
- version == qdutils::MDP_V3_0_5) {
- int clear_w = tmpWormRect.right - tmpWormRect.left;
- int clear_h = tmpWormRect.bottom - tmpWormRect.top;
- //mdp can't handle solid fill for one line
- //making solid fill as full in this case
- //disable swap rect if presents
- if ((clear_w == 1) || (clear_h ==1)) {
- clear(copybit, renderBuffer, fbFrame);
- return 0;
- } else {
- clear(copybit, renderBuffer, tmpWormRect);
- }
- } else {
- clear(copybit, renderBuffer, tmpWormRect);
- }
- }
- return 1;
-}
-
-}//namespace qdutils
diff --git a/msm8909/libqdutils/cb_utils.h b/msm8909/libqdutils/cb_utils.h
deleted file mode 100644
index 8d26b8e..0000000
--- a/msm8909/libqdutils/cb_utils.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
-* Redistribution and use in source and binary forms, with or without
-* * modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyrigh
-* notice, this list of conditions and the following disclaimer
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#ifndef CB_UTIL_H
-#define CB_UTIL_H
-
-#include "hwc_utils.h"
-#include "copybit.h"
-
-using namespace qhwc;
-namespace qdutils {
-class CBUtils {
-public:
- static int uiClearRegion(hwc_display_contents_1_t* list,
- int version, LayerProp *layerProp, hwc_rect_t dirtyIndex,
- copybit_device_t *copybit, private_handle_t *renderBuffer);
-};
-}//namespace qdutils
-#endif /* end of include guard: CB_UTIL_H*/
-
diff --git a/msm8909/libqdutils/comptype.cpp b/msm8909/libqdutils/comptype.cpp
deleted file mode 100644
index a29158a..0000000
--- a/msm8909/libqdutils/comptype.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation or the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include<comptype.h>
-
-//Instanticate the QCCompositionType Singleton
-ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::QCCompositionType);
diff --git a/msm8909/libqdutils/comptype.h b/msm8909/libqdutils/comptype.h
deleted file mode 100644
index 71f4871..0000000
--- a/msm8909/libqdutils/comptype.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation or the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef INCLUDE_LIBQCOM_COMPTYPES
-#define INCLUDE_LIBQCOM_COMPTYPES
-
-#include <stdint.h>
-#include <utils/Singleton.h>
-#include <cutils/properties.h>
-
-using namespace android;
-namespace qdutils {
-// Enum containing the supported composition types
-enum {
- COMPOSITION_TYPE_GPU = 0,
- COMPOSITION_TYPE_MDP = 0x1,
- COMPOSITION_TYPE_C2D = 0x2,
- COMPOSITION_TYPE_CPU = 0x4,
- COMPOSITION_TYPE_DYN = 0x8
-};
-
-/* This class caches the composition type
- */
-class QCCompositionType : public Singleton <QCCompositionType>
-{
- public:
- QCCompositionType();
- ~QCCompositionType() { }
- int getCompositionType() {return mCompositionType;}
- private:
- int mCompositionType;
-
-};
-
-inline QCCompositionType::QCCompositionType()
-{
- char property[PROPERTY_VALUE_MAX];
- mCompositionType = COMPOSITION_TYPE_GPU;
- if (property_get("debug.composition.type", property, "gpu") > 0) {
- if ((strncmp(property, "mdp", 3)) == 0) {
- mCompositionType = COMPOSITION_TYPE_MDP;
- } else if ((strncmp(property, "c2d", 3)) == 0) {
- mCompositionType = COMPOSITION_TYPE_C2D;
- } else if ((strncmp(property, "dyn", 3)) == 0) {
-#ifdef USE_MDP3
- mCompositionType = COMPOSITION_TYPE_DYN | COMPOSITION_TYPE_MDP;
-#else
- mCompositionType = COMPOSITION_TYPE_DYN | COMPOSITION_TYPE_C2D;
-#endif
- }
- }
-}
-
-}; //namespace qdutils
-#endif //INCLUDE_LIBQCOM_COMPTYPES
diff --git a/msm8909/libqdutils/display_config.cpp b/msm8909/libqdutils/display_config.cpp
index 62422fe..83d912e 100644
--- a/msm8909/libqdutils/display_config.cpp
+++ b/msm8909/libqdutils/display_config.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -27,14 +27,24 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <display_config.h>
#include <QServiceUtils.h>
+#include <qd_utils.h>
using namespace android;
using namespace qService;
namespace qdutils {
+//=============================================================================
+// The functions below run in the client process and wherever necessary
+// do a binder call to HWC to get/set data.
+
int isExternalConnected(void) {
int ret;
status_t err = (status_t) FAILED_TRANSACTION;
@@ -68,9 +78,9 @@
dpyattr.yres = outParcel.readInt32();
dpyattr.xdpi = outParcel.readFloat();
dpyattr.ydpi = outParcel.readFloat();
- dpyattr.panel_type = (char) outParcel.readInt32();
+ dpyattr.panel_type = outParcel.readInt32();
} else {
- ALOGE("%s: Failed to get display attributes err=%d", __FUNCTION__, err);
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
}
return err;
}
@@ -170,22 +180,189 @@
return err;
}
-}; //namespace
+int getConfigCount(int /*dpy*/) {
+ int numConfigs = -1;
+ sp<IQService> binder = getBinder();
+ if(binder != NULL) {
+ Parcel inParcel, outParcel;
+ inParcel.writeInt32(DISPLAY_PRIMARY);
+ status_t err = binder->dispatch(IQService::GET_CONFIG_COUNT,
+ &inParcel, &outParcel);
+ if(!err) {
+ numConfigs = outParcel.readInt32();
+ ALOGI("%s() Received num configs %d", __FUNCTION__, numConfigs);
+ } else {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ }
+ }
+ return numConfigs;
+}
+
+int getActiveConfig(int dpy) {
+ int configIndex = -1;
+ sp<IQService> binder = getBinder();
+ if(binder != NULL) {
+ Parcel inParcel, outParcel;
+ inParcel.writeInt32(dpy);
+ status_t err = binder->dispatch(IQService::GET_ACTIVE_CONFIG,
+ &inParcel, &outParcel);
+ if(!err) {
+ configIndex = outParcel.readInt32();
+ ALOGI("%s() Received active config index %d", __FUNCTION__,
+ configIndex);
+ } else {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ }
+ }
+ return configIndex;
+}
+
+int setActiveConfig(int configIndex, int /*dpy*/) {
+ status_t err = (status_t) FAILED_TRANSACTION;
+ sp<IQService> binder = getBinder();
+ if(binder != NULL) {
+ Parcel inParcel, outParcel;
+ inParcel.writeInt32(configIndex);
+ inParcel.writeInt32(DISPLAY_PRIMARY);
+ err = binder->dispatch(IQService::SET_ACTIVE_CONFIG,
+ &inParcel, &outParcel);
+ if(!err) {
+ ALOGI("%s() Successfully set active config index %d", __FUNCTION__,
+ configIndex);
+ } else {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ }
+ }
+ return err;
+}
+
+DisplayAttributes getDisplayAttributes(int configIndex, int dpy) {
+ DisplayAttributes dpyattr = {};
+ sp<IQService> binder = getBinder();
+ if(binder != NULL) {
+ Parcel inParcel, outParcel;
+ inParcel.writeInt32(configIndex);
+ inParcel.writeInt32(dpy);
+ status_t err = binder->dispatch(
+ IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG, &inParcel,
+ &outParcel);
+ if(!err) {
+ dpyattr.vsync_period = outParcel.readInt32();
+ dpyattr.xres = outParcel.readInt32();
+ dpyattr.yres = outParcel.readInt32();
+ dpyattr.xdpi = outParcel.readFloat();
+ dpyattr.ydpi = outParcel.readFloat();
+ dpyattr.panel_type = outParcel.readInt32();
+ dpyattr.is_yuv = outParcel.readInt32();
+ ALOGI("%s() Received attrs for index %d: xres %d, yres %d",
+ __FUNCTION__, configIndex, dpyattr.xres, dpyattr.yres);
+ } else {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ }
+ }
+ return dpyattr;
+}
+
+int setPanelMode(int mode) {
+ status_t err = (status_t) FAILED_TRANSACTION;
+ sp<IQService> binder = getBinder();
+ if(binder != NULL) {
+ Parcel inParcel, outParcel;
+ inParcel.writeInt32(mode);
+ err = binder->dispatch(IQService::SET_DISPLAY_MODE,
+ &inParcel, &outParcel);
+ if(!err) {
+ ALOGI("%s() Successfully set the display mode to %d", __FUNCTION__,
+ mode);
+ } else {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ }
+ }
+ return err;
+}
+
+int setPanelBrightness(int level) {
+ status_t err = (status_t) FAILED_TRANSACTION;
+ sp<IQService> binder = getBinder();
+ Parcel inParcel, outParcel;
+
+ if(binder != NULL) {
+ inParcel.writeInt32(level);
+ status_t err = binder->dispatch(IQService::SET_PANEL_BRIGHTNESS,
+ &inParcel, &outParcel);
+ if(err) {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ }
+ }
+ return err;
+}
+
+int getPanelBrightness() {
+ int panel_brightness = -1;
+ sp<IQService> binder = getBinder();
+ Parcel inParcel, outParcel;
+
+ if(binder != NULL) {
+ status_t err = binder->dispatch(IQService::GET_PANEL_BRIGHTNESS,
+ &inParcel, &outParcel);
+ if(!err) {
+ panel_brightness = outParcel.readInt32();
+ ALOGI("%s() Current panel brightness value %d", __FUNCTION__,
+ panel_brightness);
+ } else {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ }
+ }
+ return panel_brightness;
+}
+
+}// namespace
// ----------------------------------------------------------------------------
-// Screen refresh for native daemons linking dynamically to libqdutils
+// Functions for linking dynamically to libqdutils
// ----------------------------------------------------------------------------
+extern "C" int minHdcpEncryptionLevelChanged(int dpy, int min_enc_level) {
+ status_t err = (status_t) FAILED_TRANSACTION;
+ sp<IQService> binder = getBinder();
+ Parcel inParcel, outParcel;
+ inParcel.writeInt32(dpy);
+ inParcel.writeInt32(min_enc_level);
+
+ if(binder != NULL) {
+ err = binder->dispatch(IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED,
+ &inParcel, &outParcel);
+ }
+
+ if(err) {
+ ALOGE("%s: Failed for dpy %d err=%d", __FUNCTION__, dpy, err);
+ } else {
+ err = outParcel.readInt32();
+ }
+
+ return err;
+}
+
extern "C" int refreshScreen() {
int ret = 0;
ret = screenRefresh();
return ret;
}
-// ----------------------------------------------------------------------------
-// Native daemons needs to send enable partial update ack for PU to enable
-// ----------------------------------------------------------------------------
-extern "C" int setPartialUpdateState() {
- int ret = 0;
- ret = setPartialUpdate(IQService::ENABLE_PARTIAL_UPDATE);
- return ret;
+extern "C" int controlPartialUpdate(int dpy, int mode) {
+ status_t err = (status_t) FAILED_TRANSACTION;
+ sp<IQService> binder = getBinder();
+ if(binder != NULL) {
+ Parcel inParcel, outParcel;
+ inParcel.writeInt32(dpy);
+ inParcel.writeInt32(mode);
+ err = binder->dispatch(IQService::CONTROL_PARTIAL_UPDATE, &inParcel, &outParcel);
+ if(err != 0) {
+ ALOGE_IF(getBinder(), "%s() failed with err %d", __FUNCTION__, err);
+ } else {
+ return outParcel.readInt32();
+ }
+ }
+
+ return err;
}
+
diff --git a/msm8909/libqdutils/display_config.h b/msm8909/libqdutils/display_config.h
index e9b2fc3..6512bf5 100644
--- a/msm8909/libqdutils/display_config.h
+++ b/msm8909/libqdutils/display_config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2016 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -26,24 +26,33 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
+#ifndef _DISPLAY_CONFIG_H
+#define _DISPLAY_CONFIG_H
+
#include <gralloc_priv.h>
#include <qdMetaData.h>
-#include <mdp_version.h>
#include <hardware/hwcomposer.h>
-// This header is for clients to use to set/get global display configuration
-// The functions in this header run in the client process and wherever necessary
-// do a binder call to HWC to get/set data.
+// This header is for clients to use to set/get global display configuration.
// Only primary and external displays are supported here.
-// WiFi/virtual displays are not supported.
namespace qdutils {
+
+/* TODO: Have all the common enums that need be exposed to clients and which
+ * are also needed in hwc defined here. Remove such definitions we have in
+ * hwc_utils.h
+ */
+
// Use this enum to specify the dpy parameters where needed
enum {
- DISPLAY_PRIMARY = HWC_DISPLAY_PRIMARY,
+ DISPLAY_PRIMARY = HWC_DISPLAY_PRIMARY,
DISPLAY_EXTERNAL = HWC_DISPLAY_EXTERNAL,
- DISPLAY_VIRTUAL = HWC_DISPLAY_VIRTUAL,
+#ifdef QTI_BSP
+ DISPLAY_TERTIARY = HWC_DISPLAY_TERTIARY,
+#endif
+ DISPLAY_VIRTUAL = HWC_DISPLAY_VIRTUAL,
};
// External Display states - used in setSecondaryDisplayStatus()
@@ -61,16 +70,37 @@
SET_BINDER_DYN_REFRESH_RATE,
};
+enum {
+ DEFAULT_MODE = 0,
+ VIDEO_MODE,
+ COMMAND_MODE,
+};
+
+enum {
+ DISPLAY_PORT_DEFAULT = 0,
+ DISPLAY_PORT_DSI,
+ DISPLAY_PORT_DTV,
+ DISPLAY_PORT_WRITEBACK,
+ DISPLAY_PORT_LVDS,
+ DISPLAY_PORT_EDP,
+ DISPLAY_PORT_DP,
+};
+
// Display Attributes that are available to clients of this library
// Not to be confused with a similar struct in hwc_utils (in the hwc namespace)
-struct DisplayAttributes_t {
- uint32_t vsync_period; //nanoseconds
- uint32_t xres;
- uint32_t yres;
- float xdpi;
- float ydpi;
- char panel_type;
-};
+typedef struct DisplayAttributes {
+ uint32_t vsync_period = 0; //nanoseconds
+ uint32_t xres = 0;
+ uint32_t yres = 0;
+ float xdpi = 0.0f;
+ float ydpi = 0.0f;
+ int panel_type = DISPLAY_PORT_DEFAULT;
+ bool is_yuv = false;
+} DisplayAttributes_t;
+
+//=============================================================================
+// The functions below run in the client process and wherever necessary
+// do a binder call to HWC to get/set data.
// Check if external display is connected. Useful to check before making
// calls for external displays
@@ -98,4 +128,36 @@
// Enable/Disable/Set refresh rate dynamically
int configureDynRefreshRate(uint32_t op, uint32_t refreshRate);
+
+// Returns the number of configs supported for the display on success.
+// Returns -1 on error.
+// Only primary display supported for now, value of dpy ignored.
+int getConfigCount(int dpy);
+
+// Returns the index of config that is current set for the display on success.
+// Returns -1 on error.
+// Only primary display supported for now, value of dpy ignored.
+int getActiveConfig(int dpy);
+
+// Sets the config for the display on success and returns 0.
+// Returns -1 on error.
+// Only primary display supported for now, value of dpy ignored
+int setActiveConfig(int configIndex, int dpy);
+
+// Returns the attributes for the specified config for the display on success.
+// Returns xres and yres as 0 on error.
+// Only primary display supported for now, value of dpy ignored
+DisplayAttributes getDisplayAttributes(int configIndex, int dpy);
+
+// Set the primary display mode to command or video mode
+int setDisplayMode(int mode);
+
+// Sets the panel brightness of the primary display
+int setPanelBrightness(int level);
+
+// Retrieves the current panel brightness value
+int getPanelBrightness();
+
}; //namespace
+
+#endif
diff --git a/msm8909/libqdutils/idle_invalidator.cpp b/msm8909/libqdutils/idle_invalidator.cpp
deleted file mode 100644
index b8db0bf..0000000
--- a/msm8909/libqdutils/idle_invalidator.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "idle_invalidator.h"
-#include <unistd.h>
-#include <poll.h>
-#include <string.h>
-#include <fcntl.h>
-#include <cutils/properties.h>
-
-#define II_DEBUG 0
-#define IDLE_NOTIFY_PATH "/sys/devices/virtual/graphics/fb0/idle_notify"
-#define IDLE_TIME_PATH "/sys/devices/virtual/graphics/fb0/idle_time"
-
-
-static const char *threadName = "IdleInvalidator";
-InvalidatorHandler IdleInvalidator::mHandler = NULL;
-android::sp<IdleInvalidator> IdleInvalidator::sInstance(0);
-
-IdleInvalidator::IdleInvalidator(): Thread(false), mHwcContext(0),
- mTimeoutEventFd(-1) {
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
-}
-
-IdleInvalidator::~IdleInvalidator() {
- if(mTimeoutEventFd >= 0) {
- close(mTimeoutEventFd);
- }
-}
-
-int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data) {
- mHandler = reg_handler;
- mHwcContext = user_data;
-
- // Open a sysfs node to receive the timeout notification from driver.
- mTimeoutEventFd = open(IDLE_NOTIFY_PATH, O_RDONLY);
- if (mTimeoutEventFd < 0) {
- ALOGE ("%s:not able to open %s node %s",
- __FUNCTION__, IDLE_NOTIFY_PATH, strerror(errno));
- return -1;
- }
-
- int defaultIdleTime = 70; //ms
- char property[PROPERTY_VALUE_MAX] = {0};
- if((property_get("debug.mdpcomp.idletime", property, NULL) > 0)) {
- defaultIdleTime = atoi(property);
- }
- if(not setIdleTimeout(defaultIdleTime)) {
- close(mTimeoutEventFd);
- mTimeoutEventFd = -1;
- return -1;
- }
-
- //Triggers the threadLoop to run, if not already running.
- run(threadName, android::PRIORITY_LOWEST);
- return 0;
-}
-
-bool IdleInvalidator::setIdleTimeout(const uint32_t& timeout) {
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s timeout %d",
- __FUNCTION__, timeout);
-
- // Open a sysfs node to send the timeout value to driver.
- int fd = open(IDLE_TIME_PATH, O_WRONLY);
-
- if (fd < 0) {
- ALOGE ("%s:Unable to open %s node %s",
- __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
- return false;
- }
-
- char strSleepTime[64];
- snprintf(strSleepTime, sizeof(strSleepTime), "%d", timeout);
-
- // Notify driver about the timeout value
- ssize_t len = pwrite(fd, strSleepTime, strlen(strSleepTime), 0);
- if(len < -1) {
- ALOGE ("%s:Unable to write into %s node %s",
- __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
- close(fd);
- return false;
- }
-
- close(fd);
- return true;
-}
-
-bool IdleInvalidator::threadLoop() {
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
- struct pollfd pFd;
- pFd.fd = mTimeoutEventFd;
- if (pFd.fd >= 0)
- pFd.events = POLLPRI | POLLERR;
- // Poll for an timeout event from driver
- int err = poll(&pFd, 1, -1);
- if(err > 0) {
- if (pFd.revents & POLLPRI) {
- char data[64];
- // Consume the node by reading it
- ssize_t len = pread(pFd.fd, data, 64, 0);
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s Idle Timeout fired len %zd",
- __FUNCTION__, len);
- mHandler((void*)mHwcContext);
- }
- }
- return true;
-}
-
-int IdleInvalidator::readyToRun() {
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
- return 0; /*NO_ERROR*/
-}
-
-void IdleInvalidator::onFirstRef() {
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
-}
-
-IdleInvalidator *IdleInvalidator::getInstance() {
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
- if(sInstance.get() == NULL)
- sInstance = new IdleInvalidator();
- return sInstance.get();
-}
diff --git a/msm8909/libqdutils/idle_invalidator.h b/msm8909/libqdutils/idle_invalidator.h
deleted file mode 100644
index 52334a0..0000000
--- a/msm8909/libqdutils/idle_invalidator.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef INCLUDE_IDLEINVALIDATOR
-#define INCLUDE_IDLEINVALIDATOR
-
-#include <cutils/log.h>
-#include <utils/threads.h>
-#include <gr.h>
-
-typedef void (*InvalidatorHandler)(void*);
-
-class IdleInvalidator : public android::Thread {
- IdleInvalidator();
- void *mHwcContext;
- int mTimeoutEventFd;
- static InvalidatorHandler mHandler;
- static android::sp<IdleInvalidator> sInstance;
-
-public:
- ~IdleInvalidator();
- /* init timer obj */
- int init(InvalidatorHandler reg_handler, void* user_data);
- bool setIdleTimeout(const uint32_t& timeout);
-
- /*Overrides*/
- virtual bool threadLoop();
- virtual int readyToRun();
- virtual void onFirstRef();
- static IdleInvalidator *getInstance();
-};
-
-#endif // INCLUDE_IDLEINVALIDATOR
diff --git a/msm8909/libqdutils/mdp_version.cpp b/msm8909/libqdutils/mdp_version.cpp
deleted file mode 100644
index 088f82b..0000000
--- a/msm8909/libqdutils/mdp_version.cpp
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <cutils/log.h>
-#include <linux/msm_mdp.h>
-#include "mdp_version.h"
-#include "qd_utils.h"
-
-#define DEBUG 0
-
-ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::MDPVersion);
-namespace qdutils {
-
-#define TOKEN_PARAMS_DELIM "="
-
-// chip variants have same major number and minor numbers usually vary
-// for e.g., MDSS_MDP_HW_REV_101 is 0x10010000
-// 1001 - major number
-// 0000 - minor number
-// 8x26 v1 minor number is 0000
-// v2 minor number is 0001 etc..
-#ifndef MDSS_MDP_HW_REV_100
-#define MDSS_MDP_HW_REV_100 0x10000000 //8974 v1
-#endif
-#ifndef MDSS_MDP_HW_REV_101
-#define MDSS_MDP_HW_REV_101 0x10010000 //8x26
-#endif
-#ifndef MDSS_MDP_HW_REV_102
-#define MDSS_MDP_HW_REV_102 0x10020000 //8974 v2
-#endif
-#ifndef MDSS_MDP_HW_REV_103
-#define MDSS_MDP_HW_REV_103 0x10030000 //8084
-#endif
-#ifndef MDSS_MDP_HW_REV_104
-#define MDSS_MDP_HW_REV_104 0x10040000 //Next version
-#endif
-#ifndef MDSS_MDP_HW_REV_105
-#define MDSS_MDP_HW_REV_105 0x10050000 //8994
-#endif
-#ifndef MDSS_MDP_HW_REV_106
-#define MDSS_MDP_HW_REV_106 0x10060000 //8x16
-#endif
-#ifndef MDSS_MDP_HW_REV_107
-#define MDSS_MDP_HW_REV_107 0x10070000 //Next version
-#endif
-#ifndef MDSS_MDP_HW_REV_108
-#define MDSS_MDP_HW_REV_108 0x10080000 //8x39 & 8x36
-#endif
-#ifndef MDSS_MDP_HW_REV_109
-#define MDSS_MDP_HW_REV_109 0x10090000 //Next version
-#endif
-#ifndef MDSS_MDP_HW_REV_200
-#define MDSS_MDP_HW_REV_200 0x20000000 //8092
-#endif
-#ifndef MDSS_MDP_HW_REV_206
-#define MDSS_MDP_HW_REV_206 0x20060000 //Future
-#endif
-
-MDPVersion::MDPVersion()
-{
- mMDPVersion = MDSS_V5;
- mMdpRev = 0;
- mRGBPipes = 0;
- mVGPipes = 0;
- mDMAPipes = 0;
- mFeatures = 0;
- mMDPUpscale = 1;
- mMDPDownscale = 1;
- mMacroTileEnabled = false;
- mLowBw = 0;
- mHighBw = 0;
- mSourceSplit = false;
- mSourceSplitAlways = false;
- mRGBHasNoScalar = false;
- mRotDownscale = false;
-
- // this is the default limit of mixer unless driver reports it.
- // For resolutions beyond this, we use dual/split overlay pipes.
- mMaxMixerWidth = 2048;
-
- updatePanelInfo();
-
- if(!updateSysFsInfo()) {
- ALOGE("Unable to read display sysfs node");
- }
- if (mMdpRev == MDP_V3_0_4){
- mMDPVersion = MDP_V3_0_4;
- }
- else if (mMdpRev == MDP_V3_0_5){
- mMDPVersion = MDP_V3_0_5;
- }
-
- mHasOverlay = false;
- if((mMDPVersion >= MDP_V4_0) ||
- (mMDPVersion == MDP_V_UNKNOWN) ||
- (mMDPVersion == MDP_V3_0_4) ||
- (mMDPVersion == MDP_V3_0_5))
- mHasOverlay = true;
- if(!updateSplitInfo()) {
- ALOGE("Unable to read display split node");
- }
-}
-
-MDPVersion::~MDPVersion() {
- close(mFd);
-}
-
-int MDPVersion::tokenizeParams(char *inputParams, const char *delim,
- char* tokenStr[], int *idx) {
- char *tmp_token = NULL;
- char *temp_ptr;
- int index = 0;
- if (!inputParams) {
- return -1;
- }
- tmp_token = strtok_r(inputParams, delim, &temp_ptr);
- while (tmp_token != NULL) {
- tokenStr[index++] = tmp_token;
- tmp_token = strtok_r(NULL, " ", &temp_ptr);
- }
- *idx = index;
- return 0;
-}
-// This function reads the sysfs node to read the primary panel type
-// and updates information accordingly
-void MDPVersion::updatePanelInfo() {
- FILE *displayDeviceFP = NULL;
- FILE *panelInfoNodeFP = NULL;
- char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
- const char *strCmdPanel = "mipi dsi cmd panel";
- const char *strVideoPanel = "mipi dsi video panel";
- const char *strLVDSPanel = "lvds panel";
- const char *strEDPPanel = "edp panel";
-
- displayDeviceFP = fopen("/sys/class/graphics/fb0/msm_fb_type", "r");
- if(displayDeviceFP){
- fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
- displayDeviceFP);
- if(strncmp(fbType, strCmdPanel, strlen(strCmdPanel)) == 0) {
- mPanelInfo.mType = MIPI_CMD_PANEL;
- }
- else if(strncmp(fbType, strVideoPanel, strlen(strVideoPanel)) == 0) {
- mPanelInfo.mType = MIPI_VIDEO_PANEL;
- }
- else if(strncmp(fbType, strLVDSPanel, strlen(strLVDSPanel)) == 0) {
- mPanelInfo.mType = LVDS_PANEL;
- }
- else if(strncmp(fbType, strEDPPanel, strlen(strEDPPanel)) == 0) {
- mPanelInfo.mType = EDP_PANEL;
- }
- fclose(displayDeviceFP);
- } else {
- ALOGE("Unable to read Primary Panel Information");
- }
-
- panelInfoNodeFP = fopen("/sys/class/graphics/fb0/msm_fb_panel_info", "r");
- if(panelInfoNodeFP){
- size_t len = PAGE_SIZE;
- ssize_t read;
- char *readLine = (char *) malloc (len);
- char property[PROPERTY_VALUE_MAX];
- while((read = getline((char **)&readLine, &len,
- panelInfoNodeFP)) != -1) {
- int token_ct=0;
- char *tokens[10];
- memset(tokens, 0, sizeof(tokens));
-
- if(!tokenizeParams(readLine, TOKEN_PARAMS_DELIM, tokens,
- &token_ct)) {
- if(!strncmp(tokens[0], "pu_en", strlen("pu_en"))) {
- mPanelInfo.mPartialUpdateEnable = atoi(tokens[1]);
- ALOGI("PartialUpdate status: %s",
- mPanelInfo.mPartialUpdateEnable? "Enabled" :
- "Disabled");
- }
- if(!strncmp(tokens[0], "xstart", strlen("xstart"))) {
- mPanelInfo.mLeftAlign = atoi(tokens[1]);
- ALOGI("Left Align: %d", mPanelInfo.mLeftAlign);
- }
- if(!strncmp(tokens[0], "walign", strlen("walign"))) {
- mPanelInfo.mWidthAlign = atoi(tokens[1]);
- ALOGI("Width Align: %d", mPanelInfo.mWidthAlign);
- }
- if(!strncmp(tokens[0], "ystart", strlen("ystart"))) {
- mPanelInfo.mTopAlign = atoi(tokens[1]);
- ALOGI("Top Align: %d", mPanelInfo.mTopAlign);
- }
- if(!strncmp(tokens[0], "halign", strlen("halign"))) {
- mPanelInfo.mHeightAlign = atoi(tokens[1]);
- ALOGI("Height Align: %d", mPanelInfo.mHeightAlign);
- }
- if(!strncmp(tokens[0], "min_w", strlen("min_w"))) {
- mPanelInfo.mMinROIWidth = atoi(tokens[1]);
- ALOGI("Min ROI Width: %d", mPanelInfo.mMinROIWidth);
- }
- if(!strncmp(tokens[0], "min_h", strlen("min_h"))) {
- mPanelInfo.mMinROIHeight = atoi(tokens[1]);
- ALOGI("Min ROI Height: %d", mPanelInfo.mMinROIHeight);
- }
- if(!strncmp(tokens[0], "roi_merge", strlen("roi_merge"))) {
- mPanelInfo.mNeedsROIMerge = atoi(tokens[1]);
- ALOGI("Needs ROI Merge: %d", mPanelInfo.mNeedsROIMerge);
- }
- if(!strncmp(tokens[0], "dyn_fps_en", strlen("dyn_fps_en"))) {
- mPanelInfo.mDynFpsSupported = atoi(tokens[1]);
- ALOGI("Dynamic Fps: %s", mPanelInfo.mDynFpsSupported ?
- "Enabled" : "Disabled");
- }
- if(!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
- mPanelInfo.mMinFps = atoi(tokens[1]);
- ALOGI("Min Panel fps: %d", mPanelInfo.mMinFps);
- }
- if(!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
- mPanelInfo.mMaxFps = atoi(tokens[1]);
- ALOGI("Max Panel fps: %d", mPanelInfo.mMaxFps);
- }
- }
- }
- if((property_get("persist.hwc.pubypass", property, 0) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- mPanelInfo.mPartialUpdateEnable = 0;
- ALOGI("PartialUpdate disabled by property");
- }
- fclose(panelInfoNodeFP);
- } else {
- ALOGE("Failed to open msm_fb_panel_info node");
- }
-}
-
-// This function reads the sysfs node to read MDP capabilities
-// and parses and updates information accordingly.
-bool MDPVersion::updateSysFsInfo() {
- FILE *sysfsFd;
- size_t len = PAGE_SIZE;
- ssize_t read;
- char *line = NULL;
- char sysfsPath[255];
- memset(sysfsPath, 0, sizeof(sysfsPath));
- snprintf(sysfsPath , sizeof(sysfsPath),
- "/sys/class/graphics/fb0/mdp/caps");
- char property[PROPERTY_VALUE_MAX];
- bool enableMacroTile = false;
-
- if((property_get("persist.hwc.macro_tile_enable", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- enableMacroTile = true;
- }
-
- sysfsFd = fopen(sysfsPath, "rb");
-
- if (sysfsFd == NULL) {
- ALOGE("%s: sysFsFile file '%s' not found",
- __FUNCTION__, sysfsPath);
- return false;
- } else {
- line = (char *) malloc(len);
- while((read = getline(&line, &len, sysfsFd)) != -1) {
- int index=0;
- char *tokens[10];
- memset(tokens, 0, sizeof(tokens));
-
- // parse the line and update information accordingly
- if(!tokenizeParams(line, TOKEN_PARAMS_DELIM, tokens, &index)) {
- if(!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
- mMdpRev = atoi(tokens[1]);
- }
- else if(!strncmp(tokens[0], "rgb_pipes", strlen("rgb_pipes"))) {
- mRGBPipes = (uint8_t)atoi(tokens[1]);
- }
- else if(!strncmp(tokens[0], "vig_pipes", strlen("vig_pipes"))) {
- mVGPipes = (uint8_t)atoi(tokens[1]);
- }
- else if(!strncmp(tokens[0], "dma_pipes", strlen("dma_pipes"))) {
- mDMAPipes = (uint8_t)atoi(tokens[1]);
- }
- else if(!strncmp(tokens[0], "max_downscale_ratio",
- strlen("max_downscale_ratio"))) {
- mMDPDownscale = atoi(tokens[1]);
- }
- else if(!strncmp(tokens[0], "max_upscale_ratio",
- strlen("max_upscale_ratio"))) {
- mMDPUpscale = atoi(tokens[1]);
- } else if(!strncmp(tokens[0], "max_bandwidth_low",
- strlen("max_bandwidth_low"))) {
- mLowBw = atol(tokens[1]);
- } else if(!strncmp(tokens[0], "max_bandwidth_high",
- strlen("max_bandwidth_high"))) {
- mHighBw = atol(tokens[1]);
- } else if(!strncmp(tokens[0], "max_mixer_width",
- strlen("max_mixer_width"))) {
- mMaxMixerWidth = atoi(tokens[1]);
- } else if(!strncmp(tokens[0], "features", strlen("features"))) {
- for(int i=1; i<index;i++) {
- if(!strncmp(tokens[i], "bwc", strlen("bwc"))) {
- mFeatures |= MDP_BWC_EN;
- } else if(!strncmp(tokens[i], "decimation",
- strlen("decimation"))) {
- mFeatures |= MDP_DECIMATION_EN;
- } else if(!strncmp(tokens[i], "tile_format",
- strlen("tile_format"))) {
- if(enableMacroTile)
- mMacroTileEnabled = true;
- } else if(!strncmp(tokens[i], "src_split",
- strlen("src_split"))) {
- mSourceSplit = true;
- } else if(!strncmp(tokens[i], "non_scalar_rgb",
- strlen("non_scalar_rgb"))) {
- mRGBHasNoScalar = true;
- } else if(!strncmp(tokens[i], "rotator_downscale",
- strlen("rotator_downscale"))) {
- mRotDownscale = true;
- }
- }
- }
- }
- }
- free(line);
- fclose(sysfsFd);
- }
-
- if(mMDPVersion >= qdutils::MDP_V4_2 and mMDPVersion < qdutils::MDSS_V5) {
- mRotDownscale = true;
- }
-
- if(mSourceSplit) {
- memset(sysfsPath, 0, sizeof(sysfsPath));
- snprintf(sysfsPath , sizeof(sysfsPath),
- "/sys/class/graphics/fb0/msm_fb_src_split_info");
-
- sysfsFd = fopen(sysfsPath, "rb");
- if (sysfsFd == NULL) {
- ALOGE("%s: Opening file %s failed with error %s", __FUNCTION__,
- sysfsPath, strerror(errno));
- return false;
- } else {
- line = (char *) malloc(len);
- if((read = getline(&line, &len, sysfsFd)) != -1) {
- if(!strncmp(line, "src_split_always",
- strlen("src_split_always"))) {
- mSourceSplitAlways = true;
- }
- }
- free(line);
- fclose(sysfsFd);
- }
- }
-
- ALOGD_IF(DEBUG, "%s: mMDPVersion: %d mMdpRev: %x mRGBPipes:%d,"
- "mVGPipes:%d", __FUNCTION__, mMDPVersion, mMdpRev,
- mRGBPipes, mVGPipes);
- ALOGD_IF(DEBUG, "%s:mDMAPipes:%d \t mMDPDownscale:%d, mFeatures:%d",
- __FUNCTION__, mDMAPipes, mMDPDownscale, mFeatures);
- ALOGD_IF(DEBUG, "%s:mLowBw: %lu mHighBw: %lu", __FUNCTION__, mLowBw,
- mHighBw);
-
- return true;
-}
-
-// This function reads the sysfs node to read MDP capabilities
-// and parses and updates information accordingly.
-bool MDPVersion::updateSplitInfo() {
- if(mMDPVersion >= MDSS_V5) {
- char split[64] = {0};
- FILE* fp = fopen("/sys/class/graphics/fb0/msm_fb_split", "r");
- if(fp){
- //Format "left right" space as delimiter
- if(fread(split, sizeof(char), 64, fp)) {
- split[sizeof(split) - 1] = '\0';
- mSplit.mLeft = atoi(split);
- ALOGI_IF(mSplit.mLeft, "Left Split=%d", mSplit.mLeft);
- char *rght = strpbrk(split, " ");
- if(rght)
- mSplit.mRight = atoi(rght + 1);
- ALOGI_IF(mSplit.mRight, "Right Split=%d", mSplit.mRight);
- }
- } else {
- ALOGE("Failed to open mdss_fb_split node");
- return false;
- }
- if(fp)
- fclose(fp);
- }
- return true;
-}
-
-
-bool MDPVersion::hasMinCropWidthLimitation() const {
- return mMdpRev <= MDSS_MDP_HW_REV_102;
-}
-
-bool MDPVersion::supportsDecimation() {
- return mFeatures & MDP_DECIMATION_EN;
-}
-
-uint32_t MDPVersion::getMaxMDPDownscale() {
- return mMDPDownscale;
-}
-
-uint32_t MDPVersion::getMaxMDPUpscale() {
- return mMDPUpscale;
-}
-
-bool MDPVersion::supportsBWC() {
- // BWC - Bandwidth Compression
- return (mFeatures & MDP_BWC_EN);
-}
-
-bool MDPVersion::supportsMacroTile() {
- // MACRO TILE support
- return mMacroTileEnabled;
-}
-
-bool MDPVersion::isSrcSplit() const {
- return mSourceSplit;
-}
-
-bool MDPVersion::isSrcSplitAlways() const {
- return mSourceSplitAlways;
-}
-
-bool MDPVersion::isRGBScalarSupported() const {
- return (!mRGBHasNoScalar);
-}
-
-bool MDPVersion::is8x26() {
- return (mMdpRev >= MDSS_MDP_HW_REV_101 and
- mMdpRev < MDSS_MDP_HW_REV_102);
-}
-
-bool MDPVersion::is8x74v2() {
- return (mMdpRev >= MDSS_MDP_HW_REV_102 and
- mMdpRev < MDSS_MDP_HW_REV_103);
-}
-
-bool MDPVersion::is8084() {
- return (mMdpRev >= MDSS_MDP_HW_REV_103 and
- mMdpRev < MDSS_MDP_HW_REV_104);
-}
-
-bool MDPVersion::is8092() {
- return (mMdpRev >= MDSS_MDP_HW_REV_200 and
- mMdpRev < MDSS_MDP_HW_REV_206);
-}
-
-bool MDPVersion::is8994() {
- return (mMdpRev >= MDSS_MDP_HW_REV_105 and
- mMdpRev < MDSS_MDP_HW_REV_106);
-}
-
-bool MDPVersion::is8x16() {
- return (mMdpRev >= MDSS_MDP_HW_REV_106 and
- mMdpRev < MDSS_MDP_HW_REV_107);
-}
-
-bool MDPVersion::is8x39() {
- return (mMdpRev >= MDSS_MDP_HW_REV_108 and
- mMdpRev < MDSS_MDP_HW_REV_109);
-}
-
-
-}; //namespace qdutils
-
diff --git a/msm8909/libqdutils/mdp_version.h b/msm8909/libqdutils/mdp_version.h
deleted file mode 100644
index 3c7f6a3..0000000
--- a/msm8909/libqdutils/mdp_version.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef INCLUDE_LIBQCOMUTILS_MDPVER
-#define INCLUDE_LIBQCOMUTILS_MDPVER
-
-#include <stdint.h>
-#include <utils/Singleton.h>
-#include <cutils/properties.h>
-
-/* This class gets the MSM type from the soc info
-*/
-using namespace android;
-namespace qdutils {
-// These panel definitions are available at mdss_mdp.h which is internal header
-// file and is not available at <linux/mdss_mdp.h>.
-// ToDo: once it is available at linux/mdss_mdp.h, these below definitions can
-// be removed.
-enum mdp_version {
- MDP_V_UNKNOWN = 0,
- MDP_V2_2 = 220,
- MDP_V3_0 = 300,
- MDP_V3_0_3 = 303,
- MDP_V3_0_4 = 304,
- MDP_V3_0_5 = 305,
- MDP_V3_1 = 310,
- MDP_V4_0 = 400,
- MDP_V4_1 = 410,
- MDP_V4_2 = 420,
- MDP_V4_3 = 430,
- MDP_V4_4 = 440,
- MDSS_V5 = 500,
-};
-
-#define NO_PANEL '0'
-#define MDDI_PANEL '1'
-#define EBI2_PANEL '2'
-#define LCDC_PANEL '3'
-#define EXT_MDDI_PANEL '4'
-#define TV_PANEL '5'
-#define DTV_PANEL '7'
-#define MIPI_VIDEO_PANEL '8'
-#define MIPI_CMD_PANEL '9'
-#define WRITEBACK_PANEL 'a'
-#define LVDS_PANEL 'b'
-#define EDP_PANEL 'c'
-
-class MDPVersion;
-
-struct Split {
- int mLeft;
- int mRight;
- Split() : mLeft(0), mRight(0){}
- int left() { return mLeft; }
- int right() { return mRight; }
- friend class MDPVersion;
-};
-
-struct PanelInfo {
- char mType; // Smart or Dumb
- int mPartialUpdateEnable; // Partial update feature
- int mLeftAlign; // ROI left alignment restriction
- int mWidthAlign; // ROI width alignment restriction
- int mTopAlign; // ROI top alignment restriction
- int mHeightAlign; // ROI height alignment restriction
- int mMinROIWidth; // Min width needed for ROI
- int mMinROIHeight; // Min height needed for ROI
- bool mNeedsROIMerge; // Merge ROI's of both the DSI's
- bool mDynFpsSupported; // Panel Supports dyn fps
- uint32_t mMinFps; // Min fps supported by panel
- uint32_t mMaxFps; // Max fps supported by panel
- PanelInfo() : mType(NO_PANEL), mPartialUpdateEnable(0),
- mLeftAlign(0), mWidthAlign(0), mTopAlign(0), mHeightAlign(0),
- mMinROIWidth(0), mMinROIHeight(0), mNeedsROIMerge(false),
- mDynFpsSupported(0), mMinFps(0), mMaxFps(0) {}
- friend class MDPVersion;
-};
-
-class MDPVersion : public Singleton <MDPVersion>
-{
-public:
- MDPVersion();
- ~MDPVersion();
- int getMDPVersion() {return mMDPVersion;}
- char getPanelType() {return mPanelInfo.mType;}
- bool hasOverlay() {return mHasOverlay;}
- uint8_t getTotalPipes() {
- return (uint8_t)(mRGBPipes + mVGPipes + mDMAPipes);
- }
- uint8_t getRGBPipes() { return mRGBPipes; }
- uint8_t getVGPipes() { return mVGPipes; }
- uint8_t getDMAPipes() { return mDMAPipes; }
- bool supportsDecimation();
- uint32_t getMaxMDPDownscale();
- uint32_t getMaxMDPUpscale();
- bool supportsBWC();
- bool supportsMacroTile();
- int getLeftSplit() { return mSplit.left(); }
- int getRightSplit() { return mSplit.right(); }
- bool isPartialUpdateEnabled() { return mPanelInfo.mPartialUpdateEnable; }
- int getLeftAlign() { return mPanelInfo.mLeftAlign; }
- int getWidthAlign() { return mPanelInfo.mWidthAlign; }
- int getTopAlign() { return mPanelInfo.mTopAlign; }
- int getHeightAlign() { return mPanelInfo.mHeightAlign; }
- int getMinROIWidth() { return mPanelInfo.mMinROIWidth; }
- int getMinROIHeight() { return mPanelInfo.mMinROIHeight; }
- bool needsROIMerge() { return mPanelInfo.mNeedsROIMerge; }
- unsigned long getLowBw() { return mLowBw; }
- unsigned long getHighBw() { return mHighBw; }
- bool isRotDownscaleEnabled() { return mRotDownscale; }
- bool isDynFpsSupported() { return mPanelInfo.mDynFpsSupported; }
- uint32_t getMinFpsSupported() { return mPanelInfo.mMinFps; }
- uint32_t getMaxFpsSupported() { return mPanelInfo.mMaxFps; }
- uint32_t getMaxMixerWidth() const { return mMaxMixerWidth; }
- bool hasMinCropWidthLimitation() const;
- bool isSrcSplit() const;
- bool isSrcSplitAlways() const;
- bool isRGBScalarSupported() const;
- bool is8x26();
- bool is8x74v2();
- bool is8084();
- bool is8092();
- bool is8994();
- bool is8x16();
- bool is8x39();
-
-private:
- bool updateSysFsInfo();
- void updatePanelInfo();
- bool updateSplitInfo();
- int tokenizeParams(char *inputParams, const char *delim,
- char* tokenStr[], int *idx);
- int mFd;
- int mMDPVersion;
- bool mHasOverlay;
- uint32_t mMdpRev;
- uint8_t mRGBPipes;
- uint8_t mVGPipes;
- uint8_t mDMAPipes;
- uint32_t mFeatures;
- uint32_t mMDPDownscale;
- uint32_t mMDPUpscale;
- bool mMacroTileEnabled;
- Split mSplit;
- PanelInfo mPanelInfo;
- unsigned long mLowBw; //kbps
- unsigned long mHighBw; //kbps
- bool mSourceSplit;
- //Additional property on top of source split
- bool mSourceSplitAlways;
- bool mRGBHasNoScalar;
- bool mRotDownscale;
- uint32_t mMaxMixerWidth; //maximum x-res of a given mdss mixer.
-};
-}; //namespace qdutils
-#endif //INCLUDE_LIBQCOMUTILS_MDPVER
diff --git a/msm8909/libqdutils/profiler.cpp b/msm8909/libqdutils/profiler.cpp
index b183e6d..810b019 100644
--- a/msm8909/libqdutils/profiler.cpp
+++ b/msm8909/libqdutils/profiler.cpp
@@ -28,6 +28,7 @@
*/
#define LOG_NDDEBUG 0
+#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#include "profiler.h"
diff --git a/msm8909/libqdutils/profiler.h b/msm8909/libqdutils/profiler.h
index 5f270b0..9ac8157 100644
--- a/msm8909/libqdutils/profiler.h
+++ b/msm8909/libqdutils/profiler.h
@@ -33,7 +33,7 @@
#include <stdio.h>
#include <utils/Singleton.h>
#include <cutils/properties.h>
-#include <cutils/log.h>
+#include <log/log.h>
#ifndef DEBUG_CALC_FPS
#define CALC_FPS() ((void)0)
diff --git a/msm8909/libqdutils/qdMetaData.cpp b/msm8909/libqdutils/qdMetaData.cpp
index 9f8a324..9f73e44 100644
--- a/msm8909/libqdutils/qdMetaData.cpp
+++ b/msm8909/libqdutils/qdMetaData.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,61 +30,71 @@
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
-#include <cutils/log.h>
+#include <log/log.h>
+#include <cinttypes>
#include <gralloc_priv.h>
-#include <inttypes.h>
#include "qdMetaData.h"
-int setMetaData(private_handle_t *handle, DispParamType paramType,
- void *param) {
- if (!handle) {
- ALOGE("%s: Private handle is null!", __func__);
+unsigned long getMetaDataSize() {
+ return static_cast<unsigned long>(ROUND_UP_PAGESIZE(sizeof(MetaData_t)));
+}
+
+static int validateAndMap(private_handle_t* handle) {
+ if (private_handle_t::validate(handle)) {
+ ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
return -1;
}
if (handle->fd_metadata == -1) {
- ALOGE("%s: Bad fd for extra data!", __func__);
+ ALOGE("%s: Invalid metadata fd - handle:%p fd: %d",
+ __func__, handle, handle->fd_metadata);
return -1;
}
+
+ if (!handle->base_metadata) {
+ auto size = getMetaDataSize();
+ void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
+ handle->fd_metadata, 0);
+ if (base == reinterpret_cast<void*>(MAP_FAILED)) {
+ ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s",
+ __func__, handle, handle->fd_metadata, strerror(errno));
+
+ return -1;
+ }
+ handle->base_metadata = (uintptr_t) base;
+ }
+ return 0;
+}
+
+int setMetaData(private_handle_t *handle, DispParamType paramType,
+ void *param) {
+ auto err = validateAndMap(handle);
+ if (err != 0)
+ return err;
+ return setMetaDataVa(reinterpret_cast<MetaData_t*>(handle->base_metadata),
+ paramType, param);
+}
+
+int setMetaDataVa(MetaData_t *data, DispParamType paramType,
+ void *param) {
+ if (data == nullptr)
+ return -EINVAL;
+ // If parameter is NULL reset the specific MetaData Key
if (!param) {
- ALOGE("%s: input param is null!", __func__);
- return -1;
+ data->operation &= ~paramType;
+ // param unset
+ return 0;
}
- unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
- void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
- handle->fd_metadata, 0);
- if (base == reinterpret_cast<void*>(MAP_FAILED)) {
- ALOGE("%s: mmap() failed: error is %s!", __func__, strerror(errno));
- return -1;
- }
- MetaData_t *data = reinterpret_cast <MetaData_t *>(base);
+
data->operation |= paramType;
switch (paramType) {
- case PP_PARAM_HSIC:
- memcpy((void *)&data->hsicData, param, sizeof(HSICData_t));
- break;
- case PP_PARAM_SHARPNESS:
- data->sharpness = *((int32_t *)param);
- break;
- case PP_PARAM_VID_INTFC:
- data->video_interface = *((int32_t *)param);
- break;
case PP_PARAM_INTERLACED:
data->interlaced = *((int32_t *)param);
break;
- case PP_PARAM_IGC:
- memcpy((void *)&data->igcData, param, sizeof(IGCData_t));
- break;
- case PP_PARAM_SHARP2:
- memcpy((void *)&data->Sharp2Data, param, sizeof(Sharp2Data_t));
- break;
- case PP_PARAM_TIMESTAMP:
- data->timestamp = *((int64_t *)param);
- break;
case UPDATE_BUFFER_GEOMETRY:
- memcpy((void *)&data->bufferDim, param, sizeof(BufferDim_t));
+ data->bufferDim = *((BufferDim_t *)param);
break;
case UPDATE_REFRESH_RATE:
- data->refreshrate = *((uint32_t *)param);
+ data->refreshrate = *((float *)param);
break;
case UPDATE_COLOR_SPACE:
data->colorSpace = *((ColorSpace_t *)param);
@@ -92,12 +102,206 @@
case MAP_SECURE_BUFFER:
data->mapSecureBuffer = *((int32_t *)param);
break;
+ case S3D_FORMAT:
+ data->s3dFormat = *((uint32_t *)param);
+ break;
+ case LINEAR_FORMAT:
+ data->linearFormat = *((uint32_t *)param);
+ break;
+ case SET_IGC:
+ data->igc = *((IGC_t *)param);
+ break;
+ case SET_SINGLE_BUFFER_MODE:
+ data->isSingleBufferMode = *((uint32_t *)param);
+ break;
+ case SET_S3D_COMP:
+ data->s3dComp = *((S3DGpuComp_t *)param);
+ break;
+ case SET_VT_TIMESTAMP:
+ data->vtTimeStamp = *((uint64_t *)param);
+ break;
+ case COLOR_METADATA:
+ data->color = *((ColorMetaData *)param);
+ break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
}
- if(munmap(base, size))
- ALOGE("%s: failed to unmap ptr %p, err %d", __func__, (void*)base,
- errno);
return 0;
}
+
+int clearMetaData(private_handle_t *handle, DispParamType paramType) {
+ auto err = validateAndMap(handle);
+ if (err != 0)
+ return err;
+ return clearMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+ paramType);
+}
+
+int clearMetaDataVa(MetaData_t *data, DispParamType paramType) {
+ if (data == nullptr)
+ return -EINVAL;
+ data->operation &= ~paramType;
+ switch (paramType) {
+ case SET_S3D_COMP:
+ data->s3dComp.displayId = -1;
+ data->s3dComp.s3dMode = 0;
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ return 0;
+}
+
+int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
+ void *param) {
+ int ret = validateAndMap(handle);
+ if (ret != 0)
+ return ret;
+ return getMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+ paramType, param);
+}
+
+int getMetaDataVa(MetaData_t *data, DispFetchParamType paramType,
+ void *param) {
+ // Make sure we send 0 only if the operation queried is present
+ int ret = -EINVAL;
+ if (data == nullptr)
+ return ret;
+
+ switch (paramType) {
+ case GET_PP_PARAM_INTERLACED:
+ if (data->operation & PP_PARAM_INTERLACED) {
+ *((int32_t *)param) = data->interlaced;
+ ret = 0;
+ }
+ break;
+ case GET_BUFFER_GEOMETRY:
+ if (data->operation & UPDATE_BUFFER_GEOMETRY) {
+ *((BufferDim_t *)param) = data->bufferDim;
+ ret = 0;
+ }
+ break;
+ case GET_REFRESH_RATE:
+ if (data->operation & UPDATE_REFRESH_RATE) {
+ *((float *)param) = data->refreshrate;
+ ret = 0;
+ }
+ break;
+ case GET_COLOR_SPACE:
+ if (data->operation & UPDATE_COLOR_SPACE) {
+ *((ColorSpace_t *)param) = data->colorSpace;
+ ret = 0;
+ }
+ break;
+ case GET_MAP_SECURE_BUFFER:
+ if (data->operation & MAP_SECURE_BUFFER) {
+ *((int32_t *)param) = data->mapSecureBuffer;
+ ret = 0;
+ }
+ break;
+ case GET_S3D_FORMAT:
+ if (data->operation & S3D_FORMAT) {
+ *((uint32_t *)param) = data->s3dFormat;
+ ret = 0;
+ }
+ break;
+ case GET_LINEAR_FORMAT:
+ if (data->operation & LINEAR_FORMAT) {
+ *((uint32_t *)param) = data->linearFormat;
+ ret = 0;
+ }
+ break;
+ case GET_IGC:
+ if (data->operation & SET_IGC) {
+ *((IGC_t *)param) = data->igc;
+ ret = 0;
+ }
+ break;
+ case GET_SINGLE_BUFFER_MODE:
+ if (data->operation & SET_SINGLE_BUFFER_MODE) {
+ *((uint32_t *)param) = data->isSingleBufferMode;
+ ret = 0;
+ }
+ break;
+ case GET_S3D_COMP:
+ if (data->operation & SET_S3D_COMP) {
+ *((S3DGpuComp_t *)param) = data->s3dComp;
+ ret = 0;
+ }
+ break;
+ case GET_VT_TIMESTAMP:
+ if (data->operation & SET_VT_TIMESTAMP) {
+ *((uint64_t *)param) = data->vtTimeStamp;
+ ret = 0;
+ }
+ break;
+ case GET_COLOR_METADATA:
+ if (data->operation & COLOR_METADATA) {
+ *((ColorMetaData *)param) = data->color;
+ ret = 0;
+ }
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ return ret;
+}
+
+int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst) {
+ auto err = validateAndMap(src);
+ if (err != 0)
+ return err;
+
+ err = validateAndMap(dst);
+ if (err != 0)
+ return err;
+
+ MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
+ MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
+ *dst_data = *src_data;
+ return 0;
+}
+
+int copyMetaDataVaToHandle(MetaData_t *src_data, struct private_handle_t *dst) {
+ int err = -EINVAL;
+ if (src_data == nullptr)
+ return err;
+
+ err = validateAndMap(dst);
+ if (err != 0)
+ return err;
+
+ MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
+ *dst_data = *src_data;
+ return 0;
+}
+
+int copyMetaDataHandleToVa(struct private_handle_t *src, MetaData_t *dst_data) {
+ int err = -EINVAL;
+ if (dst_data == nullptr)
+ return err;
+
+ err = validateAndMap(src);
+ if (err != 0)
+ return err;
+
+ MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
+ *dst_data = *src_data;
+ return 0;
+}
+
+int copyMetaDataVaToVa(MetaData_t *src_data, MetaData_t *dst_data) {
+ int err = -EINVAL;
+ if (src_data == nullptr)
+ return err;
+
+ if (dst_data == nullptr)
+ return err;
+
+ *dst_data = *src_data;
+ return 0;
+}
+
diff --git a/msm8909/libqdutils/qdMetaData.h b/msm8909/libqdutils/qdMetaData.h
index 32d788e..afe86d3 100644
--- a/msm8909/libqdutils/qdMetaData.h
+++ b/msm8909/libqdutils/qdMetaData.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,16 +30,25 @@
#ifndef _QDMETADATA_H
#define _QDMETADATA_H
+#include <color_metadata.h>
+
#ifdef __cplusplus
extern "C" {
#endif
-#define MAX_IGC_LUT_ENTRIES 256
+#define MAX_UBWC_STATS_LENGTH 32
enum ColorSpace_t{
ITU_R_601,
ITU_R_601_FR,
ITU_R_709,
+ ITU_R_2020,
+ ITU_R_2020_FR,
+};
+
+enum IGC_t {
+ IGC_NotSpecified,
+ IGC_sRGB,
};
struct HSICData_t {
@@ -49,36 +58,52 @@
float contrast;
};
-struct Sharp2Data_t {
- int32_t strength;
- uint32_t edge_thr;
- uint32_t smooth_thr;
- uint32_t noise_thr;
-};
-
-struct IGCData_t{
- uint16_t c0[MAX_IGC_LUT_ENTRIES];
- uint16_t c1[MAX_IGC_LUT_ENTRIES];
- uint16_t c2[MAX_IGC_LUT_ENTRIES];
-};
-
struct BufferDim_t {
int32_t sliceWidth;
int32_t sliceHeight;
};
+enum UBWC_Version {
+ UBWC_UNUSED = 0,
+ UBWC_1_0 = 0x1,
+ UBWC_2_0 = 0x2,
+ UBWC_MAX_VERSION = 0xFF,
+};
+
+struct UBWC_2_0_Stats {
+ uint32_t nCRStatsTile32; /**< UBWC Stats info for 32 Byte Tile */
+ uint32_t nCRStatsTile64; /**< UBWC Stats info for 64 Byte Tile */
+ uint32_t nCRStatsTile96; /**< UBWC Stats info for 96 Byte Tile */
+ uint32_t nCRStatsTile128; /**< UBWC Stats info for 128 Byte Tile */
+ uint32_t nCRStatsTile160; /**< UBWC Stats info for 160 Byte Tile */
+ uint32_t nCRStatsTile192; /**< UBWC Stats info for 192 Byte Tile */
+ uint32_t nCRStatsTile256; /**< UBWC Stats info for 256 Byte Tile */
+};
+
+struct UBWCStats {
+ enum UBWC_Version version; /* Union depends on this version. */
+ uint8_t bDataValid; /* If [non-zero], CR Stats data is valid.
+ * Consumers may use stats data.
+ * If [zero], CR Stats data is invalid.
+ * Consumers *Shall* not use stats data */
+ union {
+ struct UBWC_2_0_Stats ubwc_stats;
+ uint32_t reserved[MAX_UBWC_STATS_LENGTH]; /* This is for future */
+ };
+};
+
+struct S3DGpuComp_t {
+ int32_t displayId; /* on which display S3D is composed by client */
+ uint32_t s3dMode; /* the S3D format of this layer to be accessed by client */
+};
+
struct MetaData_t {
int32_t operation;
int32_t interlaced;
struct BufferDim_t bufferDim;
- struct HSICData_t hsicData;
- int32_t sharpness;
- int32_t video_interface;
- struct IGCData_t igcData;
- struct Sharp2Data_t Sharp2Data;
- int64_t timestamp;
- uint32_t refreshrate;
+ float refreshrate;
enum ColorSpace_t colorSpace;
+ enum IGC_t igc;
/* Gralloc sets PRIV_SECURE_BUFFER flag to inform that the buffers are from
* ION_SECURE. which should not be mapped. However, for GPU post proc
* feature, GFX needs to map this buffer, in the client context and in SF
@@ -86,25 +111,87 @@
* for clients to set, and GPU will to read and know when to map the
* SECURE_BUFFER(ION) */
int32_t mapSecureBuffer;
+ /* The supported formats are defined in gralloc_priv.h to
+ * support legacy code*/
+ uint32_t s3dFormat;
+ /* VENUS output buffer is linear for UBWC Interlaced video */
+ uint32_t linearFormat;
+ /* Set by graphics to indicate that this buffer will be written to but not
+ * swapped out */
+ uint32_t isSingleBufferMode;
+ /* Indicate GPU to draw S3D layer on dedicate display device */
+ struct S3DGpuComp_t s3dComp;
+
+ /* Set by camera to program the VT Timestamp */
+ uint64_t vtTimeStamp;
+ /* Color Aspects + HDR info */
+ ColorMetaData color;
+ /* Consumer should read this data as follows based on
+ * Gralloc flag "interlaced" listed above.
+ * [0] : If it is progressive.
+ * [0] : Top field, if it is interlaced.
+ * [1] : Do not read, if it is progressive.
+ * [1] : Bottom field, if it is interlaced.
+ */
+ struct UBWCStats ubwcCRStats[2];
};
enum DispParamType {
- PP_PARAM_HSIC = 0x0001,
- PP_PARAM_SHARPNESS = 0x0002,
- PP_PARAM_INTERLACED = 0x0004,
- PP_PARAM_VID_INTFC = 0x0008,
- PP_PARAM_IGC = 0x0010,
- PP_PARAM_SHARP2 = 0x0020,
- PP_PARAM_TIMESTAMP = 0x0040,
- UPDATE_BUFFER_GEOMETRY = 0x0080,
- UPDATE_REFRESH_RATE = 0x0100,
- UPDATE_COLOR_SPACE = 0x0200,
- MAP_SECURE_BUFFER = 0x400,
+ SET_VT_TIMESTAMP = 0x0001,
+ COLOR_METADATA = 0x0002,
+ PP_PARAM_INTERLACED = 0x0004,
+ UNUSED2 = 0x0008,
+ UNUSED3 = 0x0010,
+ UNUSED4 = 0x0020,
+ SET_UBWC_CR_STATS_INFO = 0x0040,
+ UPDATE_BUFFER_GEOMETRY = 0x0080,
+ UPDATE_REFRESH_RATE = 0x0100,
+ UPDATE_COLOR_SPACE = 0x0200,
+ MAP_SECURE_BUFFER = 0x0400,
+ S3D_FORMAT = 0x0800,
+ LINEAR_FORMAT = 0x1000,
+ SET_IGC = 0x2000,
+ SET_SINGLE_BUFFER_MODE = 0x4000,
+ SET_S3D_COMP = 0x8000,
+};
+
+enum DispFetchParamType {
+ GET_VT_TIMESTAMP = 0x0001,
+ GET_COLOR_METADATA = 0x0002,
+ GET_PP_PARAM_INTERLACED = 0x0004,
+ GET_UBWC_CR_STATS_INFO = 0x0040,
+ GET_BUFFER_GEOMETRY = 0x0080,
+ GET_REFRESH_RATE = 0x0100,
+ GET_COLOR_SPACE = 0x0200,
+ GET_MAP_SECURE_BUFFER = 0x0400,
+ GET_S3D_FORMAT = 0x0800,
+ GET_LINEAR_FORMAT = 0x1000,
+ GET_IGC = 0x2000,
+ GET_SINGLE_BUFFER_MODE = 0x4000,
+ GET_S3D_COMP = 0x8000,
};
struct private_handle_t;
int setMetaData(struct private_handle_t *handle, enum DispParamType paramType,
- void *param);
+ void *param);
+int setMetaDataVa(struct MetaData_t* data, enum DispParamType paramType,
+ void *param);
+
+int getMetaData(struct private_handle_t *handle,
+ enum DispFetchParamType paramType,
+ void *param);
+int getMetaDataVa(struct MetaData_t* data, enum DispFetchParamType paramType,
+ void *param);
+
+int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst);
+int copyMetaDataVaToHandle(struct MetaData_t *src, struct private_handle_t *dst);
+int copyMetaDataHandleToVa(struct private_handle_t* src, struct MetaData_t *dst);
+int copyMetaDataVaToVa(struct MetaData_t *src, struct MetaData_t *dst);
+
+int clearMetaData(struct private_handle_t *handle, enum DispParamType paramType);
+int clearMetaDataVa(struct MetaData_t *data, enum DispParamType paramType);
+
+unsigned long getMetaDataSize();
#ifdef __cplusplus
}
diff --git a/msm8909/libqdutils/qd_utils.cpp b/msm8909/libqdutils/qd_utils.cpp
index 0584216..fc01eab 100644
--- a/msm8909/libqdutils/qd_utils.cpp
+++ b/msm8909/libqdutils/qd_utils.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2018 The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -27,57 +27,152 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <unistd.h>
+#include <gralloc_priv.h>
#include "qd_utils.h"
-#define QD_UTILS_DEBUG 0
namespace qdutils {
-#ifdef HDMI_STUB
-int getHDMINode(void)
-{
- ALOGD_IF(QD_UTILS_DEBUG, "%s: HDMI_STUB\n", __func__);
- return -1;
-}
-int getEdidRawData(char *buffer)
-{
- ALOGD_IF(QD_UTILS_DEBUG, "%s: HDMI_STUB\n", __func__);
- (void) buffer;
+static int parseLine(char *input, char *tokens[], const uint32_t maxToken, uint32_t *count) {
+ char *tmpToken = NULL;
+ char *tmpPtr;
+ uint32_t index = 0;
+ const char *delim = ", =\n";
+ if (!input) {
+ return -1;
+ }
+ tmpToken = strtok_r(input, delim, &tmpPtr);
+ while (tmpToken && index < maxToken) {
+ tokens[index++] = tmpToken;
+ tmpToken = strtok_r(NULL, delim, &tmpPtr);
+ }
+ *count = index;
+
return 0;
}
-#else
-int getHDMINode(void)
-{
+
+static int getExternalNode(const char *type) {
FILE *displayDeviceFP = NULL;
char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
int j = 0;
- for(j = 0; j < HWC_NUM_DISPLAY_TYPES; j++) {
+ for(j = 0; j < kFBNodeMax; j++) {
snprintf (msmFbTypePath, sizeof(msmFbTypePath),
- "/sys/class/graphics/fb%d/msm_fb_type", j);
+ "/sys/devices/virtual/graphics/fb%d/msm_fb_type", j);
displayDeviceFP = fopen(msmFbTypePath, "r");
if(displayDeviceFP) {
fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
displayDeviceFP);
- if(strncmp(fbType, "dtv panel", strlen("dtv panel")) == 0) {
- ALOGD("%s: HDMI is at fb%d", __func__, j);
+ if(strncmp(fbType, type, strlen(type)) == 0) {
+ ALOGD("%s: %s is at fb%d", __func__, type, j);
fclose(displayDeviceFP);
break;
}
fclose(displayDeviceFP);
} else {
- ALOGE("%s: Failed to open fb node %d", __func__, j);
+ ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath);
}
}
- if (j < HWC_NUM_DISPLAY_TYPES)
+ if (j < kFBNodeMax)
return j;
else
- ALOGE("%s: Failed to find HDMI node", __func__);
+ ALOGE("%s: Failed to find %s node", __func__, type);
return -1;
}
+static int querySDEInfoDRM(HWQueryType type, int *value) {
+ char property[PROPERTY_VALUE_MAX] = {0};
+
+ // TODO(user): If future targets don't support WB UBWC, add separate
+ // properties in target specific system.prop and have clients like WFD
+ // directly rely on those.
+ switch(type) {
+ case HAS_UBWC:
+ case HAS_WB_UBWC: // WFD stack still uses this
+ *value = 1;
+ property_get(DISABLE_UBWC_PROP, property, "0");
+ if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
+ !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
+ *value = 0;
+ }
+ break;
+ default:
+ ALOGE("Invalid query type %d", type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int querySDEInfoFB(HWQueryType type, int *value) {
+ FILE *fileptr = NULL;
+ const char *featureName;
+ char stringBuffer[MAX_STRING_LENGTH];
+ uint32_t tokenCount = 0;
+ const uint32_t maxCount = 10;
+ char *tokens[maxCount] = { NULL };
+
+ switch(type) {
+ case HAS_UBWC:
+ featureName = "ubwc";
+ break;
+ case HAS_WB_UBWC:
+ featureName = "wb_ubwc";
+ break;
+ default:
+ ALOGE("Invalid query type %d", type);
+ return -EINVAL;
+ }
+
+ fileptr = fopen("/sys/devices/virtual/graphics/fb0/mdp/caps", "rb");
+ if (!fileptr) {
+ ALOGE("File '%s' not found", stringBuffer);
+ return -EINVAL;
+ }
+
+ size_t len = MAX_STRING_LENGTH;
+ ssize_t read;
+ char *line = stringBuffer;
+ while ((read = getline(&line, &len, fileptr)) != -1) {
+ // parse the line and update information accordingly
+ if (parseLine(line, tokens, maxCount, &tokenCount)) {
+ continue;
+ }
+
+ if (strncmp(tokens[0], "features", strlen("features"))) {
+ continue;
+ }
+
+ for (uint32_t i = 0; i < tokenCount; i++) {
+ if (!strncmp(tokens[i], featureName, strlen(featureName))) {
+ *value = 1;
+ }
+ }
+ }
+ fclose(fileptr);
+
+ return 0;
+}
+
+int querySDEInfo(HWQueryType type, int *value) {
+ if (!value) {
+ return -EINVAL;
+ }
+
+ if (getDriverType() == DriverType::DRM) {
+ return querySDEInfoDRM(type, value);
+ }
+
+ return querySDEInfoFB(type, value);
+}
+
+int getHDMINode(void) {
+ return getExternalNode("dtv panel");
+}
+
int getEdidRawData(char *buffer)
{
int size;
@@ -91,12 +186,12 @@
}
snprintf(msmFbTypePath, sizeof(msmFbTypePath),
- "/sys/class/graphics/fb%d/edid_raw_data", node_id);
+ "/sys/devices/virtual/graphics/fb%d/edid_raw_data", node_id);
- edidFile = open(msmFbTypePath, O_RDONLY, 0);
+ edidFile = open(msmFbTypePath, O_RDONLY, 0);
if (edidFile < 0) {
- ALOGE("%s no edid raw data found", __func__);
+ ALOGE("%s no edid raw data found %s", __func__,msmFbTypePath);
return 0;
}
@@ -104,34 +199,162 @@
close(edidFile);
return size;
}
-#endif
-/* Calculates the aspect ratio for based on src & dest */
-void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
- int srcHeight, hwc_rect_t& rect) {
- int x =0, y =0;
+bool isDPConnected() {
+ char connectPath[MAX_FRAME_BUFFER_NAME_SIZE];
+ FILE *connectFile = NULL;
+ size_t len = MAX_STRING_LENGTH;
+ char stringBuffer[MAX_STRING_LENGTH];
+ char *line = stringBuffer;
- if (srcWidth * destHeight > destWidth * srcHeight) {
- srcHeight = destWidth * srcHeight / srcWidth;
- srcWidth = destWidth;
- } else if (srcWidth * destHeight < destWidth * srcHeight) {
- srcWidth = destHeight * srcWidth / srcHeight;
- srcHeight = destHeight;
- } else {
- srcWidth = destWidth;
- srcHeight = destHeight;
+ int nodeId = getExternalNode("dp panel");
+ if (nodeId < 0) {
+ ALOGE("%s no DP node found", __func__);
+ return false;
}
- if (srcWidth > destWidth) srcWidth = destWidth;
- if (srcHeight > destHeight) srcHeight = destHeight;
- x = (destWidth - srcWidth) / 2;
- y = (destHeight - srcHeight) / 2;
- ALOGD_IF(QD_UTILS_DEBUG, "%s: AS Position: x = %d, y = %d w = %d h = %d",
- __FUNCTION__, x, y, srcWidth , srcHeight);
- // Convert it back to hwc_rect_t
- rect.left = x;
- rect.top = y;
- rect.right = srcWidth + rect.left;
- rect.bottom = srcHeight + rect.top;
+
+ snprintf(connectPath, sizeof(connectPath),
+ "/sys/devices/virtual/graphics/fb%d/connected", nodeId);
+
+ connectFile = fopen(connectPath, "rb");
+ if (!connectFile) {
+ ALOGW("Failed to open connect node for device node %s", connectPath);
+ return false;
+ }
+
+ if (getline(&line, &len, connectFile) < 0) {
+ fclose(connectFile);
+ return false;
+ }
+
+ fclose(connectFile);
+
+ return atoi(line);
+}
+
+int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType) {
+ if (!panelBpp || !patternType) {
+ return -1;
+ }
+
+ char configPath[MAX_FRAME_BUFFER_NAME_SIZE];
+ FILE *configFile = NULL;
+ uint32_t tokenCount = 0;
+ const uint32_t maxCount = 10;
+ char *tokens[maxCount] = { NULL };
+ size_t len = MAX_STRING_LENGTH;
+ char stringBuffer[MAX_STRING_LENGTH];
+ char *line = stringBuffer;
+
+ int nodeId = getExternalNode("dp panel");
+ if (nodeId < 0) {
+ ALOGE("%s no DP node found", __func__);
+ return -EINVAL;
+ }
+
+ snprintf(configPath, sizeof(configPath),
+ "/sys/devices/virtual/graphics/fb%d/config", nodeId);
+
+ configFile = fopen(configPath, "rb");
+ if (!configFile) {
+ ALOGW("Failed to open config node for device node %s", configPath);
+ return -EINVAL;
+ }
+
+ while (getline(&line, &len, configFile) != -1) {
+ if (!parseLine(line, tokens, maxCount, &tokenCount)) {
+ if (!strncmp(tokens[0], "bpp", strlen("bpp"))) {
+ *panelBpp = static_cast<uint32_t>(atoi(tokens[1]));
+ } else if (!strncmp(tokens[0], "pattern", strlen("pattern"))) {
+ *patternType = static_cast<uint32_t>(atoi(tokens[1]));
+ }
+ }
+ }
+
+ fclose(configFile);
+
+ return 0;
+}
+
+DriverType getDriverType() {
+ const char *fb_caps = "/sys/devices/virtual/graphics/fb0/mdp/caps";
+ // 0 - File exists
+ return access(fb_caps, F_OK) ? DriverType::DRM : DriverType::FB;
+}
+
+const char *GetHALPixelFormatString(int format) {
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return "RGBA_8888";
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ return "RGBX_8888";
+ case HAL_PIXEL_FORMAT_RGB_888:
+ return "RGB_888";
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return "RGB_565";
+ case HAL_PIXEL_FORMAT_BGR_565:
+ return "BGR_565";
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ return "BGRA_8888";
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ return "RGBA_5551";
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ return "RGBA_4444";
+ case HAL_PIXEL_FORMAT_YV12:
+ return "YV12";
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ return "YCbCr_422_SP_NV16";
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ return "YCrCb_420_SP_NV21";
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ return "YCbCr_422_I_YUY2";
+ case HAL_PIXEL_FORMAT_YCrCb_422_I:
+ return "YCrCb_422_I_YVYU";
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ return "NV12_ENCODEABLE";
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ return "YCbCr_420_SP_TILED_TILE_4x2";
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ return "YCbCr_420_SP";
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ return "YCrCb_420_SP_ADRENO";
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ return "YCrCb_422_SP";
+ case HAL_PIXEL_FORMAT_R_8:
+ return "R_8";
+ case HAL_PIXEL_FORMAT_RG_88:
+ return "RG_88";
+ case HAL_PIXEL_FORMAT_INTERLACE:
+ return "INTERLACE";
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ return "YCbCr_420_SP_VENUS";
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ return "YCrCb_420_SP_VENUS";
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ return "YCbCr_420_SP_VENUS_UBWC";
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ return "RGBA_1010102";
+ case HAL_PIXEL_FORMAT_ARGB_2101010:
+ return "ARGB_2101010";
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ return "RGBX_1010102";
+ case HAL_PIXEL_FORMAT_XRGB_2101010:
+ return "XRGB_2101010";
+ case HAL_PIXEL_FORMAT_BGRA_1010102:
+ return "BGRA_1010102";
+ case HAL_PIXEL_FORMAT_ABGR_2101010:
+ return "ABGR_2101010";
+ case HAL_PIXEL_FORMAT_BGRX_1010102:
+ return "BGRX_1010102";
+ case HAL_PIXEL_FORMAT_XBGR_2101010:
+ return "XBGR_2101010";
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ return "YCbCr_420_P010";
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ return "YCbCr_420_TP10_UBWC";
+ default:
+ return "Unknown_format";
+ }
}
}; //namespace qdutils
diff --git a/msm8909/libqdutils/qd_utils.h b/msm8909/libqdutils/qd_utils.h
index 1d4bc19..eed8661 100644
--- a/msm8909/libqdutils/qd_utils.h
+++ b/msm8909/libqdutils/qd_utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013, 2017 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -35,7 +35,7 @@
#include <ctype.h>
#include <fcntl.h>
#include <utils/Errors.h>
-#include <utils/Log.h>
+#include <log/log.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
@@ -45,18 +45,31 @@
#include <hardware/hwcomposer.h>
namespace qdutils {
-#define EDID_RAW_DATA_SIZE 640
-enum qd_utils {
- MAX_FRAME_BUFFER_NAME_SIZE = 128,
- MAX_SYSFS_FILE_PATH = 255,
- SUPPORTED_DOWNSCALE_AREA = (1920*1080)
+enum HWQueryType {
+ HAS_UBWC = 1,
+ HAS_WB_UBWC = 2
};
-int getHDMINode(void);
-int getEdidRawData(char *buffer);
+enum {
+ EDID_RAW_DATA_SIZE = 640,
+ MAX_FRAME_BUFFER_NAME_SIZE = 128,
+ MAX_SYSFS_FILE_PATH = 255,
+ MAX_STRING_LENGTH = 1024,
+};
-void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
- int srcHeight, hwc_rect_t& rect);
+int querySDEInfo(HWQueryType type, int *value);
+int getEdidRawData(char *buffer);
+int getHDMINode(void);
+bool isDPConnected();
+int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType);
+
+enum class DriverType {
+ FB = 0,
+ DRM,
+};
+DriverType getDriverType();
+const char *GetHALPixelFormatString(int format);
+static const int kFBNodeMax = 4;
}; //namespace qdutils
#endif
diff --git a/msm8909/libqservice/Android.bp b/msm8909/libqservice/Android.bp
new file mode 100644
index 0000000..fe69d39
--- /dev/null
+++ b/msm8909/libqservice/Android.bp
@@ -0,0 +1,16 @@
+cc_library_shared {
+ name: "libqservice",
+ vendor: true,
+ defaults: ["display_defaults"],
+ shared_libs: ["libbinder"],
+ cflags: [
+ "-DLOG_TAG=\"qdqservice\"",
+ "-Wno-sign-conversion",
+ ],
+ srcs: [
+ "QService.cpp",
+ "IQService.cpp",
+ "IQClient.cpp",
+ "IQHDMIClient.cpp",
+ ],
+}
diff --git a/msm8909/libqservice/Android.mk b/msm8909/libqservice/Android.mk
deleted file mode 100644
index e2a8255..0000000
--- a/msm8909/libqservice/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libqservice
-LOCAL_MODULE_TAGS := optional
-LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) libbinder
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdqservice\"
-LOCAL_CFLAGS += -Wno-error
-LOCAL_CLANG := $(common_clang_flags)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := QService.cpp \
- IQService.cpp \
- IQClient.cpp
-LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
-LOCAL_COPY_HEADERS := IQService.h \
- IQClient.h
-
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/msm8909/libqservice/IQHDMIClient.cpp b/msm8909/libqservice/IQHDMIClient.cpp
new file mode 100644
index 0000000..6379e57
--- /dev/null
+++ b/msm8909/libqservice/IQHDMIClient.cpp
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <log/log.h>
+#include <binder/Parcel.h>
+#include "IQHDMIClient.h"
+
+using namespace android;
+namespace qClient {
+
+enum {
+ HDMI_CONNECTED = IBinder::FIRST_CALL_TRANSACTION,
+ CEC_MESSAGE_RECEIVED
+};
+
+class BpQHDMIClient : public BpInterface<IQHDMIClient>
+{
+public:
+ BpQHDMIClient(const sp<IBinder>& impl)
+ :BpInterface<IQHDMIClient>(impl)
+ {
+ }
+
+ void onHdmiHotplug(int connected)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IQHDMIClient::getInterfaceDescriptor());
+ data.writeInt32(connected);
+ remote()->transact(HDMI_CONNECTED, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ void onCECMessageRecieved(char *msg, ssize_t len)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IQHDMIClient::getInterfaceDescriptor());
+ data.writeInt32((int32_t)len);
+ void *buf = data.writeInplace(len);
+ if (buf != NULL)
+ memcpy(buf, msg, len);
+ remote()->transact(CEC_MESSAGE_RECEIVED, data, &reply,
+ IBinder::FLAG_ONEWAY);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(QHDMIClient,
+ "android.display.IQHDMIClient");
+
+status_t BnQHDMIClient::onTransact(uint32_t code, const Parcel& data,
+ Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case HDMI_CONNECTED: {
+ CHECK_INTERFACE(IQHDMIClient, data, reply);
+ int connected = data.readInt32();
+ onHdmiHotplug(connected);
+ return NO_ERROR;
+ }
+ case CEC_MESSAGE_RECEIVED: {
+ CHECK_INTERFACE(IQHDMIClient, data, reply);
+ ssize_t len = data.readInt32();
+ const void* msg;
+ if(len >= 0 && len <= (ssize_t) data.dataAvail()) {
+ msg = data.readInplace(len);
+ } else {
+ msg = NULL;
+ len = 0;
+ }
+ if (msg != NULL)
+ onCECMessageRecieved((char*) msg, len);
+ return NO_ERROR;
+ }
+ default: {
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+ }
+}
+
+}; //namespace qClient
diff --git a/sdm845/libqservice/IQHDMIClient.h b/msm8909/libqservice/IQHDMIClient.h
similarity index 100%
rename from sdm845/libqservice/IQHDMIClient.h
rename to msm8909/libqservice/IQHDMIClient.h
diff --git a/msm8909/libqservice/IQService.cpp b/msm8909/libqservice/IQService.cpp
index 9e2b0f5..d45a141 100644
--- a/msm8909/libqservice/IQService.cpp
+++ b/msm8909/libqservice/IQService.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2016, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -25,8 +25,8 @@
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/IPCThreadState.h>
+#include <cutils/android_filesystem_config.h>
#include <utils/Errors.h>
-#include <private/android_filesystem_config.h>
#include <IQService.h>
#define QSERVICE_DEBUG 0
@@ -45,13 +45,22 @@
: BpInterface<IQService>(impl) {}
virtual void connect(const sp<IQClient>& client) {
- ALOGD_IF(QSERVICE_DEBUG, "%s: connect client", __FUNCTION__);
+ ALOGD_IF(QSERVICE_DEBUG, "%s: connect HWC client", __FUNCTION__);
Parcel data, reply;
data.writeInterfaceToken(IQService::getInterfaceDescriptor());
data.writeStrongBinder(IInterface::asBinder(client));
- remote()->transact(CONNECT, data, &reply);
+ remote()->transact(CONNECT_HWC_CLIENT, data, &reply);
}
+ virtual void connect(const sp<IQHDMIClient>& client) {
+ ALOGD_IF(QSERVICE_DEBUG, "%s: connect HDMI client", __FUNCTION__);
+ Parcel data, reply;
+ data.writeInterfaceToken(IQService::getInterfaceDescriptor());
+ data.writeStrongBinder(IInterface::asBinder(client));
+ remote()->transact(CONNECT_HDMI_CLIENT, data, &reply);
+ }
+
+
virtual android::status_t dispatch(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
ALOGD_IF(QSERVICE_DEBUG, "%s: dispatch in:%p", __FUNCTION__, inParcel);
@@ -70,8 +79,6 @@
// ----------------------------------------------------------------------
-static void getProcName(int pid, char *buf, int size);
-
status_t BnQService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
@@ -80,33 +87,41 @@
IPCThreadState* ipc = IPCThreadState::self();
const int callerPid = ipc->getCallingPid();
const int callerUid = ipc->getCallingUid();
- const int MAX_BUF_SIZE = 1024;
- char callingProcName[MAX_BUF_SIZE] = {0};
-
- getProcName(callerPid, callingProcName, MAX_BUF_SIZE);
const bool permission = (callerUid == AID_MEDIA ||
callerUid == AID_GRAPHICS ||
callerUid == AID_ROOT ||
- callerUid == AID_SYSTEM);
+ callerUid == AID_CAMERASERVER ||
+ callerUid == AID_AUDIO ||
+ callerUid == AID_SYSTEM ||
+ callerUid == AID_MEDIA_CODEC);
- if (code == CONNECT) {
+ if (code == CONNECT_HWC_CLIENT) {
CHECK_INTERFACE(IQService, data, reply);
if(callerUid != AID_GRAPHICS) {
- ALOGE("display.qservice CONNECT access denied: \
- pid=%d uid=%d process=%s",
- callerPid, callerUid, callingProcName);
+ ALOGE("display.qservice CONNECT_HWC_CLIENT access denied: pid=%d uid=%d",
+ callerPid, callerUid);
return PERMISSION_DENIED;
}
sp<IQClient> client =
interface_cast<IQClient>(data.readStrongBinder());
connect(client);
return NO_ERROR;
+ } else if(code == CONNECT_HDMI_CLIENT) {
+ CHECK_INTERFACE(IQService, data, reply);
+ if(callerUid != AID_SYSTEM && callerUid != AID_ROOT) {
+ ALOGE("display.qservice CONNECT_HDMI_CLIENT access denied: pid=%d uid=%d",
+ callerPid, callerUid);
+ return PERMISSION_DENIED;
+ }
+ sp<IQHDMIClient> client =
+ interface_cast<IQHDMIClient>(data.readStrongBinder());
+ connect(client);
+ return NO_ERROR;
} else if (code > COMMAND_LIST_START && code < COMMAND_LIST_END) {
if(!permission) {
- ALOGE("display.qservice access denied: command=%d\
- pid=%d uid=%d process=%s", code, callerPid,
- callerUid, callingProcName);
+ ALOGE("display.qservice access denied: command=%d pid=%d uid=%d",
+ code, callerPid, callerUid);
return PERMISSION_DENIED;
}
CHECK_INTERFACE(IQService, data, reply);
@@ -117,20 +132,4 @@
}
}
-//Helper
-static void getProcName(int pid, char *buf, int size) {
- int fd = -1;
- snprintf(buf, size, "/proc/%d/cmdline", pid);
- fd = open(buf, O_RDONLY);
- if (fd < 0) {
- strlcpy(buf, "Unknown", size);
- } else {
- ssize_t len = read(fd, buf, size - 1);
- if (len >= 0)
- buf[len] = 0;
-
- close(fd);
- }
-}
-
}; // namespace qService
diff --git a/msm8909/libqservice/IQService.h b/msm8909/libqservice/IQService.h
index 0f0dc4c..f9aa7fd 100644
--- a/msm8909/libqservice/IQService.h
+++ b/msm8909/libqservice/IQService.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -28,6 +28,7 @@
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <IQClient.h>
+#include <IQHDMIClient.h>
namespace qService {
@@ -39,25 +40,41 @@
DECLARE_META_INTERFACE(QService);
enum {
COMMAND_LIST_START = android::IBinder::FIRST_CALL_TRANSACTION,
- SECURING, // Hardware securing start/end notification
- UNSECURING, // Hardware unsecuring start/end notification
- CONNECT, // Connect to qservice
- SCREEN_REFRESH, // Refresh screen through SF invalidate
- EXTERNAL_ORIENTATION, // Set external orientation
- BUFFER_MIRRORMODE, // Buffer mirrormode
- CHECK_EXTERNAL_STATUS, // Check status of external display
- GET_DISPLAY_ATTRIBUTES, // Get display attributes
- SET_HSIC_DATA, // Set HSIC on dspp
- GET_DISPLAY_VISIBLE_REGION, // Get the visibleRegion for dpy
- SET_SECONDARY_DISPLAY_STATUS, // Sets secondary display status
- SET_PARTIAL_UPDATE, // Preference on partial update feature
- SET_VIEW_FRAME, // Set view frame of display
- DYNAMIC_DEBUG, // Enable more logging on the fly
- SET_IDLE_TIMEOUT, // Set idle timeout for GPU fallback
+ GET_PANEL_BRIGHTNESS = 2, // Provides ability to set the panel brightness
+ SET_PANEL_BRIGHTNESS = 3, // Provides ability to get the panel brightness
+ CONNECT_HWC_CLIENT = 4, // Connect to qservice
+ SCREEN_REFRESH = 5, // Refresh screen through SF invalidate
+ EXTERNAL_ORIENTATION = 6,// Set external orientation
+ BUFFER_MIRRORMODE = 7, // Buffer mirrormode
+ CHECK_EXTERNAL_STATUS = 8,// Check status of external display
+ GET_DISPLAY_ATTRIBUTES = 9,// Get display attributes
+ SET_HSIC_DATA = 10, // Set HSIC on dspp
+ GET_DISPLAY_VISIBLE_REGION = 11,// Get the visibleRegion for dpy
+ SET_SECONDARY_DISPLAY_STATUS = 12,// Sets secondary display status
+ SET_MAX_PIPES_PER_MIXER = 13,// Set max pipes per mixer for MDPComp
+ SET_VIEW_FRAME = 14, // Set view frame of display
+ DYNAMIC_DEBUG = 15, // Enable more logging on the fly
+ SET_IDLE_TIMEOUT = 16, // Set idle timeout for GPU fallback
+ TOGGLE_BWC = 17, // Toggle BWC On/Off on targets that support
/* Enable/Disable/Set refresh rate dynamically */
- CONFIGURE_DYN_REFRESH_RATE,
- QDCM_SVC_CMDS, // request QDCM services.
- TOGGLE_SCREEN_UPDATE, // Provides ability to disable screen updates
+ CONFIGURE_DYN_REFRESH_RATE = 18,
+ CONTROL_PARTIAL_UPDATE = 19, // Provides ability to enable/disable partial update
+ TOGGLE_SCREEN_UPDATES = 20, // Provides ability to set the panel brightness
+ SET_FRAME_DUMP_CONFIG = 21, // Provides ability to set the frame dump config
+ SET_S3D_MODE = 22, // Set the 3D mode as specified in msm_hdmi_modes.h
+ CONNECT_HDMI_CLIENT = 23, // Connect HDMI CEC HAL Client
+ QDCM_SVC_CMDS = 24, // request QDCM services.
+ SET_ACTIVE_CONFIG = 25, //Set a specified display config
+ GET_ACTIVE_CONFIG = 26, //Get the current config index
+ GET_CONFIG_COUNT = 27, //Get the number of supported display configs
+ GET_DISPLAY_ATTRIBUTES_FOR_CONFIG = 28, //Get attr for specified config
+ SET_DISPLAY_MODE = 29, // Set display mode to command or video mode
+ SET_CAMERA_STATUS = 30, // To notify display when camera is on and off
+ MIN_HDCP_ENCRYPTION_LEVEL_CHANGED = 31,
+ GET_BW_TRANSACTION_STATUS = 32, //Client can query BW transaction status.
+ SET_LAYER_MIXER_RESOLUTION = 33, // Enables client to set layer mixer resolution.
+ SET_COLOR_MODE = 34, // Overrides the QDCM mode on the display
+ GET_HDR_CAPABILITIES = 35, // Get HDR capabilities for legacy HWC interface
COMMAND_LIST_END = 400,
};
@@ -72,6 +89,14 @@
DEBUG_VSYNC,
DEBUG_VD,
DEBUG_PIPE_LIFECYCLE,
+ DEBUG_DRIVER_CONFIG,
+ DEBUG_ROTATOR,
+ DEBUG_QDCM,
+ DEBUG_SCALAR,
+ DEBUG_CLIENT,
+ DEBUG_DISPLAY,
+ DEBUG_MAX_VAL = DEBUG_DISPLAY, // Used to check each bit of the debug command paramater.
+ // Update DEBUG_MAX_VAL when adding new debug tag.
};
enum {
@@ -80,8 +105,13 @@
ENABLE_PARTIAL_UPDATE,
};
- // Register a client that can be notified
+ // Register a HWC client that can be notified
+ // This client is generic and is intended to get
+ // dispatches of all events calling into QService
virtual void connect(const android::sp<qClient::IQClient>& client) = 0;
+ // Register an HDMI client. This client gets notification of HDMI events
+ // such as plug/unplug and CEC messages
+ virtual void connect(const android::sp<qClient::IQHDMIClient>& client) = 0;
// Generic function to dispatch binder commands
// The type of command decides how the data is parceled
virtual android::status_t dispatch(uint32_t command,
diff --git a/sdm845/libqservice/Makefile.am b/msm8909/libqservice/Makefile.am
similarity index 100%
rename from sdm845/libqservice/Makefile.am
rename to msm8909/libqservice/Makefile.am
diff --git a/msm8909/libqservice/QService.cpp b/msm8909/libqservice/QService.cpp
index 12dd995..546ad7e 100644
--- a/msm8909/libqservice/QService.cpp
+++ b/msm8909/libqservice/QService.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -50,24 +50,52 @@
}
void QService::connect(const sp<qClient::IQClient>& client) {
- ALOGD_IF(QSERVICE_DEBUG,"client connected");
+ ALOGD_IF(QSERVICE_DEBUG,"HWC client connected");
mClient = client;
}
+void QService::connect(const sp<qClient::IQHDMIClient>& client) {
+ ALOGD_IF(QSERVICE_DEBUG,"HDMI client connected");
+ mHDMIClient = client;
+}
+
status_t QService::dispatch(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t err = (status_t) FAILED_TRANSACTION;
IPCThreadState* ipc = IPCThreadState::self();
//Rewind parcel in case we're calling from the same process
- if (ipc->getCallingPid() == getpid())
+ bool sameProcess = (ipc->getCallingPid() == getpid());
+ if(sameProcess)
inParcel->setDataPosition(0);
if (mClient.get()) {
ALOGD_IF(QSERVICE_DEBUG, "Dispatching command: %d", command);
err = mClient->notifyCallback(command, inParcel, outParcel);
+ //Rewind parcel in case we're calling from the same process
+ if (sameProcess)
+ outParcel->setDataPosition(0);
}
return err;
}
+void QService::onHdmiHotplug(int connected) {
+ if(mHDMIClient.get()) {
+ ALOGD_IF(QSERVICE_DEBUG, "%s: HDMI hotplug", __FUNCTION__);
+ mHDMIClient->onHdmiHotplug(connected);
+ } else {
+ ALOGW("%s: Failed to get a valid HDMI client", __FUNCTION__);
+ }
+}
+
+void QService::onCECMessageReceived(char *msg, ssize_t len) {
+ if(mHDMIClient.get()) {
+ ALOGD_IF(QSERVICE_DEBUG, "%s: CEC message received", __FUNCTION__);
+ mHDMIClient->onCECMessageRecieved(msg, len);
+ } else {
+ ALOGW("%s: Failed to get a valid HDMI client", __FUNCTION__);
+ }
+}
+
+
void QService::init()
{
if(!sQService) {
diff --git a/msm8909/libqservice/QService.h b/msm8909/libqservice/QService.h
index a8e4cdb..6bb4d7d 100644
--- a/msm8909/libqservice/QService.h
+++ b/msm8909/libqservice/QService.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -32,7 +32,7 @@
#include <utils/Errors.h>
#include <sys/types.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <binder/IServiceManager.h>
#include <IQService.h>
#include <IQClient.h>
@@ -46,13 +46,17 @@
public:
virtual ~QService();
virtual void connect(const android::sp<qClient::IQClient>& client);
+ virtual void connect(const android::sp<qClient::IQHDMIClient>& client);
virtual android::status_t dispatch(uint32_t command,
const android::Parcel* data,
android::Parcel* reply);
+ virtual void onHdmiHotplug(int connected);
+ virtual void onCECMessageReceived(char *msg, ssize_t len);
static void init();
private:
QService();
android::sp<qClient::IQClient> mClient;
+ android::sp<qClient::IQHDMIClient> mHDMIClient;
static QService *sQService;
};
}; // namespace qService
diff --git a/msm8909/libqservice/QServiceUtils.h b/msm8909/libqservice/QServiceUtils.h
index ff09aa9..8f25253 100644
--- a/msm8909/libqservice/QServiceUtils.h
+++ b/msm8909/libqservice/QServiceUtils.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013-15 The Linux Foundation. All rights reserved.
+* Copyright (c) 2013-14 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -62,24 +62,12 @@
// ----------------------------------------------------------------------------
// Convenience wrappers that clients can call
// ----------------------------------------------------------------------------
-inline android::status_t securing(uint32_t startEnd) {
- return sendSingleParam(qService::IQService::SECURING, startEnd);
-}
-
-inline android::status_t unsecuring(uint32_t startEnd) {
- return sendSingleParam(qService::IQService::UNSECURING, startEnd);
-}
-
inline android::status_t screenRefresh() {
return sendSingleParam(qService::IQService::SCREEN_REFRESH, 1);
}
-inline android::status_t setPartialUpdate(uint32_t enable) {
- return sendSingleParam(qService::IQService::SET_PARTIAL_UPDATE, enable);
-}
-
inline android::status_t toggleScreenUpdate(uint32_t on) {
- return sendSingleParam(qService::IQService::TOGGLE_SCREEN_UPDATE, on);
+ return sendSingleParam(qService::IQService::TOGGLE_SCREEN_UPDATES, on);
}
inline android::status_t setExtOrientation(uint32_t orientation) {
@@ -91,4 +79,24 @@
return sendSingleParam(qService::IQService::BUFFER_MIRRORMODE, enable);
}
+inline android::status_t setCameraLaunchStatus(uint32_t on) {
+ return sendSingleParam(qService::IQService::SET_CAMERA_STATUS, on);
+}
+
+inline bool displayBWTransactionPending() {
+ android::status_t err = (android::status_t) android::FAILED_TRANSACTION;
+ bool ret = false;
+ android::sp<qService::IQService> binder = getBinder();
+ android::Parcel inParcel, outParcel;
+ if(binder != NULL) {
+ err = binder->dispatch(qService::IQService::GET_BW_TRANSACTION_STATUS,
+ &inParcel , &outParcel);
+ if(err != android::NO_ERROR){
+ ALOGE("GET_BW_TRANSACTION_STATUS binder call failed err=%d", err);
+ return ret;
+ }
+ }
+ ret = outParcel.readInt32();
+ return ret;
+}
#endif /* end of include guard: QSERVICEUTILS_H */
diff --git a/sdm845/sdm/include/core/buffer_allocator.h b/msm8909/sdm/include/core/buffer_allocator.h
similarity index 100%
rename from sdm845/sdm/include/core/buffer_allocator.h
rename to msm8909/sdm/include/core/buffer_allocator.h
diff --git a/sdm845/sdm/include/core/buffer_sync_handler.h b/msm8909/sdm/include/core/buffer_sync_handler.h
similarity index 100%
rename from sdm845/sdm/include/core/buffer_sync_handler.h
rename to msm8909/sdm/include/core/buffer_sync_handler.h
diff --git a/msm8909/sdm/include/core/core_interface.h b/msm8909/sdm/include/core/core_interface.h
new file mode 100644
index 0000000..88cbf75
--- /dev/null
+++ b/msm8909/sdm/include/core/core_interface.h
@@ -0,0 +1,240 @@
+/*
+* Copyright (c) 2014 - 2016, 2018 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*! @file core_interface.h
+ @brief Interface file for core of the display subsystem.
+
+ @details Display core is primarily used for loading and unloading different display device
+ components viz primary, external and virtual. Display core is a statically linked library which
+ runs in caller's process context.
+*/
+#ifndef __CORE_INTERFACE_H__
+#define __CORE_INTERFACE_H__
+
+#include <stdint.h>
+
+#include "display_interface.h"
+#include "sdm_types.h"
+#include "buffer_allocator.h"
+#include "buffer_sync_handler.h"
+#include "socket_handler.h"
+
+/*! @brief Display manager interface version.
+
+ @details Display manager interfaces are version tagged to maintain backward compatibility. This
+ version is supplied as a default argument during display core initialization.
+
+ Client may use an older version of interfaces and link to a higher version of display manager
+ library, but vice versa is not allowed.
+
+ A 32-bit client must use 32-bit display core library and a 64-bit client must use 64-bit display
+ core library.
+
+ Display manager interfaces follow default data structures alignment. Client must not override the
+ default padding rules while using these interfaces.
+
+ @warning It is assumed that client upgrades or downgrades display core interface all at once
+ and recompile all binaries which use these interfaces. Mix and match of these interfaces can
+ lead to unpredictable behaviour.
+
+ @sa CoreInterface::CreateCore
+*/
+#define SDM_REVISION_MAJOR (1)
+#define SDM_REVISION_MINOR (0)
+
+#define SDM_VERSION_TAG ((uint32_t) ((SDM_REVISION_MAJOR << 24) | (SDM_REVISION_MINOR << 16) | \
+ (sizeof(SDMCompatibility) << 8) | sizeof(int *)))
+
+namespace sdm {
+
+/*! @brief Forward declaration for debug handler.
+*/
+class DebugHandler;
+
+/*! @brief This enum represents max bandwidth limit mode.
+
+ @sa DisplayInterface::SetMaxBandwidthMode
+*/
+enum HWBwModes {
+ kBwDefault, //!< Default state. No change in device bandwidth limit.
+ kBwCamera, //!< Camera is on. Bandwidth limit should be reduced accordingly.
+ kBwVFlip, //!< VFlip is required. Reduce bandwidth limit accordingly.
+ kBwHFlip, //!< HFlip is required. Reduce bandwidth limit accordingly.
+ kBwModeMax, //!< Limiter for maximum available bandwidth modes.
+};
+
+
+/*! @brief Information on hardware for the first display
+
+ @details This structure returns the display type of the first display on the device
+ (internal display or HDMI etc) and whether it is currently connected,
+
+*/
+struct HWDisplayInterfaceInfo {
+ DisplayType type;
+ bool is_connected;
+};
+
+/*! @brief Display core interface.
+
+ @details This class defines display core interfaces. It contains methods which client shall use
+ to create/destroy different display devices. This interface is created during display core
+ CreateCore() and remains valid until DestroyCore().
+
+ @sa CoreInterface::CreateCore
+ @sa CoreInterface::DestroyCore
+*/
+class CoreInterface {
+ public:
+ /*! @brief Method to create and get handle to display core interface.
+
+ @details This method is the entry point into the display core. Client can create and operate on
+ different display devices only through a valid interface handle obtained using this method. An
+ object of display core is created and handle to this object is returned via output parameter.
+ This interface shall be called only once.
+
+ @param[in] debug_handler \link DebugHandler \endlink
+ @param[in] buffer_allocator \link BufferAllocator \endlink
+ @param[in] buffer_sync_handler \link BufferSyncHandler \endlink
+ @param[out] interface \link CoreInterface \endlink
+ @param[in] version \link SDM_VERSION_TAG \endlink. Client must not override this argument.
+
+ @return \link DisplayError \endlink
+
+ @sa DestroyCore
+ */
+ static DisplayError CreateCore(DebugHandler *debug_handler, BufferAllocator *buffer_allocator,
+ BufferSyncHandler *buffer_sync_handler, CoreInterface **interface,
+ uint32_t version = SDM_VERSION_TAG);
+
+ /*! @brief Method to create and get handle to display core interface.
+
+ @details This method is the entry point into the display core. Client can create and operate on
+ different display devices only through a valid interface handle obtained using this method. An
+ object of display core is created and handle to this object is returned via output parameter.
+ This interface shall be called only once.
+
+ @param[in] debug_handler \link DebugHandler \endlink
+ @param[in] buffer_allocator \link BufferAllocator \endlink
+ @param[in] buffer_sync_handler \link BufferSyncHandler \endlink
+ @param[in] socket_handler \link SocketHandler \endlink
+ @param[out] interface \link CoreInterface \endlink
+ @param[in] version \link SDM_VERSION_TAG \endlink. Client must not override this argument.
+
+ @return \link DisplayError \endlink
+
+ @sa DestroyCore
+ */
+ static DisplayError CreateCore(DebugHandler *debug_handler, BufferAllocator *buffer_allocator,
+ BufferSyncHandler *buffer_sync_handler,
+ SocketHandler *socket_handler, CoreInterface **interface,
+ uint32_t version = SDM_VERSION_TAG);
+
+ /*! @brief Method to release handle to display core interface.
+
+ @details The object of corresponding display core is destroyed when this method is invoked.
+ Client must explicitly destroy all created display device objects associated with this handle
+ before invoking this method.
+
+ @param[in] interface \link CoreInterface \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa CreateCore
+ */
+ static DisplayError DestroyCore();
+
+ /*! @brief Method to create a display device for a given type.
+
+ @details Client shall use this method to create each of the connected display type. A handle to
+ interface associated with this object is returned via output parameter which can be used to
+ interact further with the display device.
+
+ @param[in] type \link DisplayType \endlink
+ @param[in] event_handler \link DisplayEventHandler \endlink
+ @param[out] interface \link DisplayInterface \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa DestroyDisplay
+ */
+ virtual DisplayError CreateDisplay(DisplayType type, DisplayEventHandler *event_handler,
+ DisplayInterface **interface) = 0;
+
+ /*! @brief Method to destroy a display device.
+
+ @details Client shall use this method to destroy each of the created display device objects.
+
+ @param[in] interface \link DisplayInterface \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa CreateDisplay
+ */
+ virtual DisplayError DestroyDisplay(DisplayInterface *interface) = 0;
+
+ /*! @brief Method to update the bandwidth limit as per given mode.
+
+ @param[in] mode indicate the mode or use case
+
+ @return \link DisplayError \endlink
+
+ */
+ virtual DisplayError SetMaxBandwidthMode(HWBwModes mode) = 0;
+
+ /*! @brief Method to get characteristics of the first display.
+
+ @details Client shall use this method to determine if the first display is HDMI, and whether
+ it is currently connected.
+
+ @param[in] hw_disp_info structure that this method will fill up with info.
+
+ @return \link DisplayError \endlink
+
+ */
+ virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) = 0;
+
+ /*! @brief Method to check color transform supported or not.
+
+ @details Client shall use this method to determine if target supports color transform or not
+
+ @return bool
+
+ */
+ virtual bool IsColorTransformSupported() = 0;
+
+
+ protected:
+ virtual ~CoreInterface() { }
+};
+
+} // namespace sdm
+
+#endif // __CORE_INTERFACE_H__
+
diff --git a/sdm845/sdm/include/core/debug_interface.h b/msm8909/sdm/include/core/debug_interface.h
similarity index 96%
copy from sdm845/sdm/include/core/debug_interface.h
copy to msm8909/sdm/include/core/debug_interface.h
index da21944..08f65ea 100644
--- a/sdm845/sdm/include/core/debug_interface.h
+++ b/msm8909/sdm/include/core/debug_interface.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -49,7 +49,8 @@
kTagRotator, //!< Debug log is tagged for rotator.
kTagScalar, //!< Debug log is tagged for Scalar Helper.
kTagQDCM, //!< Debug log is tagged for display QDCM color managing.
- kTagQOSClient, //!< Debug log is tagged for Qos client
+ kTagDisplay, //!< Debug log is tagged for display core logs.
+ kTagClient, //!< Debug log is tagged for SDM client.
};
/*! @brief Display debug handler class.
diff --git a/sdm845/sdm/include/core/display_interface.h b/msm8909/sdm/include/core/display_interface.h
similarity index 94%
copy from sdm845/sdm/include/core/display_interface.h
copy to msm8909/sdm/include/core/display_interface.h
index 524141e..3101eec 100644
--- a/sdm845/sdm/include/core/display_interface.h
+++ b/msm8909/sdm/include/core/display_interface.h
@@ -135,6 +135,12 @@
kPortDP, // Display is connected to DP port.
};
+/*! @brief This enum represents the events received by Display HAL. */
+enum DisplayEvent {
+ kIdleTimeout, // Event triggered by Idle Timer.
+ kThermalEvent, // Event triggered by Thermal.
+};
+
/*! @brief This structure defines configuration for fixed properties of a display device.
@sa DisplayInterface::GetConfig
@@ -245,6 +251,9 @@
*/
virtual DisplayError CECMessage(char *message) = 0;
+ /*! @brief Event handler for events received by Display HAL. */
+ virtual DisplayError HandleEvent(DisplayEvent event) = 0;
+
protected:
virtual ~DisplayEventHandler() { }
};
@@ -455,13 +464,11 @@
/*! @brief Method to set the refresh rate of a display.
- @param[in] refresh_rate new refresh rate of the display.
-
- @param[in] final_rate indicates whether refresh rate is final rate or can be changed by sdm
+ @param[in] new refresh rate of the display.
@return \link DisplayError \endlink
*/
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate) = 0;
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate) = 0;
/*! @brief Method to query whether scanning is support for the HDMI display.
@@ -541,13 +548,6 @@
*/
virtual DisplayError SetColorMode(const std::string &color_mode) = 0;
- /*! @brief Method to set the color mode by ID. This method is used for debugging only.
-
- @param[in] mode_name Mode ID which needs to be set
-
- @return \link DisplayError \endlink
- */
- virtual DisplayError SetColorModeById(int32_t color_mode_id) = 0;
/*! @brief Method to set the color transform
@param[in] length Mode name which needs to be set
@@ -664,6 +664,26 @@
*/
virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable) = 0;
+ /*! @brief Method to check whether a client target with the given properties
+ can be supported/handled by hardware.
+
+ @param[in] width client target width
+ @param[in] height client target height
+ @param[in] format client target format
+ @param[in] colorMetaData client target colorMetaData
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetClientTargetSupport(uint32_t width, uint32_t height,
+ LayerBufferFormat format,
+ const ColorMetaData &color_metadata) = 0;
+
+ /*
+ * Returns a string consisting of a dump of SDM's display and layer related state
+ * as programmed to driver
+ */
+ virtual std::string Dump() = 0;
+
protected:
virtual ~DisplayInterface() { }
};
diff --git a/sdm845/sdm/include/core/layer_buffer.h b/msm8909/sdm/include/core/layer_buffer.h
similarity index 100%
rename from sdm845/sdm/include/core/layer_buffer.h
rename to msm8909/sdm/include/core/layer_buffer.h
diff --git a/sdm845/sdm/include/core/layer_stack.h b/msm8909/sdm/include/core/layer_stack.h
similarity index 98%
rename from sdm845/sdm/include/core/layer_stack.h
rename to msm8909/sdm/include/core/layer_stack.h
index b8977e2..f12e5c1 100644
--- a/sdm845/sdm/include/core/layer_stack.h
+++ b/msm8909/sdm/include/core/layer_stack.h
@@ -85,8 +85,8 @@
kCompositionSDE, //!< This layer will be composed by SDE. It must not be composed by
//!< GPU or Blit.
- kCompositionCursor, // This cursor layer can receive async position updates irrespective of
- // dedicated h/w cursor usage. It must not be composed by GPU or Blit
+ kCompositionHWCursor, //!< This layer will be composed by SDE using HW Cursor. It must not be
+ //!< composed by GPU or Blit.
kCompositionHybrid, //!< This layer will be drawn by a blit engine and SDE together.
//!< Display device will split the layer, update the blit rectangle
diff --git a/sdm845/sdm/include/core/sdm_types.h b/msm8909/sdm/include/core/sdm_types.h
similarity index 97%
rename from sdm845/sdm/include/core/sdm_types.h
rename to msm8909/sdm/include/core/sdm_types.h
index fae1153..f8bb4e3 100644
--- a/sdm845/sdm/include/core/sdm_types.h
+++ b/msm8909/sdm/include/core/sdm_types.h
@@ -55,6 +55,7 @@
kErrorShutDown, //!< Driver is processing shutdown sequence
kErrorPerfValidation, //!< Bandwidth or Clock requirement validation failure.
kErrorNoAppLayers, //!< No App layer(s) in the draw cycle.
+ kErrorNotValidated, //!< Draw cycle has not been validated.
};
/*! @brief This structure is defined for client and library compatibility check purpose only. This
diff --git a/sdm845/sdm/include/core/socket_handler.h b/msm8909/sdm/include/core/socket_handler.h
similarity index 100%
rename from sdm845/sdm/include/core/socket_handler.h
rename to msm8909/sdm/include/core/socket_handler.h
diff --git a/sdm845/sdm/include/private/color_interface.h b/msm8909/sdm/include/private/color_interface.h
similarity index 100%
rename from sdm845/sdm/include/private/color_interface.h
rename to msm8909/sdm/include/private/color_interface.h
diff --git a/sdm845/sdm/include/private/color_params.h b/msm8909/sdm/include/private/color_params.h
similarity index 95%
copy from sdm845/sdm/include/private/color_params.h
copy to msm8909/sdm/include/private/color_params.h
index 0a53832..897b234 100644
--- a/sdm845/sdm/include/private/color_params.h
+++ b/msm8909/sdm/include/private/color_params.h
@@ -37,12 +37,16 @@
#include <core/sdm_types.h>
#include <core/display_interface.h>
+#include <utility>
#include <string>
+#include <vector>
#include "hw_info_types.h"
namespace sdm {
+typedef std::vector<std::pair<std::string, std::string>> AttrVal;
+
// Bitmap Pending action to indicate to the caller what's pending to be taken care of.
enum PendingAction {
kInvalidating = BITMAP(0),
@@ -55,6 +59,7 @@
kDisableFrameCapture = BITMAP(7),
kConfigureDetailedEnhancer = BITMAP(8),
kInvalidatingAndkSetPanelBrightness = BITMAP(9),
+ kModeSet = BITMAP(10),
kGetDetailedEnhancerData = BITMAP(21),
kNoAction = BITMAP(31),
};
@@ -89,7 +94,7 @@
static const std::string kSdr = "sdr";
static const std::string kNative = "native";
-static const std::string kDcip3 = "dci_p3";
+static const std::string kDcip3 = "dcip3";
static const std::string kSrgb = "srgb";
static const std::string kDisplayP3 = "display_p3";
@@ -115,11 +120,12 @@
kGlobalColorFeatureDither,
kGlobalColorFeatureGamut,
kGlobalColorFeaturePADither,
+ kGlobalColorFeatureCsc,
kMaxNumPPFeatures,
};
struct PPPendingParams {
- PendingAction action = kNoAction;
+ int32_t action = kNoAction;
void *params = NULL;
};
@@ -327,6 +333,21 @@
SDEPccCfg *GetConfig() { return this; }
};
+struct SDECscCfg {
+ static const uint32_t kCscMVSize = 9;
+ static const uint32_t kCscBVSize = 3;
+ static const uint32_t kCscLVSize = 6;
+ uint32_t flags;
+ uint32_t csc_mv[kCscMVSize];
+ uint32_t csc_pre_bv[kCscBVSize];
+ uint32_t csc_post_bv[kCscBVSize];
+ uint32_t csc_pre_lv[kCscLVSize];
+ uint32_t csc_post_lv[kCscLVSize];
+
+ static SDECscCfg *Init(uint32_t arg __attribute__((__unused__)));
+ SDECscCfg *GetConfig() { return this; }
+};
+
struct SDEDitherCfg {
uint32_t g_y_depth;
uint32_t r_cr_depth;
@@ -578,9 +599,13 @@
// from ColorManager, containing all physical features to be programmed and also compute
// metadata/populate into T.
inline DisplayError AddFeature(uint32_t feature_id, PPFeatureInfo *feature) {
- if (feature_id < kMaxNumPPFeatures)
+ if (feature_id < kMaxNumPPFeatures) {
+ if (feature_[feature_id]) {
+ delete feature_[feature_id];
+ feature_[feature_id] = NULL;
+ }
feature_[feature_id] = feature;
-
+ }
return kErrorNone;
}
diff --git a/sdm845/sdm/include/private/dpps_control_interface.h b/msm8909/sdm/include/private/dpps_control_interface.h
similarity index 100%
rename from sdm845/sdm/include/private/dpps_control_interface.h
rename to msm8909/sdm/include/private/dpps_control_interface.h
diff --git a/sdm845/sdm/include/private/extension_interface.h b/msm8909/sdm/include/private/extension_interface.h
similarity index 100%
rename from sdm845/sdm/include/private/extension_interface.h
rename to msm8909/sdm/include/private/extension_interface.h
diff --git a/sdm845/sdm/include/private/hw_info_types.h b/msm8909/sdm/include/private/hw_info_types.h
similarity index 96%
copy from sdm845/sdm/include/private/hw_info_types.h
copy to msm8909/sdm/include/private/hw_info_types.h
index cdfec2e..d4f8d72 100644
--- a/sdm845/sdm/include/private/hw_info_types.h
+++ b/msm8909/sdm/include/private/hw_info_types.h
@@ -38,8 +38,6 @@
const int kMaxSDELayers = 16; // Maximum number of layers that can be handled by MDP5 hardware
// in a given layer stack.
-const int kMaxBlitLayers = 32; // Maximum number of layers that can be handled by MDP3 hardware
- // in a given layer stack.
#define MAX_PLANES 4
#define MAX_DETAIL_ENHANCE_CURVE 3
@@ -111,12 +109,11 @@
};
typedef std::map<HWSubBlockType, std::vector<LayerBufferFormat>> FormatsMap;
-typedef std::map<LayerBufferFormat, float> CompRatioMap;
struct HWDynBwLimitInfo {
uint32_t cur_mode = kBwDefault;
- uint64_t total_bw_limit[kBwModeMax] = { 0 };
- uint64_t pipe_bw_limit[kBwModeMax] = { 0 };
+ uint32_t total_bw_limit[kBwModeMax] = { 0 };
+ uint32_t pipe_bw_limit[kBwModeMax] = { 0 };
};
struct HWPipeCaps {
@@ -143,7 +140,6 @@
uint32_t max_input_width = 0;
uint32_t max_output_width = 0;
uint32_t max_scale_up = 1;
- uint32_t prefill_lines = 4;
};
enum SmartDMARevision {
@@ -166,12 +162,13 @@
uint32_t num_smp_per_pipe = 0;
uint32_t max_scale_up = 1;
uint32_t max_scale_down = 1;
+ float rot_downscale_max = 0.0f;
uint64_t max_bandwidth_low = 0;
uint64_t max_bandwidth_high = 0;
uint32_t max_mixer_width = 2048;
uint32_t max_pipe_width = 2048;
uint32_t max_cursor_size = 0;
- uint64_t max_pipe_bw = 0;
+ uint32_t max_pipe_bw = 0;
uint32_t max_sde_clk = 0;
float clk_fudge_factor = 1.0f;
uint32_t macrotile_nv12_factor = 0;
@@ -187,6 +184,7 @@
bool has_macrotile = false;
bool has_non_scalar_rgb = false;
bool is_src_split = false;
+ bool perf_calc = false;
bool has_dyn_bw_support = false;
bool separate_rotator = false;
bool has_qseed3 = false;
@@ -201,11 +199,6 @@
bool has_avr = false;
bool has_hdr = false;
SmartDMARevision smart_dma_rev = SmartDMARevision::V1;
- float ib_fudge_factor = 1.0f;
- uint32_t undersized_prefill_lines = 0;
- CompRatioMap comp_ratio_rt_map;
- CompRatioMap comp_ratio_nrt_map;
-
void Reset() { *this = HWResourceInfo(); }
};
@@ -438,7 +431,6 @@
};
struct HWPipeInfo {
- HWPipeInfo *pair = NULL;
uint8_t rect = 255;
uint32_t pipe_id = 0;
HWSubBlockType sub_block_type = kHWSubBlockMax;
@@ -492,8 +484,10 @@
std::vector<LayerRect> left_frame_roi = {}; // Left ROI.
std::vector<LayerRect> right_frame_roi = {}; // Right ROI.
LayerRect partial_fb_roi = {}; // Damaged area in framebuffer.
+
bool roi_split = false; // Indicates separated left and right ROI
- bool async_cursor_updates = false; // Cursor layer allowed to have async updates
+
+ bool use_hw_cursor = false; // Indicates that HWCursor pipe needs to be used for cursor layer
DestScaleInfoMap dest_scale_info_map = {};
HWHDRLayerInfo hdr_layer_info = {};
Handle pvt_data = NULL; // Private data used by sdm extension only.
@@ -503,9 +497,8 @@
HWLayersInfo info;
HWLayerConfig config[kMaxSDELayers];
float output_compression = 1.0f;
- uint64_t ab_bps = 0;
- uint64_t ib_bps = 0;
- uint32_t clock_hz = 0;
+ uint32_t bandwidth = 0;
+ uint32_t clock = 0;
HWAVRInfo hw_avr_info = {};
};
diff --git a/sdm845/sdm/include/private/partial_update_interface.h b/msm8909/sdm/include/private/partial_update_interface.h
similarity index 92%
rename from sdm845/sdm/include/private/partial_update_interface.h
rename to msm8909/sdm/include/private/partial_update_interface.h
index a1c2382..b753587 100644
--- a/sdm845/sdm/include/private/partial_update_interface.h
+++ b/msm8909/sdm/include/private/partial_update_interface.h
@@ -35,6 +35,8 @@
struct PUConstraints {
bool enable = true; //!< If this is set, PU will be enabled or it will be disabled
+ bool enable_cursor_pu = false; //!< If this is set, PU will consider cursor layer in the layer
+ //!< stack for cursor partial update
};
class PartialUpdateInterface {
diff --git a/sdm845/sdm/include/private/resource_interface.h b/msm8909/sdm/include/private/resource_interface.h
similarity index 88%
rename from sdm845/sdm/include/private/resource_interface.h
rename to msm8909/sdm/include/private/resource_interface.h
index e140c33..356c566 100644
--- a/sdm845/sdm/include/private/resource_interface.h
+++ b/msm8909/sdm/include/private/resource_interface.h
@@ -48,7 +48,7 @@
const HWPanelInfo &hw_panel_info,
const HWMixerAttributes &mixer_attributes) = 0;
virtual DisplayError Start(Handle display_ctx) = 0;
- virtual DisplayError Stop(Handle display_ctx) = 0;
+ virtual DisplayError Stop(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError Commit(Handle display_ctx, HWLayers *hw_layers) = 0;
@@ -58,8 +58,11 @@
virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
bool rotate90, BufferLayout layout,
bool use_rotator_downscale) = 0;
- virtual DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
- int x, int y) = 0;
+ virtual DisplayError ValidateCursorConfig(Handle display_ctx, const Layer *layer,
+ bool is_top) = 0;
+ virtual DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
+ int x, int y,
+ DisplayConfigVariableInfo *fb_config) = 0;
virtual DisplayError SetMaxBandwidthMode(HWBwModes mode) = 0;
virtual DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info) = 0;
virtual DisplayError SetDetailEnhancerData(Handle display_ctx,
diff --git a/sdm845/sdm/include/private/strategy_interface.h b/msm8909/sdm/include/private/strategy_interface.h
similarity index 93%
rename from sdm845/sdm/include/private/strategy_interface.h
rename to msm8909/sdm/include/private/strategy_interface.h
index 1174e7f..f903d5f 100644
--- a/sdm845/sdm/include/private/strategy_interface.h
+++ b/msm8909/sdm/include/private/strategy_interface.h
@@ -36,6 +36,9 @@
//!< that requires minimum number of pipe for the current frame. i.e.,
//!< video only composition, secure only composition or GPU composition
+ bool use_cursor = false; //!< If this is set, strategy manager will configure cursor layer in the
+ //!< layer stack as hw cursor else it will be treated as a normal layer
+
uint32_t max_layers = kMaxSDELayers; //!< Maximum number of layers that shall be programmed
//!< on hardware for the given layer stack.
};
diff --git a/sdm845/sdm/include/utils/constants.h b/msm8909/sdm/include/utils/constants.h
similarity index 100%
rename from sdm845/sdm/include/utils/constants.h
rename to msm8909/sdm/include/utils/constants.h
diff --git a/msm8909/sdm/include/utils/debug.h b/msm8909/sdm/include/utils/debug.h
new file mode 100644
index 0000000..af23a92
--- /dev/null
+++ b/msm8909/sdm/include/utils/debug.h
@@ -0,0 +1,121 @@
+/*
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+#include <stdint.h>
+#include <core/sdm_types.h>
+#include <core/debug_interface.h>
+#include <core/display_interface.h>
+#include <display_properties.h>
+
+#define DLOG(tag, method, format, ...) Debug::Get()->method(tag, __CLASS__ "::%s: " format, \
+ __FUNCTION__, ##__VA_ARGS__)
+
+#define DLOGE_IF(tag, format, ...) DLOG(tag, Error, format, ##__VA_ARGS__)
+#define DLOGW_IF(tag, format, ...) DLOG(tag, Warning, format, ##__VA_ARGS__)
+#define DLOGI_IF(tag, format, ...) DLOG(tag, Info, format, ##__VA_ARGS__)
+#define DLOGD_IF(tag, format, ...) DLOG(tag, Debug, format, ##__VA_ARGS__)
+#define DLOGV_IF(tag, format, ...) DLOG(tag, Verbose, format, ##__VA_ARGS__)
+
+#define DLOGE(format, ...) DLOGE_IF(kTagNone, format, ##__VA_ARGS__)
+#define DLOGD(format, ...) DLOGD_IF(kTagNone, format, ##__VA_ARGS__)
+#define DLOGW(format, ...) DLOGW_IF(kTagNone, format, ##__VA_ARGS__)
+#define DLOGI(format, ...) DLOGI_IF(kTagNone, format, ##__VA_ARGS__)
+#define DLOGV(format, ...) DLOGV_IF(kTagNone, format, ##__VA_ARGS__)
+
+#define DTRACE_BEGIN(custom_string) Debug::Get()->BeginTrace(__CLASS__, __FUNCTION__, custom_string)
+#define DTRACE_END() Debug::Get()->EndTrace()
+#define DTRACE_SCOPED() ScopeTracer <Debug> scope_tracer(__CLASS__, __FUNCTION__)
+
+namespace sdm {
+
+class Debug {
+ public:
+ static inline void SetDebugHandler(DebugHandler *debug_handler) {
+ debug_.debug_handler_ = debug_handler;
+ }
+ static inline DebugHandler* Get() { return debug_.debug_handler_; }
+ static int GetSimulationFlag();
+ static int GetHDMIResolution();
+ static void GetIdleTimeoutMs(uint32_t *active_ms, uint32_t *inactive_ms);
+ static int GetBootAnimLayerCount();
+ static bool IsRotatorDownScaleDisabled();
+ static bool IsDecimationDisabled();
+ static int GetMaxPipesPerMixer(DisplayType display_type);
+ static int GetMaxUpscale();
+ static bool IsVideoModeEnabled();
+ static bool IsRotatorUbwcDisabled();
+ static bool IsRotatorSplitDisabled();
+ static bool IsScalarDisabled();
+ static bool IsUbwcTiledFrameBuffer();
+ static bool IsAVRDisabled();
+ static bool IsExtAnimDisabled();
+ static bool IsPartialSplitDisabled();
+ static DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
+ static int GetExtMaxlayers();
+ static bool GetProperty(const char *property_name, char *value);
+ static bool SetProperty(const char *property_name, const char *value);
+
+ private:
+ Debug();
+
+ // By default, drop any log messages/traces coming from Display manager. It will be overriden by
+ // Display manager client when core is successfully initialized.
+ class DefaultDebugHandler : public DebugHandler {
+ public:
+ virtual void Error(DebugTag /*tag*/, const char */*format*/, ...) { }
+ virtual void Warning(DebugTag /*tag*/, const char */*format*/, ...) { }
+ virtual void Info(DebugTag /*tag*/, const char */*format*/, ...) { }
+ virtual void Debug(DebugTag /*tag*/, const char */*format*/, ...) { }
+ virtual void Verbose(DebugTag /*tag*/, const char */*format*/, ...) { }
+ virtual void BeginTrace(const char */*class_name*/, const char */*function_name*/,
+ const char */*custom_string*/) { }
+ virtual void EndTrace() { }
+ virtual DisplayError GetProperty(const char */*property_name*/, int */*value*/) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError GetProperty(const char */*property_name*/, char */*value*/) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError SetProperty(const char */*property_name*/, const char */*value*/) {
+ return kErrorNotSupported;
+ }
+ };
+
+ DefaultDebugHandler default_debug_handler_;
+ DebugHandler *debug_handler_;
+ static Debug debug_;
+};
+
+} // namespace sdm
+
+#endif // __DEBUG_H__
+
diff --git a/sdm845/sdm/include/utils/factory.h b/msm8909/sdm/include/utils/factory.h
similarity index 100%
rename from sdm845/sdm/include/utils/factory.h
rename to msm8909/sdm/include/utils/factory.h
diff --git a/sdm845/sdm/include/utils/formats.h b/msm8909/sdm/include/utils/formats.h
similarity index 100%
rename from sdm845/sdm/include/utils/formats.h
rename to msm8909/sdm/include/utils/formats.h
diff --git a/sdm845/sdm/include/utils/locker.h b/msm8909/sdm/include/utils/locker.h
similarity index 100%
rename from sdm845/sdm/include/utils/locker.h
rename to msm8909/sdm/include/utils/locker.h
diff --git a/msm8909/sdm/include/utils/rect.h b/msm8909/sdm/include/utils/rect.h
new file mode 100644
index 0000000..00273e1
--- /dev/null
+++ b/msm8909/sdm/include/utils/rect.h
@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __RECT_H__
+#define __RECT_H__
+
+#include <stdint.h>
+#include <core/sdm_types.h>
+#include <core/layer_stack.h>
+#include <utils/debug.h>
+
+namespace sdm {
+
+ enum RectOrientation {
+ kOrientationPortrait,
+ kOrientationLandscape,
+ kOrientationUnknown,
+ };
+
+ bool IsValid(const LayerRect &rect);
+ bool IsCongruent(const LayerRect &rect1, const LayerRect &rect2);
+ void LogI(DebugTag debug_tag, const char *prefix, const LayerRect &roi);
+ void Log(DebugTag debug_tag, const char *prefix, const LayerRect &roi);
+ void Normalize(const uint32_t &align_x, const uint32_t &align_y, LayerRect *rect);
+ LayerRect Union(const LayerRect &rect1, const LayerRect &rect2);
+ LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2);
+ LayerRect Subtract(const LayerRect &rect1, const LayerRect &rect2);
+ LayerRect Reposition(const LayerRect &rect1, const int &x_offset, const int &y_offset);
+ void SplitLeftRight(const LayerRect &in_rect, uint32_t split_count, uint32_t align_x,
+ bool flip_horizontal, LayerRect *out_rects);
+ void SplitTopBottom(const LayerRect &in_rect, uint32_t split_count, uint32_t align_y,
+ bool flip_horizontal, LayerRect *out_rects);
+ void MapRect(const LayerRect &src_domain, const LayerRect &dst_domain, const LayerRect &in_rect,
+ LayerRect *out_rect);
+ void TransformHV(const LayerRect &src_domain, const LayerRect &in_rect,
+ const LayerTransform &transform, LayerRect *out_rect);
+ RectOrientation GetOrientation(const LayerRect &in_rect);
+} // namespace sdm
+
+#endif // __RECT_H__
+
diff --git a/msm8909/sdm/include/utils/sync_task.h b/msm8909/sdm/include/utils/sync_task.h
new file mode 100644
index 0000000..725460a
--- /dev/null
+++ b/msm8909/sdm/include/utils/sync_task.h
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __SYNC_TASK_H__
+#define __SYNC_TASK_H__
+
+#include <thread>
+#include <mutex>
+#include <condition_variable> // NOLINT
+
+namespace sdm {
+
+template <class TaskCode>
+class SyncTask {
+ public:
+ // This class need to be overridden by caller to pass on a task context.
+ class TaskContext {
+ public:
+ virtual ~TaskContext() { }
+ };
+
+ // Methods to callback into caller for command codes executions in worker thread.
+ class TaskHandler {
+ public:
+ virtual ~TaskHandler() { }
+ virtual void OnTask(const TaskCode &task_code, TaskContext *task_context) = 0;
+ };
+
+ explicit SyncTask(TaskHandler &task_handler) : task_handler_(task_handler) {
+ // Block caller thread until worker thread has started and ready to listen to task commands.
+ // Worker thread will signal as soon as callback is received in the new thread.
+ std::unique_lock<std::mutex> caller_lock(caller_mutex_);
+ std::thread worker_thread(SyncTaskThread, this);
+ worker_thread_.swap(worker_thread);
+ caller_cv_.wait(caller_lock);
+ }
+
+ ~SyncTask() {
+ // Task code does not matter here.
+ PerformTask(task_code_, nullptr, true);
+ worker_thread_.join();
+ }
+
+ void PerformTask(const TaskCode &task_code, TaskContext *task_context) {
+ PerformTask(task_code, task_context, false);
+ }
+
+ private:
+ void PerformTask(const TaskCode &task_code, TaskContext *task_context, bool terminate) {
+ std::unique_lock<std::mutex> caller_lock(caller_mutex_);
+
+ // New scope to limit scope of worker lock to this block.
+ {
+ // Set task command code and notify worker thread.
+ std::unique_lock<std::mutex> worker_lock(worker_mutex_);
+ task_code_ = task_code;
+ task_context_ = task_context;
+ worker_thread_exit_ = terminate;
+ pending_code_ = true;
+ worker_cv_.notify_one();
+ }
+
+ // Wait for worker thread to finish and signal.
+ caller_cv_.wait(caller_lock);
+ }
+
+ static void SyncTaskThread(SyncTask *sync_task) {
+ if (sync_task) {
+ sync_task->OnThreadCallback();
+ }
+ }
+
+ void OnThreadCallback() {
+ // Acquire worker lock and start waiting for events.
+ // Wait must start before caller thread can post events, otherwise posted events will be lost.
+ // Caller thread will be blocked until worker thread signals readiness.
+ std::unique_lock<std::mutex> worker_lock(worker_mutex_);
+
+ // New scope to limit scope of caller lock to this block.
+ {
+ // Signal caller thread that worker thread is ready to listen to events.
+ std::unique_lock<std::mutex> caller_lock(caller_mutex_);
+ caller_cv_.notify_one();
+ }
+
+ while (!worker_thread_exit_) {
+ // Add predicate to handle spurious interrupts.
+ // Wait for caller thread to signal new command codes.
+ worker_cv_.wait(worker_lock, [this] { return pending_code_; });
+
+ // Call task handler which is implemented by the caller.
+ if (!worker_thread_exit_) {
+ task_handler_.OnTask(task_code_, task_context_);
+ }
+
+ pending_code_ = false;
+ // Notify completion of current task to the caller thread which is blocked.
+ std::unique_lock<std::mutex> caller_lock(caller_mutex_);
+ caller_cv_.notify_one();
+ }
+ }
+
+ TaskHandler &task_handler_;
+ TaskCode task_code_;
+ TaskContext *task_context_ = nullptr;
+ std::thread worker_thread_;
+ std::mutex caller_mutex_;
+ std::mutex worker_mutex_;
+ std::condition_variable caller_cv_;
+ std::condition_variable worker_cv_;
+ bool worker_thread_exit_ = false;
+ bool pending_code_ = false;
+};
+
+} // namespace sdm
+
+#endif // __SYNC_TASK_H__
diff --git a/sdm845/sdm/include/utils/sys.h b/msm8909/sdm/include/utils/sys.h
similarity index 100%
rename from sdm845/sdm/include/utils/sys.h
rename to msm8909/sdm/include/utils/sys.h
diff --git a/sdm845/sdm/include/utils/utils.h b/msm8909/sdm/include/utils/utils.h
similarity index 100%
rename from sdm845/sdm/include/utils/utils.h
rename to msm8909/sdm/include/utils/utils.h
diff --git a/sdm845/sdm/libs/core/Android.mk b/msm8909/sdm/libs/core/Android.mk
similarity index 93%
copy from sdm845/sdm/libs/core/Android.mk
copy to msm8909/sdm/libs/core/Android.mk
index c5002a9..7aab09c 100644
--- a/sdm845/sdm/libs/core/Android.mk
+++ b/msm8909/sdm/libs/core/Android.mk
@@ -7,7 +7,7 @@
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_HEADER_LIBRARIES := display_headers
-LOCAL_CFLAGS := -fno-operator-names -Wno-unused-parameter -DLOG_TAG=\"SDM\" \
+LOCAL_CFLAGS := -Wno-unused-parameter -DLOG_TAG=\"SDM\" \
$(common_flags)
LOCAL_HW_INTF_PATH_1 := fb
LOCAL_SHARED_LIBRARIES := libdl libsdmutils
@@ -32,7 +32,6 @@
comp_manager.cpp \
strategy.cpp \
resource_default.cpp \
- dump_impl.cpp \
color_manager.cpp \
hw_events_interface.cpp \
hw_info_interface.cpp \
@@ -51,7 +50,6 @@
$(LOCAL_HW_INTF_PATH_2)/hw_device_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_events_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_scale_drm.cpp \
- $(LOCAL_HW_INTF_PATH_2)/hw_virtual_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_color_manager_drm.cpp
endif
@@ -65,7 +63,6 @@
$(SDM_HEADER_PATH)/core/core_interface.h \
$(SDM_HEADER_PATH)/core/debug_interface.h \
$(SDM_HEADER_PATH)/core/display_interface.h \
- $(SDM_HEADER_PATH)/core/dump_interface.h \
$(SDM_HEADER_PATH)/core/layer_buffer.h \
$(SDM_HEADER_PATH)/core/layer_stack.h \
$(SDM_HEADER_PATH)/core/sdm_types.h \
diff --git a/sdm845/sdm/libs/core/Makefile.am b/msm8909/sdm/libs/core/Makefile.am
similarity index 100%
rename from sdm845/sdm/libs/core/Makefile.am
rename to msm8909/sdm/libs/core/Makefile.am
diff --git a/sdm845/sdm/libs/core/color_manager.cpp b/msm8909/sdm/libs/core/color_manager.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/color_manager.cpp
rename to msm8909/sdm/libs/core/color_manager.cpp
diff --git a/sdm845/sdm/libs/core/color_manager.h b/msm8909/sdm/libs/core/color_manager.h
similarity index 100%
rename from sdm845/sdm/libs/core/color_manager.h
rename to msm8909/sdm/libs/core/color_manager.h
diff --git a/sdm845/sdm/libs/core/comp_manager.cpp b/msm8909/sdm/libs/core/comp_manager.cpp
similarity index 84%
copy from sdm845/sdm/libs/core/comp_manager.cpp
copy to msm8909/sdm/libs/core/comp_manager.cpp
index d18b5b8..5488e46 100644
--- a/sdm845/sdm/libs/core/comp_manager.cpp
+++ b/msm8909/sdm/libs/core/comp_manager.cpp
@@ -33,6 +33,12 @@
namespace sdm {
+static bool NeedsScaledComposition(const DisplayConfigVariableInfo &fb_config,
+ const HWMixerAttributes &mixer_attributes) {
+ return ((fb_config.x_pixels != mixer_attributes.width) ||
+ (fb_config.y_pixels != mixer_attributes.height));
+}
+
DisplayError CompManager::Init(const HWResourceInfo &hw_res_info,
ExtensionInterface *extension_intf,
BufferAllocator *buffer_allocator,
@@ -121,6 +127,7 @@
registered_displays_[type] = 1;
display_comp_ctx->is_primary_panel = hw_panel_info.is_primary_panel;
display_comp_ctx->display_type = type;
+ display_comp_ctx->fb_config = fb_config;
*display_ctx = display_comp_ctx;
// New non-primary display device has been added, so move the composition mode to safe mode until
// resources for the added display is configured properly.
@@ -129,6 +136,7 @@
max_sde_ext_layers_ = UINT32(Debug::GetExtMaxlayers());
}
+ display_comp_ctx->scaled_composition = NeedsScaledComposition(fb_config, mixer_attributes);
DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
"display type %d", registered_displays_.to_ulong(), configured_displays_.to_ulong(),
display_comp_ctx->display_type);
@@ -207,6 +215,10 @@
}
}
+ display_comp_ctx->scaled_composition = NeedsScaledComposition(fb_config, mixer_attributes);
+ // Update new resolution.
+ display_comp_ctx->fb_config = fb_config;
+
return error;
}
@@ -214,17 +226,35 @@
DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(comp_handle);
StrategyConstraints *constraints = &display_comp_ctx->constraints;
+ bool low_end_hw = ((hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe +
+ hw_res_info_.num_dma_pipe) <= kSafeModeThreshold);
constraints->safe_mode = safe_mode_;
+ constraints->use_cursor = false;
constraints->max_layers = max_layers_;
// Limit 2 layer SDE Comp if its not a Primary Display.
// Safe mode is the policy for External display on a low end device.
if (!display_comp_ctx->is_primary_panel) {
- bool low_end_hw = ((hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe +
- hw_res_info_.num_dma_pipe) <= kSafeModeThreshold);
constraints->max_layers = max_sde_ext_layers_;
constraints->safe_mode = (low_end_hw && !hw_res_info_.separate_rotator) ? true : safe_mode_;
+ if(hw_layers->info.stack->flags.secure_present)
+ secure_external_layer_ = true;
+ else
+ secure_external_layer_ = false;
+ }
+
+ // When Secure layer is present on external, GPU composition should be policy
+ // for Primary on low end devices
+ if(display_comp_ctx->is_primary_panel && (registered_displays_.count() > 1)
+ && low_end_hw && secure_external_layer_) {
+ DLOGV_IF(kTagCompManager,"Secure layer present for LET. Fallingback to GPU");
+ hw_layers->info.stack->flags.skip_present = 1;
+ for(auto &layer : hw_layers->info.stack->layers) {
+ if(layer->composition != kCompositionGPUTarget) {
+ layer->flags.skip = 1;
+ }
+ }
}
// If a strategy fails after successfully allocating resources, then set safe mode
@@ -232,6 +262,9 @@
constraints->safe_mode = true;
}
+ // Set use_cursor constraint to Strategy
+ constraints->use_cursor = display_comp_ctx->valid_cursor;
+
// TODO(user): App layer count will change for hybrid composition
uint32_t app_layer_count = UINT32(hw_layers->info.stack->layers.size()) - 1;
if (display_comp_ctx->idle_fallback || display_comp_ctx->thermal_fallback_) {
@@ -249,6 +282,11 @@
SCOPE_LOCK(locker_);
DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
+ display_comp_ctx->valid_cursor = SupportLayerAsCursor(display_comp_ctx, hw_layers);
+
+ // pu constraints
+ display_comp_ctx->pu_constraints.enable_cursor_pu = display_comp_ctx->valid_cursor;
+
display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies,
display_comp_ctx->pu_constraints);
display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
@@ -286,10 +324,12 @@
}
if (error != kErrorNone) {
+ resource_intf_->Stop(display_resource_ctx, hw_layers);
DLOGE("Composition strategies exhausted for display = %d", display_comp_ctx->display_type);
+ return error;
}
- resource_intf_->Stop(display_resource_ctx);
+ error = resource_intf_->Stop(display_resource_ctx, hw_layers);
return error;
}
@@ -335,7 +375,7 @@
DLOGE("Reconfigure failed for display = %d", display_comp_ctx->display_type);
}
- resource_intf_->Stop(display_resource_ctx);
+ resource_intf_->Stop(display_resource_ctx, hw_layers);
if (error != kErrorNone) {
error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
}
@@ -449,23 +489,52 @@
display_comp_ctx->pu_constraints.enable = enable;
}
-void CompManager::AppendDump(char *buffer, uint32_t length) {
- SCOPE_LOCK(locker_);
-}
-
DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
bool rotate90) {
BufferLayout layout = Debug::IsUbwcTiledFrameBuffer() ? kUBWC : kLinear;
return resource_intf_->ValidateScaling(crop, dst, rotate90, layout, true);
}
-DisplayError CompManager::ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
+DisplayError CompManager::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
int x, int y) {
DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
+ return resource_intf_->ValidateAndSetCursorPosition(display_resource_ctx, hw_layers, x, y,
+ &display_comp_ctx->fb_config);
+}
- return resource_intf_->ValidateCursorPosition(display_resource_ctx, hw_layers, x, y);
+bool CompManager::SupportLayerAsCursor(Handle comp_handle, HWLayers *hw_layers) {
+ DisplayCompositionContext *display_comp_ctx =
+ reinterpret_cast<DisplayCompositionContext *>(comp_handle);
+ Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
+ LayerStack *layer_stack = hw_layers->info.stack;
+ bool supported = false;
+ int32_t gpu_index = -1;
+
+ // HW Cursor cannot be used, if Display configuration needs scaled composition.
+ if (display_comp_ctx->scaled_composition || !layer_stack->flags.cursor_present) {
+ return supported;
+ }
+
+ for (int32_t i = INT32(layer_stack->layers.size() - 1); i >= 0; i--) {
+ Layer *layer = layer_stack->layers.at(UINT32(i));
+ if (layer->composition == kCompositionGPUTarget) {
+ gpu_index = i;
+ break;
+ }
+ }
+ if (gpu_index <= 0) {
+ return supported;
+ }
+ Layer *cursor_layer = layer_stack->layers.at(UINT32(gpu_index) - 1);
+ if (cursor_layer->flags.cursor && !cursor_layer->flags.skip &&
+ resource_intf_->ValidateCursorConfig(display_resource_ctx,
+ cursor_layer, true) == kErrorNone) {
+ supported = true;
+ }
+
+ return supported;
}
DisplayError CompManager::SetMaxBandwidthMode(HWBwModes mode) {
diff --git a/sdm845/sdm/libs/core/comp_manager.h b/msm8909/sdm/libs/core/comp_manager.h
similarity index 94%
copy from sdm845/sdm/libs/core/comp_manager.h
copy to msm8909/sdm/libs/core/comp_manager.h
index c6b8972..d1351ae 100644
--- a/sdm845/sdm/libs/core/comp_manager.h
+++ b/msm8909/sdm/libs/core/comp_manager.h
@@ -33,11 +33,10 @@
#include "strategy.h"
#include "resource_default.h"
#include "hw_interface.h"
-#include "dump_impl.h"
namespace sdm {
-class CompManager : public DumpImpl {
+class CompManager {
public:
DisplayError Init(const HWResourceInfo &hw_res_info_, ExtensionInterface *extension_intf,
BufferAllocator *buffer_allocator, BufferSyncHandler *buffer_sync_handler,
@@ -67,6 +66,8 @@
void ControlPartialUpdate(Handle display_ctx, bool enable);
DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90);
DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
+ bool SupportLayerAsCursor(Handle display_ctx, HWLayers *hw_layers);
+ DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
bool SetDisplayState(Handle display_ctx, DisplayState state, DisplayType display_type);
DisplayError SetMaxBandwidthMode(HWBwModes mode);
DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info);
@@ -75,9 +76,6 @@
bool enable);
DisplayError ControlDpps(bool enable);
- // DumpImpl method
- virtual void AppendDump(char *buffer, uint32_t length);
-
private:
static const int kMaxThermalLevel = 3;
static const int kSafeModeThreshold = 4;
@@ -96,7 +94,10 @@
// Using primary panel flag of hw panel to configure Constraints. We do not need other hw
// panel parameters for now.
bool is_primary_panel = false;
+ bool valid_cursor = false;
PUConstraints pu_constraints = {};
+ bool scaled_composition = false;
+ DisplayConfigVariableInfo fb_config = {};
};
Locker locker_;
@@ -107,6 +108,7 @@
bool safe_mode_ = false; // Flag to notify all displays to be in resource crunch
// mode, where strategy manager chooses the best strategy
// that uses optimal number of pipes for each display
+ bool secure_external_layer_ = false;
HWResourceInfo hw_res_info_;
BufferAllocator *buffer_allocator_ = NULL;
ExtensionInterface *extension_intf_ = NULL;
diff --git a/msm8909/sdm/libs/core/core_impl.cpp b/msm8909/sdm/libs/core/core_impl.cpp
new file mode 100644
index 0000000..212612c
--- /dev/null
+++ b/msm8909/sdm/libs/core/core_impl.cpp
@@ -0,0 +1,188 @@
+/*
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <dlfcn.h>
+#include <utils/locker.h>
+#include <utils/constants.h>
+#include <utils/debug.h>
+
+#include "core_impl.h"
+#include "display_primary.h"
+#include "display_hdmi.h"
+#include "display_virtual.h"
+#include "hw_info_interface.h"
+#include "color_manager.h"
+
+#define __CLASS__ "CoreImpl"
+
+namespace sdm {
+
+CoreImpl::CoreImpl(BufferAllocator *buffer_allocator,
+ BufferSyncHandler *buffer_sync_handler,
+ SocketHandler *socket_handler)
+ : buffer_allocator_(buffer_allocator), buffer_sync_handler_(buffer_sync_handler),
+ socket_handler_(socket_handler) {
+}
+
+DisplayError CoreImpl::Init() {
+ SCOPE_LOCK(locker_);
+ DisplayError error = kErrorNone;
+
+ // Try to load extension library & get handle to its interface.
+ if (extension_lib_.Open(EXTENSION_LIBRARY_NAME)) {
+ if (!extension_lib_.Sym(CREATE_EXTENSION_INTERFACE_NAME,
+ reinterpret_cast<void **>(&create_extension_intf_)) ||
+ !extension_lib_.Sym(DESTROY_EXTENSION_INTERFACE_NAME,
+ reinterpret_cast<void **>(&destroy_extension_intf_))) {
+ DLOGE("Unable to load symbols, error = %s", extension_lib_.Error());
+ return kErrorUndefined;
+ }
+
+ error = create_extension_intf_(EXTENSION_VERSION_TAG, &extension_intf_);
+ if (error != kErrorNone) {
+ DLOGE("Unable to create interface");
+ return error;
+ }
+ } else {
+ DLOGW("Unable to load = %s, error = %s", EXTENSION_LIBRARY_NAME, extension_lib_.Error());
+ }
+
+ error = HWInfoInterface::Create(&hw_info_intf_);
+ if (error != kErrorNone) {
+ goto CleanupOnError;
+ }
+
+ if (hw_info_intf_ == NULL) {
+ return kErrorResources;
+ }
+ error = hw_info_intf_->GetHWResourceInfo(&hw_resource_);
+ if (error != kErrorNone) {
+ goto CleanupOnError;
+ }
+
+ error = comp_mgr_.Init(hw_resource_, extension_intf_, buffer_allocator_,
+ buffer_sync_handler_, socket_handler_);
+
+ if (error != kErrorNone) {
+ goto CleanupOnError;
+ }
+
+ error = ColorManagerProxy::Init(hw_resource_);
+ // if failed, doesn't affect display core functionalities.
+ if (error != kErrorNone) {
+ DLOGW("Unable creating color manager and continue without it.");
+ }
+
+ return kErrorNone;
+
+CleanupOnError:
+ if (hw_info_intf_) {
+ HWInfoInterface::Destroy(hw_info_intf_);
+ }
+
+ return error;
+}
+
+DisplayError CoreImpl::Deinit() {
+ SCOPE_LOCK(locker_);
+
+ ColorManagerProxy::Deinit();
+
+ comp_mgr_.Deinit();
+ HWInfoInterface::Destroy(hw_info_intf_);
+
+ return kErrorNone;
+}
+
+DisplayError CoreImpl::CreateDisplay(DisplayType type, DisplayEventHandler *event_handler,
+ DisplayInterface **intf) {
+ SCOPE_LOCK(locker_);
+
+ if (!event_handler || !intf) {
+ return kErrorParameters;
+ }
+
+ DisplayBase *display_base = NULL;
+
+ switch (type) {
+ case kPrimary:
+ display_base = new DisplayPrimary(event_handler, hw_info_intf_, buffer_sync_handler_,
+ buffer_allocator_, &comp_mgr_);
+ break;
+ case kHDMI:
+ display_base = new DisplayHDMI(event_handler, hw_info_intf_, buffer_sync_handler_,
+ buffer_allocator_, &comp_mgr_);
+ break;
+ case kVirtual:
+ display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_,
+ buffer_allocator_, &comp_mgr_);
+ break;
+ default:
+ DLOGE("Spurious display type %d", type);
+ return kErrorParameters;
+ }
+
+ if (!display_base) {
+ return kErrorMemory;
+ }
+
+ DisplayError error = display_base->Init();
+ if (error != kErrorNone) {
+ delete display_base;
+ return error;
+ }
+
+ *intf = display_base;
+ return kErrorNone;
+}
+
+DisplayError CoreImpl::DestroyDisplay(DisplayInterface *intf) {
+ SCOPE_LOCK(locker_);
+
+ if (!intf) {
+ return kErrorParameters;
+ }
+
+ DisplayBase *display_base = static_cast<DisplayBase *>(intf);
+ display_base->Deinit();
+ delete display_base;
+
+ return kErrorNone;
+}
+
+DisplayError CoreImpl::SetMaxBandwidthMode(HWBwModes mode) {
+ SCOPE_LOCK(locker_);
+
+ return comp_mgr_.SetMaxBandwidthMode(mode);
+}
+
+DisplayError CoreImpl::GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) {
+ return hw_info_intf_->GetFirstDisplayInterfaceType(hw_disp_info);
+}
+
+bool CoreImpl::IsColorTransformSupported() {
+ return (hw_resource_.has_ppp) ? false : true;
+}
+} // namespace sdm
+
diff --git a/msm8909/sdm/libs/core/core_impl.h b/msm8909/sdm/libs/core/core_impl.h
new file mode 100644
index 0000000..e5156aa
--- /dev/null
+++ b/msm8909/sdm/libs/core/core_impl.h
@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2014 - 2016, 2018 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __CORE_IMPL_H__
+#define __CORE_IMPL_H__
+
+#include <core/core_interface.h>
+#include <private/extension_interface.h>
+#include <private/color_interface.h>
+#include <utils/locker.h>
+#include <utils/sys.h>
+
+#include "hw_interface.h"
+#include "comp_manager.h"
+
+#define SET_REVISION(major, minor) ((major << 8) | minor)
+
+namespace sdm {
+
+class CoreImpl : public CoreInterface {
+ public:
+ // This class implements display core interface revision 1.0.
+ static const uint16_t kRevision = SET_REVISION(1, 0);
+ CoreImpl(BufferAllocator *buffer_allocator, BufferSyncHandler *buffer_sync_handler,
+ SocketHandler *socket_handler);
+ virtual ~CoreImpl() { }
+
+ // This method returns the interface revision for the current display core object.
+ // Future revisions will override this method and return the appropriate revision upon query.
+ virtual uint16_t GetRevision() { return kRevision; }
+ virtual DisplayError Init();
+ virtual DisplayError Deinit();
+
+ // Methods from core interface
+ virtual DisplayError CreateDisplay(DisplayType type, DisplayEventHandler *event_handler,
+ DisplayInterface **intf);
+ virtual DisplayError DestroyDisplay(DisplayInterface *intf);
+ virtual DisplayError SetMaxBandwidthMode(HWBwModes mode);
+ virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info);
+ virtual bool IsColorTransformSupported();
+
+ protected:
+ Locker locker_;
+ BufferAllocator *buffer_allocator_ = NULL;
+ BufferSyncHandler *buffer_sync_handler_ = NULL;
+ HWResourceInfo hw_resource_;
+ CompManager comp_mgr_;
+ HWInfoInterface *hw_info_intf_ = NULL;
+ DynLib extension_lib_;
+ ExtensionInterface *extension_intf_ = NULL;
+ CreateExtensionInterface create_extension_intf_ = NULL;
+ DestroyExtensionInterface destroy_extension_intf_ = NULL;
+ SocketHandler *socket_handler_ = NULL;
+};
+
+} // namespace sdm
+
+#endif // __CORE_IMPL_H__
+
diff --git a/sdm845/sdm/libs/core/core_interface.cpp b/msm8909/sdm/libs/core/core_interface.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/core_interface.cpp
rename to msm8909/sdm/libs/core/core_interface.cpp
diff --git a/sdm845/sdm/libs/core/display_base.cpp b/msm8909/sdm/libs/core/display_base.cpp
similarity index 87%
copy from sdm845/sdm/libs/core/display_base.cpp
copy to msm8909/sdm/libs/core/display_base.cpp
index 618dd2e..8246737 100644
--- a/sdm845/sdm/libs/core/display_base.cpp
+++ b/msm8909/sdm/libs/core/display_base.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
@@ -27,6 +27,11 @@
#include <utils/debug.h>
#include <utils/formats.h>
#include <utils/rect.h>
+#include <utils/utils.h>
+
+#include <iomanip>
+#include <map>
+#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
@@ -107,7 +112,7 @@
DLOGW("InitColorModes failed for display = %d", display_type_);
}
- Debug::Get()->GetProperty("sdm.disable_hdr_lut_gen", &disable_hdr_lut_gen_);
+ Debug::Get()->GetProperty(DISABLE_HDR_LUT_GEN, &disable_hdr_lut_gen_);
return kErrorNone;
@@ -153,7 +158,7 @@
hw_layers_info.app_layer_count++;
}
- DLOGV_IF(kTagNone, "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, "
+ DLOGD_IF(kTagNone, "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, "
"display type: %d", layers.size(), hw_layers_info.app_layer_count,
hw_layers_info.gpu_target_index, display_type_);
@@ -211,6 +216,7 @@
DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = kErrorNone;
+ needs_validate_ = true;
if (!active_) {
return kErrorPermission;
@@ -220,6 +226,7 @@
return kErrorParameters;
}
+ DLOGI_IF(kTagDisplay, "Entering Prepare for display type : %d", display_type_);
error = BuildLayerStackStats(layer_stack);
if (error != kErrorNone) {
return error;
@@ -250,7 +257,7 @@
error = hw_intf_->Validate(&hw_layers_);
if (error == kErrorNone) {
// Strategy is successful now, wait for Commit().
- pending_commit_ = true;
+ needs_validate_ = false;
break;
}
if (error == kErrorShutDown) {
@@ -261,6 +268,7 @@
comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
+ DLOGI_IF(kTagDisplay, "Exiting Prepare for display type : %d", display_type_);
return error;
}
@@ -269,7 +277,7 @@
DisplayError error = kErrorNone;
if (!active_) {
- pending_commit_ = false;
+ needs_validate_ = true;
return kErrorPermission;
}
@@ -277,13 +285,11 @@
return kErrorParameters;
}
- if (!pending_commit_) {
+ if (needs_validate_) {
DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_);
- return kErrorUndefined;
+ return kErrorNotValidated;
}
- pending_commit_ = false;
-
// Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp
if (layer_stack->flags.attributes_changed) {
error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_);
@@ -297,12 +303,12 @@
}
}
+ DLOGI_IF(kTagDisplay, "Entering commit for display type : %d", display_type_);
CommitLayerParams(layer_stack);
- if (comp_manager_->Commit(display_comp_ctx_, &hw_layers_)) {
- if (error != kErrorNone) {
- return error;
- }
+ error = comp_manager_->Commit(display_comp_ctx_, &hw_layers_);
+ if (error != kErrorNone) {
+ return error;
}
// check if feature list cache is dirty and pending.
@@ -329,6 +335,7 @@
return error;
}
+ DLOGI_IF(kTagDisplay, "Exiting commit for display type : %d", display_type_);
return kErrorNone;
}
@@ -343,7 +350,7 @@
error = hw_intf_->Flush();
if (error == kErrorNone) {
comp_manager_->Purge(display_comp_ctx_);
- pending_commit_ = false;
+ needs_validate_ = true;
} else {
DLOGW("Unable to flush display = %d", display_type_);
}
@@ -508,79 +515,76 @@
return error;
}
-void DisplayBase::AppendDump(char *buffer, uint32_t length) {
+std::string DisplayBase::Dump() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
HWDisplayAttributes attrib;
uint32_t active_index = 0;
uint32_t num_modes = 0;
+ std::ostringstream os;
+
hw_intf_->GetNumDisplayAttributes(&num_modes);
hw_intf_->GetActiveConfig(&active_index);
hw_intf_->GetDisplayAttributes(active_index, &attrib);
- DumpImpl::AppendString(buffer, length, "\n-----------------------");
- DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_);
- DumpImpl::AppendString(buffer, length, "\nstate: %u, vsync on: %u, max. mixer stages: %u",
- state_, INT(vsync_enable_), max_mixer_stages_);
- DumpImpl::AppendString(buffer, length, "\nnum configs: %u, active config index: %u",
- num_modes, active_index);
+ os << "device type:" << display_type_;
+ os << "\nstate: " << state_ << " vsync on: " << vsync_enable_ << " max. mixer stages: "
+ << max_mixer_stages_;
+ os << "\nnum configs: " << num_modes << " active config index: " << active_index;
DisplayConfigVariableInfo &info = attrib;
- uint32_t num_hw_layers = 0;
- if (hw_layers_.info.stack) {
- num_hw_layers = UINT32(hw_layers_.info.hw_layers.size());
- }
+ uint32_t num_hw_layers = UINT32(hw_layers_.info.hw_layers.size());
if (num_hw_layers == 0) {
- DumpImpl::AppendString(buffer, length, "\nNo hardware layers programmed");
- return;
+ os << "\nNo hardware layers programmed";
+ return os.str();
}
- LayerBuffer *out_buffer = hw_layers_.info.stack->output_buffer;
- if (out_buffer) {
- DumpImpl::AppendString(buffer, length, "\nres:%u x %u format: %s", out_buffer->width,
- out_buffer->height, GetFormatString(out_buffer->format));
+ LayerBuffer *out_buffer = nullptr;
+ if (hw_layers_.info.stack) {
+ out_buffer = hw_layers_.info.stack->output_buffer;
+ }
+ if (out_buffer != nullptr) {
+ os << "\nres: " << out_buffer->width << "x" << out_buffer->height << " format: "
+ << GetFormatString(out_buffer->format);
} else {
- DumpImpl::AppendString(buffer, length, "\nres:%u x %u, dpi:%.2f x %.2f, fps:%u,"
- "vsync period: %u", info.x_pixels, info.y_pixels, info.x_dpi,
- info.y_dpi, info.fps, info.vsync_period_ns);
+ os.precision(2);
+ os << "\nres: " << info.x_pixels << "x" << info.y_pixels << " dpi: " << std::fixed <<
+ info.x_dpi << "x" << std::fixed << info.y_dpi << " fps: " << info.fps <<
+ " vsync period: " << info.vsync_period_ns;
}
- DumpImpl::AppendString(buffer, length, "\n");
-
HWLayersInfo &layer_info = hw_layers_.info;
-
for (uint32_t i = 0; i < layer_info.left_frame_roi.size(); i++) {
LayerRect &l_roi = layer_info.left_frame_roi.at(i);
LayerRect &r_roi = layer_info.right_frame_roi.at(i);
- DumpImpl::AppendString(buffer, length, "\nROI%d(L T R B) : LEFT(%d %d %d %d)", i,
- INT(l_roi.left), INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom));
+ os << "\nROI(LTRB)#" << i << " LEFT(" << INT(l_roi.left) << " " << INT(l_roi.top) << " " <<
+ INT(l_roi.right) << " " << INT(l_roi.bottom) << ")";
if (IsValid(r_roi)) {
- DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left),
- INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
+ os << " RIGHT(" << INT(r_roi.left) << " " << INT(r_roi.top) << " " << INT(r_roi.right) << " "
+ << INT(r_roi.bottom) << ")";
}
}
LayerRect &fb_roi = layer_info.partial_fb_roi;
if (IsValid(fb_roi)) {
- DumpImpl::AppendString(buffer, length, "\nPartial FB ROI(L T R B) : (%d %d %d %d)",
- INT(fb_roi.left), INT(fb_roi.top), INT(fb_roi.right), INT(fb_roi.bottom));
+ os << "\nPartial FB ROI(LTRB):(" << INT(fb_roi.left) << " " << INT(fb_roi.top) << " " <<
+ INT(fb_roi.right) << " " << INT(fb_roi.bottom) << ")";
}
const char *header = "\n| Idx | Comp Type | Split | WB | Pipe | W x H | Format | Src Rect (L T R B) | Dst Rect (L T R B) | Z | Flags | Deci(HxV) | CS | Rng |"; //NOLINT
const char *newline = "\n|-----|-------------|--------|----|--------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|-----|"; //NOLINT
const char *format = "\n| %3s | %11s " "| %6s " "| %2s | 0x%04x | %4d x %4d | %24s " "| %4d %4d %4d %4d " "| %4d %4d %4d %4d " "| %2s | %10s " "| %9s | %2s | %3s |"; //NOLINT
- DumpImpl::AppendString(buffer, length, "\n");
- DumpImpl::AppendString(buffer, length, newline);
- DumpImpl::AppendString(buffer, length, header);
- DumpImpl::AppendString(buffer, length, newline);
+
+ os << "\n";
+ os << newline;
+ os << header;
+ os << newline;
for (uint32_t i = 0; i < num_hw_layers; i++) {
uint32_t layer_index = hw_layers_.info.index[i];
- // sdm-layer from client layer stack
- Layer *sdm_layer = hw_layers_.info.stack->layers.at(layer_index);
// hw-layer from hw layers info
Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
LayerBuffer *input_buffer = &hw_layer.input_buffer;
@@ -588,7 +592,7 @@
HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session;
char idx[8] = { 0 };
- const char *comp_type = GetName(sdm_layer->composition);
+ const char *comp_type = GetName(hw_layer.composition);
const char *buffer_format = GetFormatString(input_buffer->format);
const char *rotate_split[2] = { "Rot-1", "Rot-2" };
const char *comp_split[2] = { "Comp-1", "Comp-2" };
@@ -597,19 +601,20 @@
for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) {
char writeback_id[8] = { 0 };
+ char row[1024];
HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count];
LayerRect &src_roi = rotate.src_roi;
LayerRect &dst_roi = rotate.dst_roi;
snprintf(writeback_id, sizeof(writeback_id), "%d", rotate.writeback_id);
- DumpImpl::AppendString(buffer, length, format, idx, comp_type, rotate_split[count],
+ snprintf(row, sizeof(row), format, idx, comp_type, rotate_split[count],
writeback_id, rotate.pipe_id, input_buffer->width,
input_buffer->height, buffer_format, INT(src_roi.left),
INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right),
INT(dst_roi.bottom), "-", "- ", "- ", "-", "-");
-
+ os << row;
// print the below only once per layer block, fill with spaces for rest.
idx[0] = 0;
comp_type = "";
@@ -644,27 +649,31 @@
snprintf(color_primary, sizeof(color_primary), "%d", color_metadata.colorPrimaries);
snprintf(range, sizeof(range), "%d", color_metadata.range);
- DumpImpl::AppendString(buffer, length, format, idx, comp_type, comp_split[count],
+ char row[1024];
+ snprintf(row, sizeof(row), format, idx, comp_type, comp_split[count],
"-", pipe.pipe_id, input_buffer->width, input_buffer->height,
buffer_format, INT(src_roi.left), INT(src_roi.top),
INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left),
INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
z_order, flags, decimation, color_primary, range);
+ os << row;
// print the below only once per layer block, fill with spaces for rest.
idx[0] = 0;
comp_type = "";
}
-
- DumpImpl::AppendString(buffer, length, newline);
}
+
+ os << newline << "\n";
+
+ return os.str();
}
const char * DisplayBase::GetName(const LayerComposition &composition) {
switch (composition) {
case kCompositionGPU: return "GPU";
case kCompositionSDE: return "SDE";
- case kCompositionCursor: return "CURSOR";
+ case kCompositionHWCursor: return "CURSOR";
case kCompositionHybrid: return "HYBRID";
case kCompositionBlit: return "BLIT";
case kCompositionGPUTarget: return "GPU_TARGET";
@@ -803,10 +812,6 @@
return error;
}
-DisplayError DisplayBase::SetColorModeById(int32_t color_mode_id) {
- return color_mgr_->ColorMgrSetMode(color_mode_id);
-}
-
DisplayError DisplayBase::SetColorModeInternal(const std::string &color_mode) {
DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str());
@@ -830,7 +835,7 @@
return error;
}
-DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr, const std::string &type,
+DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr,const std::string &type,
std::string *value) {
if (!value) {
return kErrorParameters;
@@ -954,7 +959,8 @@
return kErrorNotSupported;
}
- DisplayError error = comp_manager_->ValidateCursorPosition(display_comp_ctx_, &hw_layers_, x, y);
+ DisplayError error = comp_manager_->ValidateAndSetCursorPosition(display_comp_ctx_, &hw_layers_,
+ x, y);
if (error == kErrorNone) {
return hw_intf_->SetCursorPosition(&hw_layers_, x, y);
}
@@ -986,14 +992,10 @@
DisplayError error = kErrorNone;
if (vsync_enable_ != enable) {
error = hw_intf_->SetVSyncState(enable);
- if (error == kErrorNotSupported) {
- error = hw_events_intf_->SetEventState(HWEvent::VSYNC, enable);
- }
if (error == kErrorNone) {
vsync_enable_ = enable;
}
}
-
return error;
}
@@ -1081,6 +1083,7 @@
return kErrorParameters;
}
+ DLOGD_IF(kTagQDCM, "Reconfiguring mixer with width : %d, height : %d", width, height);
HWMixerAttributes mixer_attributes;
mixer_attributes.width = width;
mixer_attributes.height = height;
@@ -1133,9 +1136,10 @@
uint32_t align_y = 2;
if (req_mixer_width_ && req_mixer_height_) {
+ DLOGD_IF(kTagDisplay, "Required mixer width : %d, height : %d",
+ req_mixer_width_, req_mixer_height_);
*new_mixer_width = req_mixer_width_;
*new_mixer_height = req_mixer_height_;
-
return (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height);
}
@@ -1151,6 +1155,7 @@
max_area_layer_index = i;
}
}
+ DLOGV_IF(kTagDisplay, "Max area layer at index : %d", max_area_layer_index);
// TODO(user): Mark layer which needs downscaling on GPU fallback as priority layer and use MDP
// for composition to avoid quality mismatch between GPU and MDP switch(idle timeout usecase).
@@ -1325,10 +1330,6 @@
sdm_layer->input_buffer.release_fence_fd = temp;
}
-
- // Reset the sync fence fds of HWLayer
- hw_layer.input_buffer.acquire_fence_fd = -1;
- hw_layer.input_buffer.release_fence_fd = -1;
}
return;
@@ -1442,4 +1443,94 @@
return error;
}
+
+DisplayError DisplayBase::GetClientTargetSupport(uint32_t width, uint32_t height,
+ LayerBufferFormat format,
+ const ColorMetaData &color_metadata) {
+ if (format != kFormatRGBA8888 && format != kFormatRGBA1010102) {
+ DLOGW("Unsupported format = %d", format);
+ return kErrorNotSupported;
+ } else if (ValidateScaling(width, height) != kErrorNone) {
+ DLOGW("Unsupported width = %d height = %d", width, height);
+ return kErrorNotSupported;
+ } else if (color_metadata.transfer && color_metadata.colorPrimaries) {
+ DisplayError error = ValidateDataspace(color_metadata);
+ if (error != kErrorNone) {
+ DLOGW("Unsupported Transfer Request = %d Color Primary = %d",
+ color_metadata.transfer, color_metadata.colorPrimaries);
+ return error;
+ }
+
+ // Check for BT2020 support
+ if (color_metadata.colorPrimaries == ColorPrimaries_BT2020) {
+ DLOGW("Unsupported Color Primary = %d", color_metadata.colorPrimaries);
+ return kErrorNotSupported;
+ }
+ }
+
+ return kErrorNone;
+}
+
+DisplayError DisplayBase::ValidateScaling(uint32_t width, uint32_t height) {
+ uint32_t display_width = display_attributes_.x_pixels;
+ uint32_t display_height = display_attributes_.y_pixels;
+
+ HWResourceInfo hw_resource_info = HWResourceInfo();
+ hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
+ float max_scale_down = FLOAT(hw_resource_info.max_scale_down);
+ float max_scale_up = FLOAT(hw_resource_info.max_scale_up);
+
+ float scale_x = FLOAT(width / display_width);
+ float scale_y = FLOAT(height / display_height);
+
+ if (scale_x > max_scale_down || scale_y > max_scale_down) {
+ return kErrorNotSupported;
+ }
+
+ if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
+ if ((1.0f / scale_x) > max_scale_up) {
+ return kErrorNotSupported;
+ }
+ }
+
+ if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
+ if ((1.0f / scale_y) > max_scale_up) {
+ return kErrorNotSupported;
+ }
+ }
+
+ return kErrorNone;
+}
+
+DisplayError DisplayBase::ValidateDataspace(const ColorMetaData &color_metadata) {
+ // Handle transfer
+ switch (color_metadata.transfer) {
+ case Transfer_sRGB:
+ case Transfer_SMPTE_170M:
+ case Transfer_SMPTE_ST2084:
+ case Transfer_HLG:
+ case Transfer_Linear:
+ case Transfer_Gamma2_2:
+ break;
+ default:
+ DLOGW("Unsupported Transfer Request = %d", color_metadata.transfer);
+ return kErrorNotSupported;
+ }
+
+ // Handle colorPrimaries
+ switch (color_metadata.colorPrimaries) {
+ case ColorPrimaries_BT709_5:
+ case ColorPrimaries_BT601_6_525:
+ case ColorPrimaries_BT601_6_625:
+ case ColorPrimaries_DCIP3:
+ case ColorPrimaries_BT2020:
+ break;
+ default:
+ DLOGW("Unsupported Color Primary = %d", color_metadata.colorPrimaries);
+ return kErrorNotSupported;
+ }
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/display_base.h b/msm8909/sdm/libs/core/display_base.h
similarity index 94%
copy from sdm845/sdm/libs/core/display_base.h
copy to msm8909/sdm/libs/core/display_base.h
index 4023229..e511dac 100644
--- a/sdm845/sdm/libs/core/display_base.h
+++ b/msm8909/sdm/libs/core/display_base.h
@@ -44,7 +44,7 @@
using std::recursive_mutex;
using std::lock_guard;
-class DisplayBase : public DisplayInterface, DumpImpl {
+class DisplayBase : public DisplayInterface {
public:
DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
@@ -96,7 +96,6 @@
virtual DisplayError GetColorModes(uint32_t *mode_count, std::vector<std::string> *color_modes);
virtual DisplayError GetColorModeAttr(const std::string &color_mode, AttrVal *attr);
virtual DisplayError SetColorMode(const std::string &color_mode);
- virtual DisplayError SetColorModeById(int32_t color_mode_id);
virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform);
virtual DisplayError GetDefaultColorMode(std::string *color_mode);
virtual DisplayError ApplyDefaultDisplayMode(void);
@@ -115,6 +114,10 @@
virtual DisplayError GetDisplayPort(DisplayPort *port);
virtual bool IsPrimaryDisplay();
virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable);
+ virtual DisplayError GetClientTargetSupport(uint32_t width, uint32_t height,
+ LayerBufferFormat format,
+ const ColorMetaData &color_metadata);
+ virtual std::string Dump();
protected:
DisplayError BuildLayerStackStats(LayerStack *layer_stack);
@@ -122,9 +125,8 @@
void CommitLayerParams(LayerStack *layer_stack);
void PostCommitLayerParams(LayerStack *layer_stack);
DisplayError HandleHDR(LayerStack *layer_stack);
-
- // DumpImpl method
- void AppendDump(char *buffer, uint32_t length);
+ DisplayError ValidateScaling(uint32_t width, uint32_t height);
+ DisplayError ValidateDataspace(const ColorMetaData &color_metadata);
const char *GetName(const LayerComposition &composition);
DisplayError ReconfigureDisplay();
@@ -153,7 +155,7 @@
Handle hw_device_ = 0;
Handle display_comp_ctx_ = 0;
HWLayers hw_layers_;
- bool pending_commit_ = false;
+ bool needs_validate_ = true;
bool vsync_enable_ = false;
uint32_t max_mixer_stages_ = 0;
HWInfoInterface *hw_info_intf_ = NULL;
diff --git a/sdm845/sdm/libs/core/display_hdmi.cpp b/msm8909/sdm/libs/core/display_hdmi.cpp
similarity index 94%
copy from sdm845/sdm/libs/core/display_hdmi.cpp
copy to msm8909/sdm/libs/core/display_hdmi.cpp
index b31ac94..5f8eeb4 100644
--- a/sdm845/sdm/libs/core/display_hdmi.cpp
+++ b/msm8909/sdm/libs/core/display_hdmi.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
@@ -54,7 +54,7 @@
uint32_t active_mode_index;
char value[64] = "0";
- Debug::GetProperty("sdm.hdmi.s3d_mode", value);
+ Debug::GetProperty(HDMI_S3D_MODE_PROP, value);
HWS3DMode mode = (HWS3DMode)atoi(value);
if (mode > kS3DModeNone && mode < kS3DModeMax) {
active_mode_index = GetBestConfig(mode);
@@ -94,8 +94,6 @@
DLOGE("Failed to create hardware events interface. Error = %d", error);
}
- current_refresh_rate_ = hw_panel_info_.max_fps;
-
return error;
}
@@ -137,21 +135,18 @@
return error;
}
-DisplayError DisplayHDMI::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+DisplayError DisplayHDMI::SetRefreshRate(uint32_t refresh_rate) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!active_) {
return kErrorPermission;
}
- if (current_refresh_rate_ != refresh_rate) {
- DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
- if (error != kErrorNone) {
- return error;
- }
+ DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
+ if (error != kErrorNone) {
+ return error;
}
- current_refresh_rate_ = refresh_rate;
return DisplayBase::ReconfigureDisplay();
}
@@ -168,7 +163,6 @@
uint32_t DisplayHDMI::GetBestConfig(HWS3DMode s3d_mode) {
uint32_t best_index = 0, index;
uint32_t num_modes = 0;
- HWDisplayAttributes best_attrib;
hw_intf_->GetNumDisplayAttributes(&num_modes);
@@ -295,10 +289,6 @@
DisplayBase::ReconfigureDisplay();
}
-void DisplayHDMI::CECMessage(char *message) {
- event_handler_->CECMessage(message);
-}
-
DisplayError DisplayHDMI::VSync(int64_t timestamp) {
if (vsync_enable_) {
DisplayEventVSync vsync;
diff --git a/sdm845/sdm/libs/core/display_hdmi.h b/msm8909/sdm/libs/core/display_hdmi.h
similarity index 92%
rename from sdm845/sdm/libs/core/display_hdmi.h
rename to msm8909/sdm/libs/core/display_hdmi.h
index ca09ce3..4758b04 100644
--- a/sdm845/sdm/libs/core/display_hdmi.h
+++ b/msm8909/sdm/libs/core/display_hdmi.h
@@ -29,7 +29,6 @@
#include <map>
#include "display_base.h"
-#include "dump_impl.h"
#include "hw_events_interface.h"
namespace sdm {
@@ -44,7 +43,7 @@
virtual DisplayError Init();
virtual DisplayError Prepare(LayerStack *layer_stack);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate);
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
virtual bool IsUnderscanSupported();
virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
@@ -53,7 +52,6 @@
virtual DisplayError Blank(bool blank) { return kErrorNone; }
virtual void IdleTimeout() { }
virtual void ThermalEvent(int64_t thermal_level) { }
- virtual void CECMessage(char *message);
virtual void IdlePowerCollapse() { }
private:
@@ -64,9 +62,8 @@
bool underscan_supported_ = false;
HWScanSupport scan_support_;
std::map<LayerBufferS3DFormat, HWS3DMode> s3d_format_to_mode_;
- std::vector<HWEvent> event_list_ = { HWEvent::VSYNC, HWEvent::IDLE_NOTIFY, HWEvent::EXIT,
- HWEvent::CEC_READ_MESSAGE };
- uint32_t current_refresh_rate_ = 0;
+ std::vector<HWEvent> event_list_ = { HWEvent::VSYNC, HWEvent::IDLE_NOTIFY, HWEvent::EXIT
+ };
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/display_primary.cpp b/msm8909/sdm/libs/core/display_primary.cpp
similarity index 86%
rename from sdm845/sdm/libs/core/display_primary.cpp
rename to msm8909/sdm/libs/core/display_primary.cpp
index 53a4fd9..af21297 100644
--- a/sdm845/sdm/libs/core/display_primary.cpp
+++ b/msm8909/sdm/libs/core/display_primary.cpp
@@ -77,8 +77,6 @@
HWInterface::Destroy(hw_intf_);
}
- current_refresh_rate_ = hw_panel_info_.max_fps;
-
return error;
}
@@ -89,32 +87,6 @@
uint32_t new_mixer_height = 0;
uint32_t display_width = display_attributes_.x_pixels;
uint32_t display_height = display_attributes_.y_pixels;
- bool needs_hv_flip = hw_panel_info_.panel_orientation.flip_horizontal &&
- hw_panel_info_.panel_orientation.flip_vertical;
- LayerRect src_domain = {};
- LayerTransform panel_transform = {};
- DisplayConfigVariableInfo variable_info = {};
-
- if (needs_hv_flip) {
- DisplayBase::GetFrameBufferConfig(&variable_info);
- src_domain.right = variable_info.x_pixels;
- src_domain.bottom = variable_info.y_pixels;
- panel_transform.flip_horizontal = hw_panel_info_.panel_orientation.flip_horizontal;
- panel_transform.flip_vertical = hw_panel_info_.panel_orientation.flip_vertical;
-
- for (Layer *layer : layer_stack->layers) {
- // Modify destination based on panel flip
- TransformHV(src_domain, layer->dst_rect, panel_transform, &layer->dst_rect);
-
- if (layer->flags.solid_fill) {
- continue;
- }
-
- layer->transform.flip_horizontal ^= (hw_panel_info_.panel_orientation.flip_horizontal);
- layer->transform.flip_vertical ^= (hw_panel_info_.panel_orientation.flip_vertical);
- // TODO(user): Check how to handle rotation, if panel has rotation.
- }
- }
if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
error = ReconfigureMixer(new_mixer_width, new_mixer_height);
@@ -264,7 +236,7 @@
return error;
}
-DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!active_ || !hw_panel_info_.dynamic_fps) {
@@ -276,21 +248,11 @@
return kErrorParameters;
}
- if (handle_idle_timeout_ && !final_rate) {
- refresh_rate = hw_panel_info_.min_fps;
+ DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
+ if (error != kErrorNone) {
+ return error;
}
- if ((current_refresh_rate_ != refresh_rate) || handle_idle_timeout_) {
- DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
- if (error != kErrorNone) {
- return error;
- }
- }
-
- // On success, set current refresh rate to new refresh rate
- current_refresh_rate_ = refresh_rate;
- handle_idle_timeout_ = false;
-
return DisplayBase::ReconfigureDisplay();
}
@@ -305,14 +267,15 @@
}
void DisplayPrimary::IdleTimeout() {
- handle_idle_timeout_ = true;
event_handler_->Refresh();
comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
+ event_handler_->HandleEvent(kIdleTimeout);
}
void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
+ event_handler_->HandleEvent(kThermalEvent);
}
void DisplayPrimary::IdlePowerCollapse() {
diff --git a/sdm845/sdm/libs/core/display_primary.h b/msm8909/sdm/libs/core/display_primary.h
similarity index 93%
copy from sdm845/sdm/libs/core/display_primary.h
copy to msm8909/sdm/libs/core/display_primary.h
index 314964a..7cb20e5 100644
--- a/sdm845/sdm/libs/core/display_primary.h
+++ b/msm8909/sdm/libs/core/display_primary.h
@@ -28,7 +28,6 @@
#include <vector>
#include "display_base.h"
-#include "dump_impl.h"
#include "hw_events_interface.h"
namespace sdm {
@@ -49,7 +48,7 @@
virtual void SetIdleTimeoutMs(uint32_t active_ms);
virtual DisplayError SetDisplayMode(uint32_t mode);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate);
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
virtual DisplayError SetPanelBrightness(int level);
virtual DisplayError GetPanelBrightness(int *level);
virtual DisplayError CachePanelBrightness(int level);
@@ -59,7 +58,6 @@
virtual DisplayError Blank(bool blank) { return kErrorNone; }
virtual void IdleTimeout();
virtual void ThermalEvent(int64_t thermal_level);
- virtual void CECMessage(char *message) { }
virtual void IdlePowerCollapse();
private:
@@ -69,8 +67,6 @@
HWEvent::SHOW_BLANK_EVENT, HWEvent::THERMAL_LEVEL, HWEvent::IDLE_POWER_COLLAPSE };
bool avr_prop_disabled_ = false;
bool switch_to_cmd_ = false;
- bool handle_idle_timeout_ = false;
- uint32_t current_refresh_rate_ = 0;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/display_virtual.cpp b/msm8909/sdm/libs/core/display_virtual.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/display_virtual.cpp
rename to msm8909/sdm/libs/core/display_virtual.cpp
diff --git a/sdm845/sdm/libs/core/display_virtual.h b/msm8909/sdm/libs/core/display_virtual.h
similarity index 96%
copy from sdm845/sdm/libs/core/display_virtual.h
copy to msm8909/sdm/libs/core/display_virtual.h
index 185366c..ad0aecb 100644
--- a/sdm845/sdm/libs/core/display_virtual.h
+++ b/msm8909/sdm/libs/core/display_virtual.h
@@ -27,7 +27,6 @@
#include <private/hw_info_types.h>
#include "display_base.h"
-#include "dump_impl.h"
namespace sdm {
@@ -53,7 +52,7 @@
virtual DisplayError SetVSyncState(bool enable) {
return kErrorNotSupported;
}
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate) {
return kErrorNotSupported;
}
virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height) {
diff --git a/sdm845/sdm/libs/core/drm/hw_color_manager_drm.cpp b/msm8909/sdm/libs/core/drm/hw_color_manager_drm.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/drm/hw_color_manager_drm.cpp
rename to msm8909/sdm/libs/core/drm/hw_color_manager_drm.cpp
diff --git a/sdm845/sdm/libs/core/drm/hw_color_manager_drm.h b/msm8909/sdm/libs/core/drm/hw_color_manager_drm.h
similarity index 100%
rename from sdm845/sdm/libs/core/drm/hw_color_manager_drm.h
rename to msm8909/sdm/libs/core/drm/hw_color_manager_drm.h
diff --git a/sdm845/sdm/libs/core/drm/hw_device_drm.cpp b/msm8909/sdm/libs/core/drm/hw_device_drm.cpp
similarity index 84%
copy from sdm845/sdm/libs/core/drm/hw_device_drm.cpp
copy to msm8909/sdm/libs/core/drm/hw_device_drm.cpp
index 1028663..400856c 100644
--- a/sdm845/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/msm8909/sdm/libs/core/drm/hw_device_drm.cpp
@@ -48,7 +48,6 @@
#include <utils/debug.h>
#include <utils/formats.h>
#include <utils/sys.h>
-#include <drm/sde_drm.h>
#include <private/color_params.h>
#include <algorithm>
@@ -93,7 +92,6 @@
using sde_drm::DRMSrcConfig;
using sde_drm::DRMOps;
using sde_drm::DRMTopology;
-using sde_drm::DRMPowerMode;
namespace sdm {
@@ -216,6 +214,14 @@
}
void HWDeviceDRM::Registry::RegisterCurrent(HWLayers *hw_layers) {
+ DRMMaster *master = nullptr;
+ DRMMaster::GetInstance(&master);
+
+ if (!master) {
+ DLOGE("Failed to acquire DRM Master instance");
+ return;
+ }
+
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
@@ -229,41 +235,28 @@
input_buffer = &hw_rotator_session->output_buffer;
}
- MapBufferToFbId(input_buffer);
- }
-}
-
-void HWDeviceDRM::Registry::MapBufferToFbId(LayerBuffer* buffer) {
- int fd = buffer->planes[0].fd;
- DRMMaster *master = nullptr;
- DRMMaster::GetInstance(&master);
-
- if (!master) {
- DLOGE("Failed to acquire DRM Master instance");
- return;
- }
-
- if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
- AllocatedBufferInfo buf_info{};
- DRMBuffer layout{};
- buf_info.fd = layout.fd = fd;
- buf_info.aligned_width = layout.width = buffer->width;
- buf_info.aligned_height = layout.height = buffer->height;
- buf_info.format = buffer->format;
- GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
- buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
- &layout.num_planes);
- uint32_t fb_id = 0;
- int ret = master->CreateFbId(layout, &fb_id);
- if (ret < 0) {
- DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
- layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
- errno);
- } else {
- hashmap_[current_index_][fd] = fb_id;
+ int fd = input_buffer->planes[0].fd;
+ if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
+ AllocatedBufferInfo buf_info {};
+ DRMBuffer layout {};
+ buf_info.fd = layout.fd = fd;
+ buf_info.aligned_width = layout.width = input_buffer->width;
+ buf_info.aligned_height = layout.height = input_buffer->height;
+ buf_info.format = input_buffer->format;
+ GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
+ buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
+ &layout.num_planes);
+ uint32_t fb_id = 0;
+ int ret = master->CreateFbId(layout, &fb_id);
+ if (ret < 0) {
+ DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
+ layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
+ errno);
+ } else {
+ hashmap_[current_index_][fd] = fb_id;
+ }
}
}
- return;
}
void HWDeviceDRM::Registry::UnregisterNext() {
@@ -305,42 +298,50 @@
: hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
registry_(buffer_allocator) {
device_type_ = kDevicePrimary;
- disp_type_ = DRMDisplayType::PERIPHERAL;
device_name_ = "Peripheral Display";
hw_info_intf_ = hw_info_intf;
}
DisplayError HWDeviceDRM::Init() {
- default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
+ DRMLibLoader *drm_lib = DRMLibLoader::GetInstance();
+ if (drm_lib == nullptr) {
+ DLOGE("Failed to load DRM Lib");
+ return kErrorResources;
+ }
+ default_mode_ = (drm_lib->IsLoaded() == false);
if (!default_mode_) {
DRMMaster *drm_master = {};
+ int dev_fd = -1;
DRMMaster::GetInstance(&drm_master);
- drm_master->GetHandle(&dev_fd_);
- DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd_, &drm_mgr_intf_);
- if (drm_mgr_intf_->RegisterDisplay(disp_type_, &token_)) {
- DLOGE("RegisterDisplay failed for display %d", disp_type_);
+ drm_master->GetHandle(&dev_fd);
+ drm_lib->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
+ if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::PERIPHERAL, &token_)) {
+ DLOGE("RegisterDisplay failed");
return kErrorResources;
}
+
drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
InitializeConfigs();
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, ¤t_mode_);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET, token_.crtc_id, 1);
+
+ // TODO(user): Enable this and remove the one in SetupAtomic() onces underruns are fixed
+ // drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
// Commit to setup pipeline with mode, which then tells us the topology etc
-
- if (!deferred_initialize_) {
- if (drm_atomic_intf_->Commit(true /* synchronous */)) {
- DRM_LOGI("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id,
- token_.conn_id, device_name_);
- return kErrorResources;
- }
- // Reload connector info for updated info after 1st commit
-
- drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+ if (drm_atomic_intf_->Commit(true /* synchronous */)) {
+ DLOGE("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id, token_.conn_id,
+ device_name_);
+ return kErrorResources;
}
+
+ // Reload connector info for updated info after 1st commit
+ drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+ DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_);
}
+
PopulateDisplayAttributes();
PopulateHWPanelInfo();
UpdateMixerAttributes();
@@ -434,30 +435,23 @@
display_attributes_.x_pixels / 2;
}
- hw_panel_info_.partial_update = connector_info_.num_roi;
- hw_panel_info_.left_roi_count = UINT32(connector_info_.num_roi);
- hw_panel_info_.right_roi_count = UINT32(connector_info_.num_roi);
- hw_panel_info_.left_align = connector_info_.xstart;
- hw_panel_info_.top_align = connector_info_.ystart;
- hw_panel_info_.width_align = connector_info_.walign;
- hw_panel_info_.height_align = connector_info_.halign;
- hw_panel_info_.min_roi_width = connector_info_.wmin;
- hw_panel_info_.min_roi_height = connector_info_.hmin;
- hw_panel_info_.needs_roi_merge = connector_info_.roi_merge;
+ hw_panel_info_.partial_update = 0;
+ hw_panel_info_.left_align = 0;
+ hw_panel_info_.width_align = 0;
+ hw_panel_info_.top_align = 0;
+ hw_panel_info_.height_align = 0;
+ hw_panel_info_.min_roi_width = 0;
+ hw_panel_info_.min_roi_height = 0;
+ hw_panel_info_.needs_roi_merge = 0;
hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
hw_panel_info_.min_fps = 60;
hw_panel_info_.max_fps = 60;
hw_panel_info_.is_primary_panel = connector_info_.is_primary;
hw_panel_info_.is_pluggable = 0;
- // no supprt for 90 rotation only flips or 180 supported
- hw_panel_info_.panel_orientation.rotation = 0;
- hw_panel_info_.panel_orientation.flip_horizontal =
- (connector_info_.panel_orientation == DRMRotation::FLIP_H) ||
- (connector_info_.panel_orientation == DRMRotation::ROT_180);
- hw_panel_info_.panel_orientation.flip_vertical =
- (connector_info_.panel_orientation == DRMRotation::FLIP_V) ||
- (connector_info_.panel_orientation == DRMRotation::ROT_180);
+ if (!default_mode_) {
+ hw_panel_info_.needs_roi_merge = (connector_info_.topology == DRMTopology::DUAL_LM_MERGE);
+ }
GetHWDisplayPortAndMode();
GetHWPanelMaxBrightness();
@@ -574,35 +568,18 @@
DisplayError HWDeviceDRM::PowerOn() {
DTRACE_SCOPED();
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
- int ret = drm_atomic_intf_->Commit(false /* synchronous */);
- if (ret) {
- DLOGE("%s failed with error %d", __FUNCTION__, ret);
- return kErrorHardware;
- }
return kErrorNone;
}
DisplayError HWDeviceDRM::PowerOff() {
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
- int ret = drm_atomic_intf_->Commit(false /* synchronous */);
- if (ret) {
- DLOGE("%s failed with error %d", __FUNCTION__, ret);
- return kErrorHardware;
- }
return kErrorNone;
}
DisplayError HWDeviceDRM::Doze() {
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
return kErrorNone;
}
DisplayError HWDeviceDRM::DozeSuspend() {
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id,
- DRMPowerMode::DOZE_SUSPEND);
return kErrorNone;
}
@@ -618,34 +595,6 @@
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
- // TODO(user): Once destination scalar is enabled we can always send ROIs if driver allows
- if (hw_panel_info_.partial_update) {
- const int kNumMaxROIs = 4;
- DRMRect crtc_rects[kNumMaxROIs] = {{0, 0, mixer_attributes_.width, mixer_attributes_.height}};
- DRMRect conn_rects[kNumMaxROIs] = {{0, 0, display_attributes_.x_pixels,
- display_attributes_.y_pixels}};
-
- for (uint32_t i = 0; i < hw_layer_info.left_frame_roi.size(); i++) {
- auto &roi = hw_layer_info.left_frame_roi.at(i);
- // TODO(user): In multi PU, stitch ROIs vertically adjacent and upate plane destination
- crtc_rects[i].left = UINT32(roi.left);
- crtc_rects[i].right = UINT32(roi.right);
- crtc_rects[i].top = UINT32(roi.top);
- crtc_rects[i].bottom = UINT32(roi.bottom);
- // TODO(user): In Dest scaler + PU, populate from HWDestScaleInfo->panel_roi
- conn_rects[i].left = UINT32(roi.left);
- conn_rects[i].right = UINT32(roi.right);
- conn_rects[i].top = UINT32(roi.top);
- conn_rects[i].bottom = UINT32(roi.bottom);
- }
-
- uint32_t num_rects = std::max(1u, static_cast<uint32_t>(hw_layer_info.left_frame_roi.size()));
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id,
- num_rects, crtc_rects);
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id,
- num_rects, conn_rects);
- }
-
for (uint32_t i = 0; i < hw_layer_count; i++) {
Layer &layer = hw_layer_info.hw_layers.at(i);
LayerBuffer *input_buffer = &layer.input_buffer;
@@ -715,12 +664,8 @@
}
}
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, hw_layers->clock_hz);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, hw_layers->ab_bps);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, hw_layers->ib_bps);
-
- DLOGI_IF(kTagDriverConfig, "System: clock=%d Hz, ab=%llu Bps ib=%llu Bps", hw_layers->clock_hz,
- hw_layers->ab_bps, hw_layers->ib_bps);
+ // TODO(user): Remove this and enable the one in Init() onces underruns are fixed
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
}
}
@@ -811,7 +756,7 @@
int ret = drm_atomic_intf_->Commit(false /* synchronous */);
if (ret) {
- DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id);
+ DLOGE("%s failed with error %d", __FUNCTION__, ret);
return kErrorHardware;
}
@@ -887,6 +832,7 @@
DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
struct DRMPPFeatureInfo info = {};
+
for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) {
memset(&info, 0, sizeof(struct DRMPPFeatureInfo));
info.id = HWColorManagerDrm::ToDrmFeatureId(i);
@@ -929,7 +875,7 @@
}
DisplayError HWDeviceDRM::SetVSyncState(bool enable) {
- return kErrorNotSupported;
+ return kErrorNone;
}
void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {}
diff --git a/sdm845/sdm/libs/core/drm/hw_device_drm.h b/msm8909/sdm/libs/core/drm/hw_device_drm.h
similarity index 93%
rename from sdm845/sdm/libs/core/drm/hw_device_drm.h
rename to msm8909/sdm/libs/core/drm/hw_device_drm.h
index ad7a3e3..cc2ae7b 100644
--- a/sdm845/sdm/libs/core/drm/hw_device_drm.h
+++ b/msm8909/sdm/libs/core/drm/hw_device_drm.h
@@ -49,7 +49,7 @@
class HWDeviceDRM : public HWInterface {
public:
- HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ explicit HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
HWInfoInterface *hw_info_intf);
virtual ~HWDeviceDRM() {}
virtual DisplayError Init();
@@ -75,7 +75,6 @@
virtual DisplayError Flush();
virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
- // This API is no longer supported, expectation is to call the correct API on HWEvents
virtual DisplayError SetVSyncState(bool enable);
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
@@ -93,7 +92,6 @@
virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
- virtual void InitializeConfigs();
enum {
kHWEventVSync,
@@ -116,6 +114,7 @@
void ResetDisplayParams();
bool EnableHotPlugDetection(int enable);
void UpdateMixerAttributes();
+ void InitializeConfigs();
void SetBlending(const LayerBlending &source, sde_drm::DRMBlendType *target);
void SetSrcConfig(const LayerBuffer &input_buffer, uint32_t *config);
void SetRect(const LayerRect &source, sde_drm::DRMRect *target);
@@ -132,13 +131,11 @@
void UnregisterNext();
// Call on display disconnect to release all gem handles and fb_ids
void Clear();
- // Maps given fd to FB ID
- void MapBufferToFbId(LayerBuffer* buffer);
// Finds an fb_id corresponding to an fd in current map
uint32_t GetFbId(int fd);
private:
- static const int kCycleDelay = 3; // N cycle delay before destroy
+ static const int kCycleDelay = 1; // N cycle delay before destroy
// fd to fb_id map. fd is used as key only for a single draw cycle between
// prepare and commit. It should not be used for caching in future due to fd recycling
std::unordered_map<int, uint32_t> hashmap_[kCycleDelay] {};
@@ -146,30 +143,24 @@
BufferAllocator *buffer_allocator_ = {};
};
- protected:
- const char *device_name_ = {};
- bool deferred_initialize_ = false;
- sde_drm::DRMDisplayType disp_type_ = {};
- HWInfoInterface *hw_info_intf_ = {};
- BufferSyncHandler *buffer_sync_handler_ = {};
- int dev_fd_ = -1;
- Registry registry_;
- sde_drm::DRMDisplayToken token_ = {};
HWResourceInfo hw_resource_ = {};
HWPanelInfo hw_panel_info_ = {};
+ HWInfoInterface *hw_info_intf_ = {};
+ BufferSyncHandler *buffer_sync_handler_ = {};
HWDeviceType device_type_ = {};
+ const char *device_name_ = {};
+ bool synchronous_commit_ = false;
+ HWDisplayAttributes display_attributes_ = {};
+ HWMixerAttributes mixer_attributes_ = {};
sde_drm::DRMManagerInterface *drm_mgr_intf_ = {};
sde_drm::DRMAtomicReqInterface *drm_atomic_intf_ = {};
- sde_drm::DRMConnectorInfo connector_info_ = {};
+ sde_drm::DRMDisplayToken token_ = {};
drmModeModeInfo current_mode_ = {};
- HWDisplayAttributes display_attributes_ = {};
-
- private:
- bool synchronous_commit_ = false;
- HWMixerAttributes mixer_attributes_ = {};
bool default_mode_ = false;
+ sde_drm::DRMConnectorInfo connector_info_ = {};
std::string interface_str_ = "DSI";
HWScaleDRM *hw_scale_ = {};
+ Registry registry_;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/drm/hw_events_drm.cpp b/msm8909/sdm/libs/core/drm/hw_events_drm.cpp
similarity index 91%
rename from sdm845/sdm/libs/core/drm/hw_events_drm.cpp
rename to msm8909/sdm/libs/core/drm/hw_events_drm.cpp
index cea76fc..9c9023a 100644
--- a/sdm845/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/msm8909/sdm/libs/core/drm/hw_events_drm.cpp
@@ -81,7 +81,6 @@
Sys::pread_(poll_fds_[i].fd, data, kMaxStringLength, 0);
} break;
case HWEvent::IDLE_NOTIFY:
- case HWEvent::CEC_READ_MESSAGE:
case HWEvent::SHOW_BLANK_EVENT:
case HWEvent::THERMAL_LEVEL:
case HWEvent::IDLE_POWER_COLLAPSE:
@@ -103,9 +102,6 @@
case HWEvent::IDLE_NOTIFY:
event_data.event_parser = &HWEventsDRM::HandleIdleTimeout;
break;
- case HWEvent::CEC_READ_MESSAGE:
- event_data.event_parser = &HWEventsDRM::HandleCECMessage;
- break;
case HWEvent::EXIT:
event_data.event_parser = &HWEventsDRM::HandleThreadExit;
break;
@@ -160,30 +156,7 @@
DisplayError HWEventsDRM::Deinit() {
exit_threads_ = true;
Sys::pthread_cancel_(event_thread_);
- WakeUpEventThread();
- pthread_join(event_thread_, NULL);
- CloseFds();
- return kErrorNone;
-}
-
-DisplayError HWEventsDRM::SetEventState(HWEvent event, bool enable, void *arg) {
- switch (event) {
- case HWEvent::VSYNC:
- vsync_enabled_ = enable;
- if (enable) {
- WakeUpEventThread();
- }
- break;
- default:
- DLOGE("Event not supported");
- return kErrorNotSupported;
- }
-
- return kErrorNone;
-}
-
-void HWEventsDRM::WakeUpEventThread() {
for (uint32_t i = 0; i < event_data_list_.size(); i++) {
if (event_data_list_[i].event_type == HWEvent::EXIT) {
uint64_t exit_value = 1;
@@ -192,9 +165,13 @@
DLOGW("Error triggering exit fd (%d). write size = %d, error = %s", poll_fds_[i].fd,
write_size, strerror(errno));
}
- break;
}
}
+
+ pthread_join(event_thread_, NULL);
+ CloseFds();
+
+ return kErrorNone;
}
DisplayError HWEventsDRM::CloseFds() {
@@ -208,7 +185,6 @@
poll_fds_[i].fd = -1;
break;
case HWEvent::IDLE_NOTIFY:
- case HWEvent::CEC_READ_MESSAGE:
case HWEvent::SHOW_BLANK_EVENT:
case HWEvent::THERMAL_LEVEL:
case HWEvent::IDLE_POWER_COLLAPSE:
@@ -236,7 +212,7 @@
setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent);
while (!exit_threads_) {
- if (vsync_enabled_ && RegisterVSync() != kErrorNone) {
+ if (RegisterVSync() != kErrorNone) {
pthread_exit(0);
return nullptr;
}
@@ -260,7 +236,6 @@
}
break;
case HWEvent::IDLE_NOTIFY:
- case HWEvent::CEC_READ_MESSAGE:
case HWEvent::SHOW_BLANK_EVENT:
case HWEvent::THERMAL_LEVEL:
case HWEvent::IDLE_POWER_COLLAPSE:
@@ -316,10 +291,6 @@
event_handler_->IdleTimeout();
}
-void HWEventsDRM::HandleCECMessage(char *data) {
- event_handler_->CECMessage(data);
-}
-
void HWEventsDRM::HandleIdlePowerCollapse(char *data) {
event_handler_->IdlePowerCollapse();
}
diff --git a/sdm845/sdm/libs/core/drm/hw_events_drm.h b/msm8909/sdm/libs/core/drm/hw_events_drm.h
similarity index 94%
rename from sdm845/sdm/libs/core/drm/hw_events_drm.h
rename to msm8909/sdm/libs/core/drm/hw_events_drm.h
index 41050c7..f114b1f 100644
--- a/sdm845/sdm/libs/core/drm/hw_events_drm.h
+++ b/msm8909/sdm/libs/core/drm/hw_events_drm.h
@@ -48,7 +48,6 @@
virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
const vector<HWEvent> &event_list);
virtual DisplayError Deinit();
- virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr);
private:
static const int kMaxStringLength = 1024;
@@ -67,13 +66,11 @@
void *DisplayEventHandler();
void HandleVSync(char *data);
void HandleIdleTimeout(char *data);
- void HandleCECMessage(char *data);
void HandleThreadExit(char *data) {}
void HandleThermal(char *data) {}
void HandleBlank(char *data) {}
void HandleIdlePowerCollapse(char *data);
void PopulateHWEventData(const vector<HWEvent> &event_list);
- void WakeUpEventThread();
DisplayError SetEventParser();
DisplayError InitializePollFd();
DisplayError CloseFds();
@@ -86,7 +83,6 @@
std::string event_thread_name_ = "SDM_EventThread";
bool exit_threads_ = false;
uint32_t vsync_index_ = 0;
- bool vsync_enabled_ = true;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/drm/hw_info_drm.cpp b/msm8909/sdm/libs/core/drm/hw_info_drm.cpp
similarity index 90%
copy from sdm845/sdm/libs/core/drm/hw_info_drm.cpp
copy to msm8909/sdm/libs/core/drm/hw_info_drm.cpp
index 6258d73..c59d9db 100644
--- a/sdm845/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/msm8909/sdm/libs/core/drm/hw_info_drm.cpp
@@ -85,17 +85,18 @@
class DRMLoggerImpl : public DRMLogger {
public:
-#define PRINTLOG(method, format, buf) \
+#define PRINTLOG(tag, method, format, buf) \
va_list list; \
va_start(list, format); \
vsnprintf(buf, sizeof(buf), format, list); \
va_end(list); \
- Debug::Get()->method(kTagNone, "%s", buf);
+ Debug::Get()->method(tag, "%s", buf);
- void Error(const char *format, ...) { PRINTLOG(Error, format, buf_); }
- void Warning(const char *format, ...) { PRINTLOG(Warning, format, buf_); }
- void Info(const char *format, ...) { PRINTLOG(Info, format, buf_); }
- void Debug(const char *format, ...) { PRINTLOG(Debug, format, buf_); }
+ void Error(const char *format, ...) { PRINTLOG(kTagNone, Error, format, buf_); }
+ void Warning(const char *format, ...) { PRINTLOG(kTagDriverConfig, Warning, format, buf_); }
+ void Info(const char *format, ...) { PRINTLOG(kTagDriverConfig, Info, format, buf_); }
+ void Debug(const char *format, ...) { PRINTLOG(kTagDriverConfig, Debug, format, buf_); }
+ void Verbose(const char *format, ...) { PRINTLOG(kTagDriverConfig, Verbose, format, buf_); }
private:
char buf_[1024] = {};
@@ -105,7 +106,12 @@
HWInfoDRM::HWInfoDRM() {
DRMLogger::Set(new DRMLoggerImpl());
- default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
+ drm_lib = DRMLibLoader::GetInstance();
+ if (drm_lib == nullptr) {
+ DLOGE("Failed to load DRM Library");
+ return;
+ }
+ default_mode_ = (drm_lib->IsLoaded() == false);
if (!default_mode_) {
DRMMaster *drm_master = {};
int dev_fd = -1;
@@ -115,27 +121,32 @@
return;
}
drm_master->GetHandle(&dev_fd);
- DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
+ drm_lib->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
}
}
HWInfoDRM::~HWInfoDRM() {
- delete hw_resource_;
- hw_resource_ = nullptr;
+ if (hw_resource_ != nullptr) {
+ delete hw_resource_;
+ hw_resource_ = nullptr;
+ }
if (drm_mgr_intf_) {
- DRMLibLoader::GetInstance()->FuncDestroyDRMManager()();
+ if (drm_lib != nullptr) {
+ drm_lib->FuncDestroyDRMManager()();
+ }
drm_mgr_intf_ = nullptr;
}
- DRMLibLoader::Destroy();
+ drm_lib->Destroy();
+ drm_lib = nullptr;
DRMMaster::DestroyInstance();
}
DisplayError HWInfoDRM::GetDynamicBWLimits(HWResourceInfo *hw_resource) {
HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
for (int index = 0; index < kBwModeMax; index++) {
- bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
+ bw_info->total_bw_limit[index] = UINT32(hw_resource->max_bandwidth_low);
bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
}
@@ -164,13 +175,14 @@
hw_resource->linear_factor = 1;
hw_resource->scale_factor = 1;
hw_resource->extra_fudge_factor = 2;
- hw_resource->amortizable_threshold = 25;
+ hw_resource->amortizable_threshold = 0;
hw_resource->system_overhead_lines = 0;
hw_resource->hw_dest_scalar_info.count = 0;
hw_resource->hw_dest_scalar_info.max_scale_up = 0;
hw_resource->hw_dest_scalar_info.max_input_width = 0;
hw_resource->hw_dest_scalar_info.max_output_width = 0;
hw_resource->is_src_split = true;
+ hw_resource->perf_calc = false;
hw_resource->has_dyn_bw_support = false;
hw_resource->has_qseed3 = false;
hw_resource->has_concurrent_writeback = false;
@@ -253,33 +265,6 @@
hw_resource->num_blending_stages = info.max_blend_stages;
hw_resource->smart_dma_rev = (info.smart_dma_rev == sde_drm::SmartDMARevision::V2) ?
SmartDMARevision::V2 : SmartDMARevision::V1;
- hw_resource->ib_fudge_factor = info.ib_fudge_factor;
- hw_resource->hw_dest_scalar_info.prefill_lines = info.dest_scale_prefill_lines;
- hw_resource->undersized_prefill_lines = info.undersized_prefill_lines;
- hw_resource->macrotile_factor = info.macrotile_prefill_lines;
- hw_resource->macrotile_nv12_factor = info.nv12_prefill_lines;
- hw_resource->linear_factor = info.linear_prefill_lines;
- hw_resource->scale_factor = info.downscale_prefill_lines;
- hw_resource->extra_fudge_factor = info.extra_prefill_lines;
- hw_resource->amortizable_threshold = info.amortized_threshold;
- hw_resource->max_bandwidth_low = info.max_bandwidth_low / kKiloUnit;
- hw_resource->max_bandwidth_high = info.max_bandwidth_high / kKiloUnit;
- hw_resource->max_sde_clk = info.max_sde_clk;
-
- std::vector<LayerBufferFormat> sdm_format;
- for (auto &it : info.comp_ratio_rt_map) {
- std::pair<uint32_t, uint64_t> drm_format = it.first;
- GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
- hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
- sdm_format.clear();
- }
-
- for (auto &it : info.comp_ratio_nrt_map) {
- std::pair<uint32_t, uint64_t> drm_format = it.first;
- GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
- hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
- sdm_format.clear();
- }
}
void HWInfoDRM::GetHWPlanesInfo(HWResourceInfo *hw_resource) {
@@ -331,13 +316,12 @@
hw_resource->max_scale_down = info.max_downscale;
hw_resource->max_scale_up = info.max_upscale;
hw_resource->has_decimation = info.max_horizontal_deci > 1 && info.max_vertical_deci > 1;
- hw_resource->max_pipe_bw = info.max_pipe_bandwidth / kKiloUnit;
}
void HWInfoDRM::PopulateSupportedFmts(HWSubBlockType sub_blk_type,
const sde_drm::DRMPlaneTypeInfo &info,
HWResourceInfo *hw_resource) {
- vector<LayerBufferFormat> sdm_formats = {};
+ vector<LayerBufferFormat> sdm_formats;
FormatsMap &fmts_map = hw_resource->supported_formats_map;
if (fmts_map.find(sub_blk_type) == fmts_map.end()) {
@@ -351,7 +335,7 @@
void HWInfoDRM::GetWBInfo(HWResourceInfo *hw_resource) {
HWSubBlockType sub_blk_type = kHWWBIntfOutput;
- vector<LayerBufferFormat> supported_sdm_formats = {};
+ vector<LayerBufferFormat> supported_sdm_formats;
sde_drm::DRMDisplayToken token;
// Fake register
diff --git a/sdm845/sdm/libs/core/drm/hw_info_drm.h b/msm8909/sdm/libs/core/drm/hw_info_drm.h
similarity index 97%
copy from sdm845/sdm/libs/core/drm/hw_info_drm.h
copy to msm8909/sdm/libs/core/drm/hw_info_drm.h
index 5d92c41..6194a4b 100644
--- a/sdm845/sdm/libs/core/drm/hw_info_drm.h
+++ b/msm8909/sdm/libs/core/drm/hw_info_drm.h
@@ -36,6 +36,7 @@
#include <private/hw_info_types.h>
#include <bitset>
#include <vector>
+#include <drm_lib_loader.h>
#include "hw_info_interface.h"
@@ -71,9 +72,9 @@
// TODO(user): Read Mdss version from the driver
static const int kHWMdssVersion5 = 500; // MDSS_V5
static const int kMaxStringLength = 1024;
- static const int kKiloUnit = 1000;
-
static HWResourceInfo *hw_resource_;
+
+ drm_utils::DRMLibLoader *drm_lib = nullptr;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/drm/hw_scale_drm.cpp b/msm8909/sdm/libs/core/drm/hw_scale_drm.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/drm/hw_scale_drm.cpp
rename to msm8909/sdm/libs/core/drm/hw_scale_drm.cpp
diff --git a/sdm845/sdm/libs/core/drm/hw_scale_drm.h b/msm8909/sdm/libs/core/drm/hw_scale_drm.h
similarity index 100%
rename from sdm845/sdm/libs/core/drm/hw_scale_drm.h
rename to msm8909/sdm/libs/core/drm/hw_scale_drm.h
diff --git a/msm8909/sdm/libs/core/fb/hw_color_manager.cpp b/msm8909/sdm/libs/core/fb/hw_color_manager.cpp
new file mode 100644
index 0000000..051d5cb
--- /dev/null
+++ b/msm8909/sdm/libs/core/fb/hw_color_manager.cpp
@@ -0,0 +1,188 @@
+/*
+* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <ctype.h>
+#include <math.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/prctl.h>
+#include <linux/msm_mdp.h>
+#include <utils/constants.h>
+#include <utils/debug.h>
+#include "hw_color_manager.h"
+
+#define __CLASS__ "HWColorManager"
+
+namespace sdm {
+
+DisplayError (*HWColorManager::SetFeature[])(const PPFeatureInfo &, msmfb_mdp_pp *) = {
+ [kGlobalColorFeaturePcc] = &HWColorManager::SetPCC,
+ [kGlobalColorFeatureIgc] = &HWColorManager::SetIGC,
+ [kGlobalColorFeaturePgc] = &HWColorManager::SetPGC,
+ [kMixerColorFeatureGc] = &HWColorManager::SetMixerGC,
+ [kGlobalColorFeaturePaV2] = &HWColorManager::SetPAV2,
+ [kGlobalColorFeatureDither] = &HWColorManager::SetDither,
+ [kGlobalColorFeatureGamut] = &HWColorManager::SetGamut,
+ [kGlobalColorFeaturePADither] = &HWColorManager::SetPADither,
+ [kGlobalColorFeatureCsc] = &HWColorManager::SetCSCLegacy,
+};
+
+DisplayError HWColorManager::SetPCC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
+ DisplayError ret = kErrorNone;
+
+ kernel_params->op = mdp_op_pcc_cfg;
+ kernel_params->data.pcc_cfg_data.version = feature.feature_version_;
+ kernel_params->data.pcc_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
+ kernel_params->data.pcc_cfg_data.ops = feature.enable_flags_;
+ kernel_params->data.pcc_cfg_data.cfg_payload = feature.GetConfigData();
+ DLOGV_IF(kTagQDCM, "kernel params version = %d, block = %d, flags = %d",
+ kernel_params->data.pcc_cfg_data.version, kernel_params->data.pcc_cfg_data.block,
+ kernel_params->data.pcc_cfg_data.ops);
+
+ return ret;
+}
+
+DisplayError HWColorManager::SetIGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
+ DisplayError ret = kErrorNone;
+
+ kernel_params->op = mdp_op_lut_cfg;
+ kernel_params->data.lut_cfg_data.lut_type = mdp_lut_igc;
+ kernel_params->data.lut_cfg_data.data.igc_lut_data.block =
+ MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
+ kernel_params->data.lut_cfg_data.data.igc_lut_data.version = feature.feature_version_;
+ kernel_params->data.lut_cfg_data.data.igc_lut_data.ops = feature.enable_flags_;
+ kernel_params->data.lut_cfg_data.data.igc_lut_data.cfg_payload = feature.GetConfigData();
+
+ return ret;
+}
+
+DisplayError HWColorManager::SetPGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
+ DisplayError ret = kErrorNone;
+
+ kernel_params->op = mdp_op_lut_cfg;
+ kernel_params->data.lut_cfg_data.lut_type = mdp_lut_pgc;
+ kernel_params->data.lut_cfg_data.data.pgc_lut_data.version = feature.feature_version_;
+ kernel_params->data.lut_cfg_data.data.pgc_lut_data.block =
+ MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
+ kernel_params->data.lut_cfg_data.data.pgc_lut_data.flags = feature.enable_flags_;
+ kernel_params->data.lut_cfg_data.data.pgc_lut_data.cfg_payload = feature.GetConfigData();
+
+ return ret;
+}
+
+DisplayError HWColorManager::SetMixerGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
+ DisplayError ret = kErrorNone;
+
+ kernel_params->op = mdp_op_lut_cfg;
+ kernel_params->data.lut_cfg_data.lut_type = mdp_lut_pgc;
+ kernel_params->data.lut_cfg_data.data.pgc_lut_data.version = feature.feature_version_;
+ kernel_params->data.lut_cfg_data.data.pgc_lut_data.block =
+ (MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_) | MDSS_PP_LM_CFG;
+ kernel_params->data.lut_cfg_data.data.pgc_lut_data.flags = feature.enable_flags_;
+ kernel_params->data.lut_cfg_data.data.pgc_lut_data.cfg_payload = feature.GetConfigData();
+ return ret;
+}
+
+DisplayError HWColorManager::SetPAV2(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
+ DisplayError ret = kErrorNone;
+
+ kernel_params->op = mdp_op_pa_v2_cfg;
+ kernel_params->data.pa_v2_cfg_data.version = feature.feature_version_;
+ kernel_params->data.pa_v2_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
+ kernel_params->data.pa_v2_cfg_data.flags = feature.enable_flags_;
+ kernel_params->data.pa_v2_cfg_data.cfg_payload = feature.GetConfigData();
+ DLOGV_IF(kTagQDCM, "kernel params version = %d, block = %d, flags = %d",
+ kernel_params->data.pa_v2_cfg_data.version, kernel_params->data.pa_v2_cfg_data.block,
+ kernel_params->data.pa_v2_cfg_data.flags);
+
+ return ret;
+}
+
+DisplayError HWColorManager::SetDither(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
+ DisplayError ret = kErrorNone;
+
+ kernel_params->op = mdp_op_dither_cfg;
+ kernel_params->data.dither_cfg_data.version = feature.feature_version_;
+ kernel_params->data.dither_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
+ kernel_params->data.dither_cfg_data.flags = feature.enable_flags_;
+ kernel_params->data.dither_cfg_data.cfg_payload = feature.GetConfigData();
+
+ return ret;
+}
+
+DisplayError HWColorManager::SetGamut(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
+ DisplayError ret = kErrorNone;
+
+ kernel_params->op = mdp_op_gamut_cfg;
+ kernel_params->data.gamut_cfg_data.version = feature.feature_version_;
+ kernel_params->data.gamut_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
+ kernel_params->data.gamut_cfg_data.flags = feature.enable_flags_;
+ kernel_params->data.gamut_cfg_data.cfg_payload = feature.GetConfigData();
+
+ return ret;
+}
+
+DisplayError HWColorManager::SetPADither(const PPFeatureInfo &feature,
+ msmfb_mdp_pp *kernel_params) {
+ DisplayError ret = kErrorNone;
+#ifdef PA_DITHER
+ kernel_params->op = mdp_op_pa_dither_cfg;
+ kernel_params->data.dither_cfg_data.version = feature.feature_version_;
+ kernel_params->data.dither_cfg_data.block = MDP_LOGICAL_BLOCK_DISP_0 + feature.disp_id_;
+ kernel_params->data.dither_cfg_data.flags = feature.enable_flags_;
+ kernel_params->data.dither_cfg_data.cfg_payload = feature.GetConfigData();
+#endif
+ return ret;
+}
+
+DisplayError HWColorManager::SetCSCLegacy(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
+ DisplayError ret = kErrorNone;
+
+ kernel_params->op = mdp_op_csc_cfg;
+ kernel_params->data.csc_cfg_data.block = MDP_BLOCK_DMA_P;
+ std::memcpy(&kernel_params->data.csc_cfg_data.csc_data, feature.GetConfigData(),
+ sizeof(mdp_csc_cfg));
+
+ for( int row = 0; row < 3; row++) {
+ DLOGV_IF(kTagQDCM, "kernel mv[%d][0]=0x%x mv[%d][1]=0x%x mv[%d][2]=0x%x\n",
+ row, kernel_params->data.csc_cfg_data.csc_data.csc_mv[row*3 + 0],
+ row, kernel_params->data.csc_cfg_data.csc_data.csc_mv[row*3 + 1],
+ row, kernel_params->data.csc_cfg_data.csc_data.csc_mv[row*3 + 2]);
+ DLOGV_IF(kTagQDCM, "kernel pre_bv[%d]=%x\n", row,
+ kernel_params->data.csc_cfg_data.csc_data.csc_pre_bv[row]);
+ DLOGV_IF(kTagQDCM, "kernel post_bv[%d]=%x\n", row,
+ kernel_params->data.csc_cfg_data.csc_data.csc_post_bv[row]);
+ }
+ return ret;
+}
+
+} // namespace sdm
diff --git a/msm8909/sdm/libs/core/fb/hw_color_manager.h b/msm8909/sdm/libs/core/fb/hw_color_manager.h
new file mode 100644
index 0000000..46e41f5
--- /dev/null
+++ b/msm8909/sdm/libs/core/fb/hw_color_manager.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2015-2017, The Linux Foundataion. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef __HW_COLOR_MANAGER_H__
+#define __HW_COLOR_MANAGER_H__
+
+#include <linux/msm_mdp_ext.h>
+#include <linux/msm_mdp.h>
+
+#include <private/color_params.h>
+
+namespace sdm {
+
+class HWColorManager {
+ public:
+ static DisplayError SetPCC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+ static DisplayError SetIGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+ static DisplayError SetPGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+ static DisplayError SetMixerGC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+ static DisplayError SetPAV2(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+ static DisplayError SetDither(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+ static DisplayError SetGamut(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+ static DisplayError SetPADither(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+ static DisplayError SetCSCLegacy(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
+ static DisplayError (*SetFeature[kMaxNumPPFeatures])(const PPFeatureInfo &feature,
+ msmfb_mdp_pp *kernel_params);
+
+ protected:
+ HWColorManager() {}
+};
+
+} // namespace sdm
+
+#endif // __HW_COLOR_MANAGER_H__
diff --git a/sdm845/sdm/libs/core/fb/hw_device.cpp b/msm8909/sdm/libs/core/fb/hw_device.cpp
similarity index 96%
copy from sdm845/sdm/libs/core/fb/hw_device.cpp
copy to msm8909/sdm/libs/core/fb/hw_device.cpp
index 773845b..491c6cf 100644
--- a/sdm845/sdm/libs/core/fb/hw_device.cpp
+++ b/msm8909/sdm/libs/core/fb/hw_device.cpp
@@ -115,6 +115,10 @@
device_fd_ = -1;
}
+ if (stored_retire_fence >= 0) {
+ Sys::close_(stored_retire_fence);
+ stored_retire_fence = -1;
+ }
return kErrorNone;
}
@@ -189,9 +193,9 @@
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
- DLOGV_IF(kTagDriverConfig, "************************** %s Validate Input ***********************",
+ DLOGD_IF(kTagDriverConfig, "************************** %s Validate Input ***********************",
device_name_);
- DLOGV_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_count);
+ DLOGD_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_count);
mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt;
@@ -208,6 +212,7 @@
HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
bool is_rotator_used = (hw_rotator_session->hw_block_count != 0);
+ bool is_cursor_pipe_used = (hw_layer_info.use_hw_cursor & layer.flags.cursor);
for (uint32_t count = 0; count < 2; count++) {
HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
@@ -246,7 +251,7 @@
#endif
SetRect(pipe_info->src_roi, &mdp_layer.src_rect);
SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
- SetMDPFlags(&layer, is_rotator_used, hw_layer_info.async_cursor_updates, &mdp_layer.flags);
+ SetMDPFlags(&layer, is_rotator_used, is_cursor_pipe_used, &mdp_layer.flags);
SetCSC(layer.input_buffer.color_metadata, &mdp_layer.color_space);
if (pipe_info->flags & kIGC) {
SetIGC(&layer.input_buffer, mdp_layer_count);
@@ -266,11 +271,11 @@
mdp_layer_count++;
- DLOGV_IF(kTagDriverConfig, "******************* Layer[%d] %s pipe Input ******************",
+ DLOGD_IF(kTagDriverConfig, "******************* Layer[%d] %s pipe Input ******************",
i, count ? "Right" : "Left");
- DLOGV_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d", mdp_buffer.width, mdp_buffer.height,
+ DLOGD_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d", mdp_buffer.width, mdp_buffer.height,
mdp_buffer.format);
- DLOGV_IF(kTagDriverConfig, "plane_alpha %d, zorder %d, blending %d, horz_deci %d, "
+ DLOGD_IF(kTagDriverConfig, "plane_alpha %d, zorder %d, blending %d, horz_deci %d, "
"vert_deci %d, pipe_id = 0x%x, mdp_flags 0x%x", mdp_layer.alpha, mdp_layer.z_order,
mdp_layer.blend_op, mdp_layer.horz_deci, mdp_layer.vert_deci, mdp_layer.pipe_ndx,
mdp_layer.flags);
@@ -279,7 +284,7 @@
DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_layer.dst_rect.x,
mdp_layer.dst_rect.y, mdp_layer.dst_rect.w, mdp_layer.dst_rect.h);
hw_scale_->DumpScaleData(mdp_layer.scale);
- DLOGV_IF(kTagDriverConfig, "*************************************************************");
+ DLOGD_IF(kTagDriverConfig, "*************************************************************");
}
}
}
@@ -337,16 +342,16 @@
index++;
- DLOGV_IF(kTagDriverConfig, "************************ DestScalar[%d] **************************",
+ DLOGD_IF(kTagDriverConfig, "************************ DestScalar[%d] **************************",
dest_scalar_data->dest_scaler_ndx);
- DLOGV_IF(kTagDriverConfig, "Mixer WxH %dx%d flags %x", dest_scalar_data->lm_width,
+ DLOGD_IF(kTagDriverConfig, "Mixer WxH %dx%d flags %x", dest_scalar_data->lm_width,
dest_scalar_data->lm_height, dest_scalar_data->flags);
#ifdef MDP_DESTSCALER_ROI_ENABLE
- DLOGV_IF(kTagDriverConfig, "Panel ROI [%d, %d, %d, %d]", dest_scalar_data->panel_roi.x,
+ DLOGD_IF(kTagDriverConfig, "Panel ROI [%d, %d, %d, %d]", dest_scalar_data->panel_roi.x,
dest_scalar_data->panel_roi.y, dest_scalar_data->panel_roi.w,
dest_scalar_data->panel_roi.h);
#endif
- DLOGV_IF(kTagDriverConfig, "*****************************************************************");
+ DLOGD_IF(kTagDriverConfig, "*****************************************************************");
}
mdp_commit.dest_scaler_cnt = UINT32(hw_layer_info.dest_scale_info_map.size());
@@ -410,9 +415,9 @@
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
- DLOGV_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
+ DLOGD_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
device_name_);
- DLOGV_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_count);
+ DLOGD_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_count);
mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
uint32_t mdp_layer_index = 0;
@@ -448,16 +453,16 @@
mdp_buffer.fence = input_buffer->acquire_fence_fd;
mdp_layer_index++;
- DLOGV_IF(kTagDriverConfig, "****************** Layer[%d] %s pipe Input *******************",
+ DLOGD_IF(kTagDriverConfig, "****************** Layer[%d] %s pipe Input *******************",
i, count ? "Right" : "Left");
- DLOGI_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d, horz_deci %d, vert_deci %d",
+ DLOGD_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d, horz_deci %d, vert_deci %d",
mdp_buffer.width, mdp_buffer.height, mdp_buffer.format, mdp_layer.horz_deci,
mdp_layer.vert_deci);
- DLOGI_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_buf_stride %d, " \
+ DLOGV_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_buf_stride %d, " \
"in_plane_count %d, in_fence %d, layer count %d", mdp_buffer.planes[0].fd,
mdp_buffer.planes[0].offset, mdp_buffer.planes[0].stride, mdp_buffer.plane_count,
mdp_buffer.fence, mdp_commit.input_layer_cnt);
- DLOGV_IF(kTagDriverConfig, "*************************************************************");
+ DLOGD_IF(kTagDriverConfig, "*************************************************************");
}
}
}
@@ -709,7 +714,7 @@
}
void HWDevice::SetMDPFlags(const Layer *layer, const bool &is_rotator_used,
- bool async_cursor_updates, uint32_t *mdp_flags) {
+ bool is_cursor_pipe_used, uint32_t *mdp_flags) {
const LayerBuffer &input_buffer = layer->input_buffer;
// Flips will be taken care by rotator, if layer uses rotator for downscale/rotation. So ignore
@@ -742,7 +747,7 @@
*mdp_flags |= MDP_LAYER_SOLID_FILL;
}
- if (layer->flags.cursor && async_cursor_updates) {
+ if (hw_panel_info_.mode != kModeCommand && layer->flags.cursor && is_cursor_pipe_used) {
// command mode panels does not support async position update
*mdp_flags |= MDP_LAYER_ASYNC;
}
@@ -1141,8 +1146,8 @@
async_layer.pipe_ndx = left_pipe->pipe_id;
async_layer.src.x = UINT32(left_pipe->src_roi.left);
async_layer.src.y = UINT32(left_pipe->src_roi.top);
- async_layer.dst.x = UINT32(x);
- async_layer.dst.y = UINT32(y);
+ async_layer.dst.x = UINT32(left_pipe->dst_roi.left);
+ async_layer.dst.y = UINT32(left_pipe->dst_roi.top);
mdp_position_update pos_update = {};
pos_update.input_layer_cnt = 1;
diff --git a/sdm845/sdm/libs/core/fb/hw_device.h b/msm8909/sdm/libs/core/fb/hw_device.h
similarity index 98%
rename from sdm845/sdm/libs/core/fb/hw_device.h
rename to msm8909/sdm/libs/core/fb/hw_device.h
index 2eea87b..374df56 100644
--- a/sdm845/sdm/libs/core/fb/hw_device.h
+++ b/msm8909/sdm/libs/core/fb/hw_device.h
@@ -116,7 +116,7 @@
void SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target);
void SetRect(const LayerRect &source, mdp_rect *target);
void SetMDPFlags(const Layer *layer, const bool &is_rotator_used,
- bool async_cursor_updates, uint32_t *mdp_flags);
+ bool is_cursor_pipe_used, uint32_t *mdp_flags);
// Retrieves HW FrameBuffer Node Index
int GetFBNodeIndex(HWDeviceType device_type);
// Populates HWPanelInfo based on node index
diff --git a/sdm845/sdm/libs/core/fb/hw_events.cpp b/msm8909/sdm/libs/core/fb/hw_events.cpp
similarity index 95%
rename from sdm845/sdm/libs/core/fb/hw_events.cpp
rename to msm8909/sdm/libs/core/fb/hw_events.cpp
index c0467f9..52a8011 100644
--- a/sdm845/sdm/libs/core/fb/hw_events.cpp
+++ b/msm8909/sdm/libs/core/fb/hw_events.cpp
@@ -89,9 +89,6 @@
case HWEvent::IDLE_NOTIFY:
event_data->event_parser = &HWEvents::HandleIdleTimeout;
break;
- case HWEvent::CEC_READ_MESSAGE:
- event_data->event_parser = &HWEvents::HandleCECMessage;
- break;
case HWEvent::EXIT:
event_data->event_parser = &HWEvents::HandleThreadExit;
break;
@@ -134,8 +131,7 @@
event_thread_name_ += " - " + std::to_string(fb_num_);
map_event_to_node_ = {{HWEvent::VSYNC, "vsync_event"}, {HWEvent::EXIT, "thread_exit"},
{HWEvent::IDLE_NOTIFY, "idle_notify"}, {HWEvent::SHOW_BLANK_EVENT, "show_blank_event"},
- {HWEvent::CEC_READ_MESSAGE, "cec/rd_msg"}, {HWEvent::THERMAL_LEVEL, "msm_fb_thermal_level"},
- {HWEvent::IDLE_POWER_COLLAPSE, "idle_power_collapse"}};
+ {HWEvent::THERMAL_LEVEL, "msm_fb_thermal_level"}, {HWEvent::IDLE_POWER_COLLAPSE, "idle_power_collapse"}};
PopulateHWEventData();
@@ -234,10 +230,6 @@
event_handler_->ThermalEvent(thermal_level);
}
-void HWEvents::HandleCECMessage(char *data) {
- event_handler_->CECMessage(data);
-}
-
void HWEvents::HandleIdlePowerCollapse(char *data) {
event_handler_->IdlePowerCollapse();
}
diff --git a/sdm845/sdm/libs/core/fb/hw_events.h b/msm8909/sdm/libs/core/fb/hw_events.h
similarity index 94%
rename from sdm845/sdm/libs/core/fb/hw_events.h
rename to msm8909/sdm/libs/core/fb/hw_events.h
index 3d9cec8..b4607a8 100644
--- a/sdm845/sdm/libs/core/fb/hw_events.h
+++ b/msm8909/sdm/libs/core/fb/hw_events.h
@@ -44,9 +44,6 @@
virtual DisplayError Init(int fb_num, HWEventHandler *event_handler,
const vector<HWEvent> &event_list);
virtual DisplayError Deinit();
- virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) {
- return kErrorNotSupported;
- }
private:
static const int kMaxStringLength = 1024;
@@ -64,7 +61,6 @@
void HandleBlank(char *data) { }
void HandleIdleTimeout(char *data);
void HandleThermal(char *data);
- void HandleCECMessage(char *data);
void HandleThreadExit(char *data) { }
void HandleIdlePowerCollapse(char *data);
void PopulateHWEventData();
diff --git a/sdm845/sdm/libs/core/fb/hw_hdmi.cpp b/msm8909/sdm/libs/core/fb/hw_hdmi.cpp
similarity index 86%
copy from sdm845/sdm/libs/core/fb/hw_hdmi.cpp
copy to msm8909/sdm/libs/core/fb/hw_hdmi.cpp
index 334a043..15b47da 100644
--- a/sdm845/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/msm8909/sdm/libs/core/fb/hw_hdmi.cpp
@@ -46,6 +46,8 @@
#define __CLASS__ "HWHDMI"
+#define MIN_HDR_RESET_WAITTIME_SEC 2
+
namespace sdm {
#ifdef MDP_HDR_STREAM
@@ -176,6 +178,18 @@
info->grayscale = V4L2_PIX_FMT_NV12;
}
+ if (!mode->active_low_h) {
+ info->sync |= (uint32_t)FB_SYNC_HOR_HIGH_ACT;
+ } else {
+ info->sync &= (uint32_t)~FB_SYNC_HOR_HIGH_ACT;
+ }
+
+ if (!mode->active_low_v) {
+ info->sync |= (uint32_t)FB_SYNC_VERT_HIGH_ACT;
+ } else {
+ info->sync &= (uint32_t)~FB_SYNC_VERT_HIGH_ACT;
+ }
+
return true;
}
@@ -184,6 +198,10 @@
HWDevice::device_type_ = kDeviceHDMI;
HWDevice::device_name_ = "HDMI Display Device";
HWDevice::hw_info_intf_ = hw_info_intf;
+ (void)hdr_reset_start_;
+ (void)hdr_reset_end_;
+ (void)reset_hdr_flag_;
+ (void)cdm_color_space_;
}
DisplayError HWHDMI::Init() {
@@ -431,8 +449,19 @@
if (error != kErrorNone) {
return error;
}
+ if (cdm_color_space_commit_) {
+#ifdef MDP_COMMIT_UPDATE_CDM_COLOR_SPACE
+ mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
+ mdp_commit.cdm_color_space = cdm_color_space_;
+ mdp_commit.flags |= MDP_COMMIT_UPDATE_CDM_COLOR_SPACE;
+#endif
+ }
- return HWDevice::Commit(hw_layers);
+ error = HWDevice::Commit(hw_layers);
+ if (cdm_color_space_commit_)
+ cdm_color_space_commit_ = false;
+
+ return error;
}
DisplayError HWHDMI::GetHWScanInfo(HWScanInfo *scan_info) {
@@ -982,23 +1011,17 @@
}
DisplayError HWHDMI::UpdateHDRMetaData(HWLayers *hw_layers) {
- const HWHDRLayerInfo &hdr_layer_info = hw_layers->info.hdr_layer_info;
- if (!hw_panel_info_.hdr_enabled || hdr_layer_info.operation == HWHDRLayerInfo::kNoOp) {
+ if (!hw_panel_info_.hdr_enabled) {
return kErrorNone;
}
DisplayError error = kErrorNone;
#ifdef MDP_HDR_STREAM
+ const HWHDRLayerInfo &hdr_layer_info = hw_layers->info.hdr_layer_info;
char hdr_stream_path[kMaxStringLength] = {};
snprintf(hdr_stream_path, sizeof(hdr_stream_path), "%s%d/hdr_stream", fb_path_, fb_node_index_);
- int fd = Sys::open_(hdr_stream_path, O_WRONLY);
- if (fd < 0) {
- DLOGE("Failed to open %s with error %s", hdr_stream_path, strerror(errno));
- return kErrorFileDescriptor;
- }
-
Layer hdr_layer = {};
if (hdr_layer_info.operation == HWHDRLayerInfo::kSet && hdr_layer_info.layer_index > -1) {
hdr_layer = *(hw_layers->info.stack->layers.at(UINT32(hdr_layer_info.layer_index)));
@@ -1009,47 +1032,89 @@
const ContentLightLevel &light_level = layer_buffer->color_metadata.contentLightLevel;
const Primaries &primaries = mastering_display.primaries;
- mdp_hdr_stream hdr_stream = {};
+ mdp_hdr_stream_ctrl hdr_ctrl = {};
if (hdr_layer_info.operation == HWHDRLayerInfo::kSet) {
int32_t eotf = GetEOTF(layer_buffer->color_metadata.transfer);
- hdr_stream.eotf = (eotf < 0) ? 0 : UINT32(eotf);
- hdr_stream.white_point_x = primaries.whitePoint[0];
- hdr_stream.white_point_y = primaries.whitePoint[1];
- hdr_stream.display_primaries_x[0] = primaries.rgbPrimaries[0][0];
- hdr_stream.display_primaries_y[0] = primaries.rgbPrimaries[0][1];
- hdr_stream.display_primaries_x[1] = primaries.rgbPrimaries[1][0];
- hdr_stream.display_primaries_y[1] = primaries.rgbPrimaries[1][1];
- hdr_stream.display_primaries_x[2] = primaries.rgbPrimaries[2][0];
- hdr_stream.display_primaries_y[2] = primaries.rgbPrimaries[2][1];
- hdr_stream.min_luminance = mastering_display.minDisplayLuminance;
- hdr_stream.max_luminance = mastering_display.maxDisplayLuminance/10000;
- hdr_stream.max_content_light_level = light_level.maxContentLightLevel;
- hdr_stream.max_average_light_level = light_level.minPicAverageLightLevel;
+ hdr_ctrl.hdr_stream.eotf = (eotf < 0) ? 0 : UINT32(eotf);
+ hdr_ctrl.hdr_stream.white_point_x = primaries.whitePoint[0];
+ hdr_ctrl.hdr_stream.white_point_y = primaries.whitePoint[1];
+ hdr_ctrl.hdr_stream.display_primaries_x[0] = primaries.rgbPrimaries[0][0];
+ hdr_ctrl.hdr_stream.display_primaries_y[0] = primaries.rgbPrimaries[0][1];
+ hdr_ctrl.hdr_stream.display_primaries_x[1] = primaries.rgbPrimaries[1][0];
+ hdr_ctrl.hdr_stream.display_primaries_y[1] = primaries.rgbPrimaries[1][1];
+ hdr_ctrl.hdr_stream.display_primaries_x[2] = primaries.rgbPrimaries[2][0];
+ hdr_ctrl.hdr_stream.display_primaries_y[2] = primaries.rgbPrimaries[2][1];
+ hdr_ctrl.hdr_stream.min_luminance = mastering_display.minDisplayLuminance;
+ hdr_ctrl.hdr_stream.max_luminance = mastering_display.maxDisplayLuminance/10000;
+ hdr_ctrl.hdr_stream.max_content_light_level = light_level.maxContentLightLevel;
+ hdr_ctrl.hdr_stream.max_average_light_level = light_level.minPicAverageLightLevel;
+ hdr_ctrl.hdr_state = HDR_ENABLE;
+ reset_hdr_flag_ = false;
+#ifdef MDP_COMMIT_UPDATE_CDM_COLOR_SPACE
+ HWDevice::SetCSC(layer_buffer->color_metadata, &cdm_color_space_);
+ cdm_color_space_commit_ = true;
+#endif
// DP related
int32_t pixel_encoding = GetPixelEncoding(hdr_layer.input_buffer);
- hdr_stream.pixel_encoding = (pixel_encoding < 0) ? 0 : UINT32(pixel_encoding);
+ hdr_ctrl.hdr_stream.pixel_encoding = (pixel_encoding < 0) ? 0 : UINT32(pixel_encoding);
int32_t colorimetry = GetColoriMetry(hdr_layer.input_buffer);
- hdr_stream.colorimetry = (colorimetry < 0) ? 0 : UINT32(colorimetry);
- hdr_stream.range = GetRange(hdr_layer.input_buffer.color_metadata.range);
+ hdr_ctrl.hdr_stream.colorimetry = (colorimetry < 0) ? 0 : UINT32(colorimetry);
+ hdr_ctrl.hdr_stream.range = GetRange(hdr_layer.input_buffer.color_metadata.range);
int32_t bits_per_component = GetBitsPerComponent(hdr_layer.input_buffer);
- hdr_stream.bits_per_component = (bits_per_component < 0) ? 0 : UINT32(bits_per_component);
- hdr_stream.content_type = GetContentType(hdr_layer.input_buffer);
+ hdr_ctrl.hdr_stream.bits_per_component =
+ (bits_per_component < 0) ? 0 : UINT32(bits_per_component);
+ hdr_ctrl.hdr_stream.content_type = GetContentType(hdr_layer.input_buffer);
- DLOGV_IF(kTagDriverConfig, "HDR Stream : MaxDisplayLuminance = %d MinDisplayLuminance = %d\n"
- "MaxContentLightLevel = %d MaxAverageLightLevel = %d Red_x = %d Red_y = %d Green_x = %d\n"
- "Green_y = %d Blue_x = %d Blue_y = %d WhitePoint_x = %d WhitePoint_y = %d EOTF = %d\n"
- "PixelEncoding = %d Colorimetry = %d Range = %d BPC = %d ContentType = %d",
- hdr_stream.max_luminance, hdr_stream.min_luminance, hdr_stream.max_content_light_level,
- hdr_stream.max_average_light_level, hdr_stream.display_primaries_x[0],
- hdr_stream.display_primaries_y[0], hdr_stream.display_primaries_x[1],
- hdr_stream.display_primaries_y[1], hdr_stream.display_primaries_x[2],
- hdr_stream.display_primaries_y[2], hdr_stream.white_point_x, hdr_stream.white_point_x,
- hdr_stream.eotf, hdr_stream.pixel_encoding, hdr_stream.colorimetry, hdr_stream.range,
- hdr_stream.bits_per_component, hdr_stream.content_type);
+ DLOGD_IF(kTagDriverConfig, "kSet: HDR Stream : MaxDisplayLuminance = %d\n"
+ "MinDisplayLuminance = %d MaxContentLightLevel = %d MaxAverageLightLevel = %d\n"
+ "Red_x = %d Red_y = %d Green_x = %d Green_y = %d Blue_x = %d Blue_y = %d\n"
+ "WhitePoint_x = %d WhitePoint_y = %d EOTF = %d PixelEncoding = %d Colorimetry = %d\n"
+ "Range = %d BPC = %d ContentType = %d hdr_state = %d",
+ hdr_ctrl.hdr_stream.max_luminance, hdr_ctrl.hdr_stream.min_luminance,
+ hdr_ctrl.hdr_stream.max_content_light_level, hdr_ctrl.hdr_stream.max_average_light_level,
+ hdr_ctrl.hdr_stream.display_primaries_x[0], hdr_ctrl.hdr_stream.display_primaries_y[0],
+ hdr_ctrl.hdr_stream.display_primaries_x[1], hdr_ctrl.hdr_stream.display_primaries_y[1],
+ hdr_ctrl.hdr_stream.display_primaries_x[2], hdr_ctrl.hdr_stream.display_primaries_y[2],
+ hdr_ctrl.hdr_stream.white_point_x, hdr_ctrl.hdr_stream.white_point_x,
+ hdr_ctrl.hdr_stream.eotf, hdr_ctrl.hdr_stream.pixel_encoding,
+ hdr_ctrl.hdr_stream.colorimetry, hdr_ctrl.hdr_stream.range,
+ hdr_ctrl.hdr_stream.bits_per_component, hdr_ctrl.hdr_stream.content_type,
+ hdr_ctrl.hdr_state);
+ } else if (hdr_layer_info.operation == HWHDRLayerInfo::kReset) {
+ memset(&hdr_ctrl.hdr_stream, 0, sizeof(hdr_ctrl.hdr_stream));
+ hdr_ctrl.hdr_state = HDR_RESET;
+ reset_hdr_flag_ = true;
+ hdr_reset_start_ = time(NULL);
+#ifdef MDP_COMMIT_UPDATE_CDM_COLOR_SPACE
+ cdm_color_space_ = (mdp_color_space) MDP_CSC_DEFAULT;
+ cdm_color_space_commit_ = true;
+#endif
+ DLOGD_IF(kTagDriverConfig, "kReset: HDR Stream: HDR_RESET");
+ } else if (hdr_layer_info.operation == HWHDRLayerInfo::kNoOp) {
+ if (reset_hdr_flag_) {
+ hdr_reset_end_ = time(NULL);
+
+ if ((hdr_reset_end_ - hdr_reset_start_) >= MIN_HDR_RESET_WAITTIME_SEC) {
+ reset_hdr_flag_ = false;
+ memset(&hdr_ctrl.hdr_stream, 0, sizeof(hdr_ctrl.hdr_stream));
+ hdr_ctrl.hdr_state = HDR_DISABLE;
+ DLOGD_IF(kTagDriverConfig, "kNoOp: HDR Stream: HDR_DISABLE");
+ } else {
+ return kErrorNone;
+ }
+ } else {
+ return kErrorNone;
+ }
}
- const void *hdr_metadata = reinterpret_cast<const void*>(&hdr_stream);
- ssize_t len = Sys::pwrite_(fd, hdr_metadata, sizeof(hdr_stream), 0);
+ int fd = Sys::open_(hdr_stream_path, O_WRONLY);
+ if (fd < 0) {
+ DLOGE("Failed to open %s with error %s", hdr_stream_path, strerror(errno));
+ return kErrorFileDescriptor;
+ }
+
+ const void *hdr_metadata = reinterpret_cast<const void*>(&hdr_ctrl);
+ ssize_t len = Sys::pwrite_(fd, hdr_metadata, sizeof(hdr_ctrl), 0);
if (len <= 0) {
DLOGE("Failed to write hdr_metadata");
error = kErrorUndefined;
diff --git a/msm8909/sdm/libs/core/fb/hw_hdmi.h b/msm8909/sdm/libs/core/fb/hw_hdmi.h
new file mode 100644
index 0000000..1496a24
--- /dev/null
+++ b/msm8909/sdm/libs/core/fb/hw_hdmi.h
@@ -0,0 +1,130 @@
+/*
+* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HW_HDMI_H__
+#define __HW_HDMI_H__
+
+#include <video/msm_hdmi_modes.h>
+#include <map>
+#include <vector>
+
+#include "hw_device.h"
+
+namespace sdm {
+
+using std::vector;
+
+class HWHDMI : public HWDevice {
+ public:
+ HWHDMI(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
+
+ protected:
+ enum HWFramerateUpdate {
+ // Switch framerate by switch to other standard modes though panel blank/unblank
+ kModeSuspendResume,
+ // Switch framerate by tuning pixel clock
+ kModeClock,
+ // Switch framerate by tuning vertical front porch
+ kModeVFP,
+ // Switch framerate by tuning horizontal front porch
+ kModeHFP,
+ // Switch framerate by tuning horizontal front porch and clock
+ kModeClockHFP,
+ // Switch framerate by tuning horizontal front porch and re-caculate clock
+ kModeHFPCalcClock,
+ kModeMAX
+ };
+
+ /**
+ * struct DynamicFPSData - defines dynamic fps related data
+ * @hor_front_porch: horizontal front porch
+ * @hor_back_porch: horizontal back porch
+ * @hor_pulse_width: horizontal pulse width
+ * @clk_rate_hz: panel clock rate in HZ
+ * @fps: frames per second
+ */
+ struct DynamicFPSData {
+ uint32_t hor_front_porch;
+ uint32_t hor_back_porch;
+ uint32_t hor_pulse_width;
+ uint32_t clk_rate_hz;
+ uint32_t fps;
+ };
+
+ virtual DisplayError Init();
+ virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
+ // Requirement to call this only after the first config has been explicitly set by client
+ virtual DisplayError GetActiveConfig(uint32_t *active_config);
+ virtual DisplayError GetDisplayAttributes(uint32_t index,
+ HWDisplayAttributes *display_attributes);
+ virtual DisplayError GetHWScanInfo(HWScanInfo *scan_info);
+ virtual DisplayError GetVideoFormat(uint32_t config_index, uint32_t *video_format);
+ virtual DisplayError GetMaxCEAFormat(uint32_t *max_cea_format);
+ virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
+ virtual DisplayError SetDisplayAttributes(uint32_t index);
+ virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+ virtual DisplayError Validate(HWLayers *hw_layers);
+ virtual DisplayError Commit(HWLayers *hw_layers);
+ virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
+
+ private:
+ DisplayError ReadEDIDInfo();
+ void ReadScanInfo();
+ HWScanSupport MapHWScanSupport(uint32_t value);
+ int OpenResolutionFile(int file_mode);
+ void RequestNewPage(uint32_t page_number);
+ DisplayError ReadTimingInfo();
+ bool ReadResolutionFile(char *config_buffer);
+ bool IsResolutionFilePresent();
+ void SetSourceProductInformation(const char *node, const char *name);
+ DisplayError GetDisplayS3DSupport(uint32_t index,
+ HWDisplayAttributes *attrib);
+ DisplayError GetPanelS3DMode();
+ bool IsSupportedS3DMode(HWS3DMode s3d_mode);
+ void UpdateMixerAttributes();
+ DisplayError UpdateHDRMetaData(HWLayers *hw_layers);
+
+ DisplayError GetDynamicFrameRateMode(uint32_t refresh_rate, uint32_t*mode,
+ DynamicFPSData *data, uint32_t *config_index);
+ static const int kThresholdRefreshRate = 1000;
+ vector<uint32_t> hdmi_modes_;
+ // Holds the hdmi timing information. Ex: resolution, fps etc.,
+ vector<msm_hdmi_mode_timing_info> supported_video_modes_;
+ HWScanInfo hw_scan_info_;
+ uint32_t active_config_index_;
+ std::map<HWS3DMode, msm_hdmi_s3d_mode> s3d_mode_sdm_to_mdp_;
+ vector<HWS3DMode> supported_s3d_modes_;
+ msm_hdmi_s3d_mode active_mdp_s3d_mode_ = HDMI_S3D_NONE;
+ uint32_t frame_rate_ = 0;
+ time_t hdr_reset_start_ = 0, hdr_reset_end_ = 0;
+ bool reset_hdr_flag_ = false;
+ mdp_color_space cdm_color_space_ = {};
+ bool cdm_color_space_commit_ = false;
+};
+
+} // namespace sdm
+
+#endif // __HW_HDMI_H__
+
diff --git a/sdm845/sdm/libs/core/fb/hw_info.cpp b/msm8909/sdm/libs/core/fb/hw_info.cpp
similarity index 96%
copy from sdm845/sdm/libs/core/fb/hw_info.cpp
copy to msm8909/sdm/libs/core/fb/hw_info.cpp
index f2a13e3..636acb9 100644
--- a/sdm845/sdm/libs/core/fb/hw_info.cpp
+++ b/msm8909/sdm/libs/core/fb/hw_info.cpp
@@ -95,7 +95,7 @@
HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
for (int index = 0; index < kBwModeMax; index++) {
- bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
+ bw_info->total_bw_limit[index] = UINT32(hw_resource->max_bandwidth_low);
bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
}
@@ -154,7 +154,9 @@
while (Sys::getline_(fs, line)) {
// parse the line and update information accordingly
if (!ParseString(line.c_str(), tokens, max_count, ":, =\n", &token_count)) {
- if (!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
+ if (!strncmp(tokens[0], "mdp_version", strlen("mdp_version"))) {
+ hw_resource_->hw_version = UINT32(atoi(tokens[1])); // HW Version 3/5
+ } else if (!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
hw_resource_->hw_revision = UINT32(atoi(tokens[1])); // HW Rev, v1/v2
} else if (!strncmp(tokens[0], "rot_input_fmts", strlen("rot_input_fmts"))) {
ParseFormats(&tokens[1], (token_count - 1), kHWRotatorInput, hw_resource_);
@@ -168,10 +170,12 @@
hw_resource_->max_scale_down = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_upscale_ratio", strlen("max_upscale_ratio"))) {
hw_resource_->max_scale_up = UINT32(atoi(tokens[1]));
+ } else if (!strncmp(tokens[0], "rot_dwnscale_max", strlen("rot_dwnscale_max"))) {
+ hw_resource_->rot_downscale_max = FLOAT(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_bandwidth_low", strlen("max_bandwidth_low"))) {
- hw_resource_->max_bandwidth_low = std::stoull(tokens[1]);
+ hw_resource_->max_bandwidth_low = UINT64(atol(tokens[1]));
} else if (!strncmp(tokens[0], "max_bandwidth_high", strlen("max_bandwidth_high"))) {
- hw_resource_->max_bandwidth_high = std::stoull(tokens[1]);
+ hw_resource_->max_bandwidth_high = UINT64(atol(tokens[1]));
} else if (!strncmp(tokens[0], "max_mixer_width", strlen("max_mixer_width"))) {
hw_resource_->max_mixer_width = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_pipe_width", strlen("max_pipe_width"))) {
@@ -179,7 +183,7 @@
} else if (!strncmp(tokens[0], "max_cursor_size", strlen("max_cursor_size"))) {
hw_resource_->max_cursor_size = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_pipe_bw", strlen("max_pipe_bw"))) {
- hw_resource_->max_pipe_bw = std::stoull(tokens[1]);
+ hw_resource_->max_pipe_bw = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_mdp_clk", strlen("max_mdp_clk"))) {
hw_resource_->max_sde_clk = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "clk_fudge_factor", strlen("clk_fudge_factor"))) {
@@ -224,6 +228,8 @@
hw_resource_->is_src_split = true;
} else if (!strncmp(tokens[i], "non_scalar_rgb", strlen("non_scalar_rgb"))) {
hw_resource_->has_non_scalar_rgb = true;
+ } else if (!strncmp(tokens[i], "perf_calc", strlen("perf_calc"))) {
+ hw_resource_->perf_calc = true;
} else if (!strncmp(tokens[i], "dynamic_bw_limit", strlen("dynamic_bw_limit"))) {
hw_resource_->has_dyn_bw_support = true;
} else if (!strncmp(tokens[i], "separate_rotator", strlen("separate_rotator"))) {
@@ -313,7 +319,8 @@
hw_resource_->macrotile_nv12_factor, hw_resource_->macrotile_factor,
hw_resource_->linear_factor, hw_resource_->scale_factor, hw_resource_->extra_fudge_factor);
- if (hw_resource_->separate_rotator || hw_resource_->num_dma_pipe) {
+ // Avoid rotator for MDP3 harware.
+ if ((hw_resource_->separate_rotator || hw_resource_->num_dma_pipe) && !hw_resource_->has_ppp) {
GetHWRotatorInfo(hw_resource_);
}
diff --git a/sdm845/sdm/libs/core/fb/hw_info.h b/msm8909/sdm/libs/core/fb/hw_info.h
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_info.h
rename to msm8909/sdm/libs/core/fb/hw_info.h
diff --git a/msm8909/sdm/libs/core/fb/hw_primary.cpp b/msm8909/sdm/libs/core/fb/hw_primary.cpp
new file mode 100644
index 0000000..60a658b
--- /dev/null
+++ b/msm8909/sdm/libs/core/fb/hw_primary.cpp
@@ -0,0 +1,687 @@
+/*
+* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/prctl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <utils/debug.h>
+#include <utils/sys.h>
+#include <core/display_interface.h>
+#include <linux/msm_mdp_ext.h>
+#include <utils/rect.h>
+
+#include <string>
+
+#include "hw_primary.h"
+#include "hw_color_manager.h"
+
+#define __CLASS__ "HWPrimary"
+
+#ifndef MDP_COMMIT_CWB_EN
+#define MDP_COMMIT_CWB_EN 0x800
+#endif
+
+#ifndef MDP_COMMIT_CWB_DSPP
+#define MDP_COMMIT_CWB_DSPP 0x1000
+#endif
+
+#ifndef MDP_COMMIT_AVR_EN
+#define MDP_COMMIT_AVR_EN 0x08
+#endif
+
+#ifndef MDP_COMMIT_AVR_ONE_SHOT_MODE
+#define MDP_COMMIT_AVR_ONE_SHOT_MODE 0x10
+#endif
+
+#ifndef MDP_COMMIT_PARTIAL_UPDATE_DUAL_ROI
+#define MDP_COMMIT_PARTIAL_UPDATE_DUAL_ROI 0x20
+#endif
+
+namespace sdm {
+
+using std::string;
+using std::to_string;
+using std::fstream;
+
+HWPrimary::HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf)
+ : HWDevice(buffer_sync_handler) {
+ HWDevice::device_type_ = kDevicePrimary;
+ HWDevice::device_name_ = "Primary Display Device";
+ HWDevice::hw_info_intf_ = hw_info_intf;
+}
+
+DisplayError HWPrimary::Init() {
+ DisplayError error = kErrorNone;
+
+ error = HWDevice::Init();
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ mdp_dest_scalar_data_.resize(hw_resource_.hw_dest_scalar_info.count);
+
+ error = PopulateDisplayAttributes();
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ UpdateMixerAttributes();
+
+ // Need to enable HPD, but toggle at start when HDMI is external
+ // This helps for framework reboot or adb shell stop/start
+ EnableHotPlugDetection(0);
+ EnableHotPlugDetection(1);
+ InitializeConfigs();
+
+ avr_prop_disabled_ = Debug::IsAVRDisabled();
+
+ return error;
+}
+
+bool HWPrimary::GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels) {
+ bool ret = false;
+ string mode_path = fb_path_ + string("0/mode");
+
+ Sys::fstream fs(mode_path, fstream::in);
+ if (!fs.is_open()) {
+ return false;
+ }
+
+ string line;
+ if (Sys::getline_(fs, line)) {
+ // String is of form "U:1600x2560p-0". Documentation/fb/modedb.txt in
+ // kernel has more info on the format.
+ size_t xpos = line.find(':');
+ size_t ypos = line.find('x');
+
+ if (xpos == string::npos || ypos == string::npos) {
+ DLOGI("Resolution switch not supported");
+ } else {
+ *curr_x_pixels = static_cast<size_t>(atoi(line.c_str() + xpos + 1));
+ *curr_y_pixels = static_cast<size_t>(atoi(line.c_str() + ypos + 1));
+ DLOGI("Current Config: %u x %u", *curr_x_pixels, *curr_y_pixels);
+ ret = true;
+ }
+ }
+
+ return ret;
+}
+
+void HWPrimary::InitializeConfigs() {
+ size_t curr_x_pixels = 0;
+ size_t curr_y_pixels = 0;
+
+ if (!GetCurrentModeFromSysfs(&curr_x_pixels, &curr_y_pixels)) {
+ return;
+ }
+
+ string modes_path = string(fb_path_) + string("0/modes");
+
+ Sys::fstream fs(modes_path, fstream::in);
+ if (!fs.is_open()) {
+ DLOGI("Unable to process modes");
+ return;
+ }
+
+ string line;
+ while (Sys::getline_(fs, line)) {
+ DisplayConfigVariableInfo config;
+ // std::getline (unlike ::getline) removes \n while driver expects it in mode, so add back
+ line += '\n';
+ size_t xpos = line.find(':');
+ size_t ypos = line.find('x');
+
+ if (xpos == string::npos || ypos == string::npos) {
+ continue;
+ }
+
+ config.x_pixels = UINT32(atoi(line.c_str() + xpos + 1));
+ config.y_pixels = UINT32(atoi(line.c_str() + ypos + 1));
+ DLOGI("Found mode %d x %d", config.x_pixels, config.y_pixels);
+ display_configs_.push_back(config);
+ display_config_strings_.push_back(string(line.c_str()));
+
+ if (curr_x_pixels == config.x_pixels && curr_y_pixels == config.y_pixels) {
+ active_config_index_ = UINT32(display_configs_.size() - 1);
+ DLOGI("Active config index %u", active_config_index_);
+ }
+ }
+}
+
+DisplayError HWPrimary::GetNumDisplayAttributes(uint32_t *count) {
+ *count = IsResolutionSwitchEnabled() ? UINT32(display_configs_.size()) : 1;
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::GetActiveConfig(uint32_t *active_config_index) {
+ *active_config_index = active_config_index_;
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::GetDisplayAttributes(uint32_t index,
+ HWDisplayAttributes *display_attributes) {
+ if (!display_attributes) {
+ return kErrorParameters;
+ }
+
+ if (IsResolutionSwitchEnabled() && index >= display_configs_.size()) {
+ return kErrorParameters;
+ }
+
+ *display_attributes = display_attributes_;
+ if (IsResolutionSwitchEnabled()) {
+ // Overwrite only the parent portion of object
+ display_attributes->x_pixels = display_configs_.at(index).x_pixels;
+ display_attributes->y_pixels = display_configs_.at(index).y_pixels;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::PopulateDisplayAttributes() {
+ DTRACE_SCOPED();
+
+ // Variable screen info
+ fb_var_screeninfo var_screeninfo = {};
+
+ if (Sys::ioctl_(device_fd_, FBIOGET_VSCREENINFO, &var_screeninfo) < 0) {
+ IOCTL_LOGE(FBIOGET_VSCREENINFO, device_type_);
+ return kErrorHardware;
+ }
+
+ // Frame rate
+ msmfb_metadata meta_data = {};
+ meta_data.op = metadata_op_frame_rate;
+ if (Sys::ioctl_(device_fd_, MSMFB_METADATA_GET, &meta_data) < 0) {
+ IOCTL_LOGE(MSMFB_METADATA_GET, device_type_);
+ return kErrorHardware;
+ }
+
+ // If driver doesn't return width/height information, default to 320 dpi
+ if (INT(var_screeninfo.width) <= 0 || INT(var_screeninfo.height) <= 0) {
+ var_screeninfo.width = UINT32(((FLOAT(var_screeninfo.xres) * 25.4f)/320.0f) + 0.5f);
+ var_screeninfo.height = UINT32(((FLOAT(var_screeninfo.yres) * 25.4f)/320.0f) + 0.5f);
+ DLOGW("Driver doesn't report panel physical width and height - defaulting to 320dpi");
+ }
+
+ display_attributes_.x_pixels = var_screeninfo.xres;
+ display_attributes_.y_pixels = var_screeninfo.yres;
+ display_attributes_.v_front_porch = var_screeninfo.lower_margin;
+ display_attributes_.v_back_porch = var_screeninfo.upper_margin;
+ display_attributes_.v_pulse_width = var_screeninfo.vsync_len;
+ uint32_t h_blanking = var_screeninfo.right_margin + var_screeninfo.left_margin +
+ var_screeninfo.hsync_len;
+ display_attributes_.h_total = var_screeninfo.xres + h_blanking;
+ display_attributes_.x_dpi =
+ (FLOAT(var_screeninfo.xres) * 25.4f) / FLOAT(var_screeninfo.width);
+ display_attributes_.y_dpi =
+ (FLOAT(var_screeninfo.yres) * 25.4f) / FLOAT(var_screeninfo.height);
+ display_attributes_.fps = meta_data.data.panel_frame_rate;
+ display_attributes_.vsync_period_ns = UINT32(1000000000L / display_attributes_.fps);
+ display_attributes_.is_device_split = (hw_panel_info_.split_info.right_split ||
+ (var_screeninfo.xres > hw_resource_.max_mixer_width));
+ display_attributes_.h_total += (display_attributes_.is_device_split ||
+ hw_panel_info_.ping_pong_split)? h_blanking : 0;
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::SetDisplayAttributes(uint32_t index) {
+ DisplayError ret = kErrorNone;
+
+ if (!IsResolutionSwitchEnabled()) {
+ return kErrorNotSupported;
+ }
+
+ if (index >= display_configs_.size()) {
+ return kErrorParameters;
+ }
+
+ string mode_path = string(fb_path_) + string("0/mode");
+ int fd = Sys::open_(mode_path.c_str(), O_WRONLY);
+
+ if (fd < 0) {
+ DLOGE("Opening mode failed");
+ return kErrorNotSupported;
+ }
+
+ ssize_t written = Sys::pwrite_(fd, display_config_strings_.at(index).c_str(),
+ display_config_strings_.at(index).length(), 0);
+ if (written > 0) {
+ DLOGI("Successfully set config %u", index);
+ PopulateHWPanelInfo();
+ PopulateDisplayAttributes();
+ UpdateMixerAttributes();
+ active_config_index_ = index;
+ } else {
+ DLOGE("Writing config index %u failed with error: %s", index, strerror(errno));
+ ret = kErrorParameters;
+ }
+
+ Sys::close_(fd);
+
+ return ret;
+}
+
+DisplayError HWPrimary::SetRefreshRate(uint32_t refresh_rate) {
+ char node_path[kMaxStringLength] = {0};
+
+ if (hw_resource_.has_avr && !avr_prop_disabled_) {
+ return kErrorNotSupported;
+ }
+
+ snprintf(node_path, sizeof(node_path), "%s%d/dynamic_fps", fb_path_, fb_node_index_);
+
+ int fd = Sys::open_(node_path, O_WRONLY);
+ if (fd < 0) {
+ DLOGE("Failed to open %s with error %s", node_path, strerror(errno));
+ return kErrorFileDescriptor;
+ }
+
+ char refresh_rate_string[kMaxStringLength];
+ snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d", refresh_rate);
+ DLOGI_IF(kTagDriverConfig, "Setting refresh rate = %d", refresh_rate);
+ ssize_t len = Sys::pwrite_(fd, refresh_rate_string, strlen(refresh_rate_string), 0);
+ if (len < 0) {
+ DLOGE("Failed to write %d with error %s", refresh_rate, strerror(errno));
+ Sys::close_(fd);
+ return kErrorUndefined;
+ }
+ Sys::close_(fd);
+
+ DisplayError error = PopulateDisplayAttributes();
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::GetConfigIndex(uint32_t mode, uint32_t *index) {
+ return HWDevice::GetConfigIndex(mode, index);
+}
+
+DisplayError HWPrimary::PowerOff() {
+ if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
+ IOCTL_LOGE(FB_BLANK_POWERDOWN, device_type_);
+ return kErrorHardware;
+ }
+
+ auto_refresh_ = false;
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::Doze() {
+ if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_NORMAL) < 0) {
+ IOCTL_LOGE(FB_BLANK_NORMAL, device_type_);
+ return kErrorHardware;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::DozeSuspend() {
+ if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_VSYNC_SUSPEND) < 0) {
+ IOCTL_LOGE(FB_BLANK_VSYNC_SUSPEND, device_type_);
+ return kErrorHardware;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
+ HWLayersInfo &hw_layer_info = hw_layers->info;
+ LayerStack *stack = hw_layer_info.stack;
+
+ HWDevice::ResetDisplayParams();
+
+ mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
+
+ LayerRect left_roi = hw_layer_info.left_frame_roi.at(0);
+ LayerRect right_roi = hw_layer_info.right_frame_roi.at(0);
+
+ mdp_commit.left_roi.x = UINT32(left_roi.left);
+ mdp_commit.left_roi.y = UINT32(left_roi.top);
+ mdp_commit.left_roi.w = UINT32(left_roi.right - left_roi.left);
+ mdp_commit.left_roi.h = UINT32(left_roi.bottom - left_roi.top);
+
+ // Update second roi information in right_roi
+ if (hw_layer_info.left_frame_roi.size() == 2) {
+ mdp_commit.flags |= MDP_COMMIT_PARTIAL_UPDATE_DUAL_ROI;
+ right_roi = hw_layer_info.left_frame_roi.at(1);
+ }
+
+ // SDM treats ROI as one full coordinate system.
+ // In case source split is disabled, However, Driver assumes Mixer to operate in
+ // different co-ordinate system.
+ if (IsValid(right_roi)) {
+ mdp_commit.right_roi.x = UINT32(right_roi.left);
+ if (!hw_resource_.is_src_split) {
+ mdp_commit.right_roi.x = UINT32(right_roi.left) - mixer_attributes_.split_left;
+ }
+ mdp_commit.right_roi.y = UINT32(right_roi.top);
+ mdp_commit.right_roi.w = UINT32(right_roi.right - right_roi.left);
+ mdp_commit.right_roi.h = UINT32(right_roi.bottom - right_roi.top);
+ }
+
+ if (stack->output_buffer && hw_resource_.has_concurrent_writeback) {
+ LayerBuffer *output_buffer = stack->output_buffer;
+ mdp_out_layer_.writeback_ndx = hw_resource_.writeback_index;
+ mdp_out_layer_.buffer.width = output_buffer->unaligned_width;
+ mdp_out_layer_.buffer.height = output_buffer->unaligned_height;
+ mdp_out_layer_.buffer.comp_ratio.denom = 1000;
+ mdp_out_layer_.buffer.comp_ratio.numer = UINT32(hw_layers->output_compression * 1000);
+ mdp_out_layer_.buffer.fence = -1;
+#ifdef OUT_LAYER_COLOR_SPACE
+ SetCSC(output_buffer->color_metadata, &mdp_out_layer_.color_space);
+#endif
+ SetFormat(output_buffer->format, &mdp_out_layer_.buffer.format);
+ mdp_commit.flags |= MDP_COMMIT_CWB_EN;
+ mdp_commit.flags |= (stack->flags.post_processed_output) ? MDP_COMMIT_CWB_DSPP : 0;
+ DLOGI_IF(kTagDriverConfig, "****************** Conc WB Output buffer Info ******************");
+ DLOGI_IF(kTagDriverConfig, "out_w %d, out_h %d, out_f %d, wb_id %d DSPP output %d",
+ mdp_out_layer_.buffer.width, mdp_out_layer_.buffer.height,
+ mdp_out_layer_.buffer.format, mdp_out_layer_.writeback_ndx,
+ stack->flags.post_processed_output);
+ DLOGI_IF(kTagDriverConfig, "****************************************************************");
+ }
+
+ if (hw_resource_.has_avr) {
+ SetAVRFlags(hw_layers->hw_avr_info, &mdp_commit.flags);
+ }
+
+ return HWDevice::Validate(hw_layers);
+}
+
+DisplayError HWPrimary::Commit(HWLayers *hw_layers) {
+ LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
+
+ if (hw_resource_.has_concurrent_writeback && output_buffer) {
+ if (output_buffer->planes[0].fd >= 0) {
+ mdp_out_layer_.buffer.planes[0].fd = output_buffer->planes[0].fd;
+ mdp_out_layer_.buffer.planes[0].offset = output_buffer->planes[0].offset;
+ SetStride(device_type_, output_buffer->format, output_buffer->planes[0].stride,
+ &mdp_out_layer_.buffer.planes[0].stride);
+ mdp_out_layer_.buffer.plane_count = 1;
+ mdp_out_layer_.buffer.fence = -1;
+
+ DLOGI_IF(kTagDriverConfig, "****************** Conc WB Output buffer Info ****************");
+ DLOGI_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d",
+ mdp_out_layer_.buffer.planes[0].fd, mdp_out_layer_.buffer.planes[0].offset,
+ mdp_out_layer_.buffer.planes[0].stride);
+ DLOGI_IF(kTagDriverConfig, "**************************************************************");
+ } else {
+ DLOGE("Invalid output buffer fd");
+ return kErrorParameters;
+ }
+ }
+
+ DisplayError ret = HWDevice::Commit(hw_layers);
+
+ if (ret == kErrorNone && hw_resource_.has_concurrent_writeback && output_buffer) {
+ output_buffer->release_fence_fd = mdp_out_layer_.buffer.fence;
+ }
+
+ return ret;
+}
+
+void HWPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
+ char node_path[kMaxStringLength] = {0};
+
+ DLOGI_IF(kTagDriverConfig, "Setting idle timeout to = %d ms", timeout_ms);
+
+ snprintf(node_path, sizeof(node_path), "%s%d/idle_time", fb_path_, fb_node_index_);
+
+ // Open a sysfs node to send the timeout value to driver.
+ int fd = Sys::open_(node_path, O_WRONLY);
+ if (fd < 0) {
+ DLOGE("Unable to open %s, node %s", node_path, strerror(errno));
+ return;
+ }
+
+ char timeout_string[64];
+ snprintf(timeout_string, sizeof(timeout_string), "%d", timeout_ms);
+
+ // Notify driver about the timeout value
+ ssize_t length = Sys::pwrite_(fd, timeout_string, strlen(timeout_string), 0);
+ if (length <= 0) {
+ DLOGE("Unable to write into %s, node %s", node_path, strerror(errno));
+ }
+
+ Sys::close_(fd);
+}
+
+DisplayError HWPrimary::SetVSyncState(bool enable) {
+ DTRACE_SCOPED();
+ return HWDevice::SetVSyncState(enable);
+}
+
+DisplayError HWPrimary::SetDisplayMode(const HWDisplayMode hw_display_mode) {
+ uint32_t mode = kModeDefault;
+
+ switch (hw_display_mode) {
+ case kModeVideo:
+ mode = kModeLPMVideo;
+ break;
+ case kModeCommand:
+ mode = kModeLPMCommand;
+ break;
+ default:
+ DLOGW("Failed to translate SDE display mode %d to a MSMFB_LPM_ENABLE mode",
+ hw_display_mode);
+ return kErrorParameters;
+ }
+
+ if (Sys::ioctl_(device_fd_, INT(MSMFB_LPM_ENABLE), &mode) < 0) {
+ IOCTL_LOGE(MSMFB_LPM_ENABLE, device_type_);
+ return kErrorHardware;
+ }
+
+ DLOGI("Triggering display mode change to %d on next commit.", hw_display_mode);
+ synchronous_commit_ = true;
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::SetPanelBrightness(int level) {
+ char buffer[kMaxSysfsCommandLength] = {0};
+
+ DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level);
+ int fd = Sys::open_(kBrightnessNode, O_RDWR);
+ if (fd < 0) {
+ DLOGV_IF(kTagDriverConfig, "Failed to open node = %s, error = %s ", kBrightnessNode,
+ strerror(errno));
+ return kErrorFileDescriptor;
+ }
+
+ int32_t bytes = snprintf(buffer, kMaxSysfsCommandLength, "%d\n", level);
+ if (bytes < 0) {
+ DLOGV_IF(kTagDriverConfig, "Failed to copy new brightness level = %d", level);
+ Sys::close_(fd);
+ return kErrorUndefined;
+ }
+
+ ssize_t ret = Sys::pwrite_(fd, buffer, static_cast<size_t>(bytes), 0);
+ if (ret <= 0) {
+ DLOGV_IF(kTagDriverConfig, "Failed to write to node = %s, error = %s ", kBrightnessNode,
+ strerror(errno));
+ Sys::close_(fd);
+ return kErrorUndefined;
+ }
+ Sys::close_(fd);
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::GetPanelBrightness(int *level) {
+ char brightness[kMaxStringLength] = {0};
+
+ if (!level) {
+ DLOGV_IF(kTagDriverConfig, "Invalid input, null pointer.");
+ return kErrorParameters;
+ }
+
+ int fd = Sys::open_(kBrightnessNode, O_RDWR);
+ if (fd < 0) {
+ DLOGV_IF(kTagDriverConfig, "Failed to open brightness node = %s, error = %s", kBrightnessNode,
+ strerror(errno));
+ return kErrorFileDescriptor;
+ }
+
+ if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
+ *level = atoi(brightness);
+ DLOGV_IF(kTagDriverConfig, "Brightness level = %d", *level);
+ }
+ Sys::close_(fd);
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::CachePanelBrightness(int level) {
+ bl_level_update_commit = level;
+ bl_update_commit = true;
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::SetAutoRefresh(bool enable) {
+ const int kWriteLength = 2;
+ char buffer[kWriteLength] = {'\0'};
+ ssize_t bytes = snprintf(buffer, kWriteLength, "%d", enable);
+
+ if (enable == auto_refresh_) {
+ return kErrorNone;
+ }
+
+ if (HWDevice::SysFsWrite(kAutoRefreshNode, buffer, bytes) <= 0) { // Returns bytes written
+ return kErrorUndefined;
+ }
+
+ auto_refresh_ = enable;
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::GetPPFeaturesVersion(PPFeatureVersion *vers) {
+ mdp_pp_feature_version version = {};
+
+#ifdef PA_DITHER
+ uint32_t feature_id_mapping[kMaxNumPPFeatures] = { PCC, IGC, GC, GC, PA,
+ DITHER, GAMUT, PA_DITHER };
+#else
+ uint32_t feature_id_mapping[kMaxNumPPFeatures] = { PCC, IGC, GC, GC, PA, DITHER, GAMUT };
+#endif
+
+ if (hw_resource_.hw_version != kHWMdssVersion3) {
+ // Do not query kGlobalColorFeatureCsc for kHWMdssVersion5
+ for (int i(0); i < (kMaxNumPPFeatures - 1); i++) {
+ version.pp_feature = feature_id_mapping[i];
+
+ if (Sys::ioctl_(device_fd_, INT(MSMFB_MDP_PP_GET_FEATURE_VERSION), &version) < 0) {
+ IOCTL_LOGE(MSMFB_MDP_PP_GET_FEATURE_VERSION, device_type_);
+ return kErrorHardware;
+ }
+ vers->version[i] = version.version_info;
+ }
+ } else {
+ for (int i(0); i < kMaxNumPPFeatures; i++) {
+ version.pp_feature = feature_id_mapping[i];
+ vers->version[i] = mdp_pp_legacy;
+ }
+ }
+
+ return kErrorNone;
+}
+
+// It was entered with PPFeaturesConfig::locker_ being hold.
+DisplayError HWPrimary::SetPPFeatures(PPFeaturesConfig *feature_list) {
+ msmfb_mdp_pp kernel_params = {};
+ int ret = 0;
+ PPFeatureInfo *feature = NULL;
+
+ while (true) {
+ ret = feature_list->RetrieveNextFeature(&feature);
+ if (ret)
+ break;
+
+ if (feature) {
+ DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
+
+ if ((feature->feature_id_ < kMaxNumPPFeatures)) {
+ HWColorManager::SetFeature[feature->feature_id_](*feature, &kernel_params);
+ if (Sys::ioctl_(device_fd_, INT(MSMFB_MDP_PP), &kernel_params) < 0) {
+ IOCTL_LOGE(MSMFB_MDP_PP, device_type_);
+
+ feature_list->Reset();
+ return kErrorHardware;
+ }
+ }
+ }
+ } // while(true)
+
+ // Once all features were consumed, then destroy all feature instance from feature_list,
+ // Then mark it as non-dirty of PPFeaturesConfig cache.
+ feature_list->Reset();
+
+ return kErrorNone;
+}
+
+DisplayError HWPrimary::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
+ if (IsResolutionSwitchEnabled()) {
+ return kErrorNotSupported;
+ }
+
+ return HWDevice::SetMixerAttributes(mixer_attributes);
+}
+
+void HWPrimary::UpdateMixerAttributes() {
+ mixer_attributes_.width = display_attributes_.x_pixels;
+ mixer_attributes_.height = display_attributes_.y_pixels;
+ mixer_attributes_.split_left = display_attributes_.is_device_split ?
+ hw_panel_info_.split_info.left_split : mixer_attributes_.width;
+}
+
+void HWPrimary::SetAVRFlags(const HWAVRInfo &hw_avr_info, uint32_t *avr_flags) {
+ if (hw_avr_info.enable) {
+ *avr_flags |= MDP_COMMIT_AVR_EN;
+ }
+
+ if (hw_avr_info.mode == kOneShotMode) {
+ *avr_flags |= MDP_COMMIT_AVR_ONE_SHOT_MODE;
+ }
+}
+
+} // namespace sdm
+
diff --git a/msm8909/sdm/libs/core/fb/hw_primary.h b/msm8909/sdm/libs/core/fb/hw_primary.h
new file mode 100644
index 0000000..a825145
--- /dev/null
+++ b/msm8909/sdm/libs/core/fb/hw_primary.h
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HW_PRIMARY_H__
+#define __HW_PRIMARY_H__
+
+#include <sys/poll.h>
+#include <vector>
+#include <string>
+
+#include "hw_device.h"
+
+namespace sdm {
+
+class HWPrimary : public HWDevice {
+ public:
+ HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
+
+ protected:
+ virtual DisplayError Init();
+ virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
+ virtual DisplayError GetActiveConfig(uint32_t *active_config);
+ virtual DisplayError GetDisplayAttributes(uint32_t index,
+ HWDisplayAttributes *display_attributes);
+ virtual DisplayError SetDisplayAttributes(uint32_t index);
+ virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+ virtual DisplayError PowerOff();
+ virtual DisplayError Doze();
+ virtual DisplayError DozeSuspend();
+ virtual DisplayError Validate(HWLayers *hw_layers);
+ virtual DisplayError Commit(HWLayers *hw_layers);
+ virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
+ virtual DisplayError SetVSyncState(bool enable);
+ virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
+ virtual DisplayError SetPanelBrightness(int level);
+ virtual DisplayError CachePanelBrightness(int level);
+ virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
+ virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
+ virtual DisplayError GetPanelBrightness(int *level);
+ virtual DisplayError SetAutoRefresh(bool enable);
+ virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
+
+ private:
+ // Panel modes for the MSMFB_LPM_ENABLE ioctl
+ enum {
+ kModeLPMVideo,
+ kModeLPMCommand,
+ };
+
+ enum {
+ kMaxSysfsCommandLength = 12,
+ };
+
+ static const int kHWMdssVersion3 = 3;
+ DisplayError PopulateDisplayAttributes();
+ void InitializeConfigs();
+ bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
+ bool GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels);
+ void UpdateMixerAttributes();
+ void SetAVRFlags(const HWAVRInfo &hw_avr_info, uint32_t *avr_flags);
+
+ std::vector<DisplayConfigVariableInfo> display_configs_;
+ std::vector<std::string> display_config_strings_;
+ uint32_t active_config_index_ = 0;
+ const char *kBrightnessNode = "/sys/class/leds/lcd-backlight/brightness";
+ const char *kAutoRefreshNode = "/sys/devices/virtual/graphics/fb0/msm_cmd_autorefresh_en";
+ bool auto_refresh_ = false;
+ bool avr_prop_disabled_ = false;
+};
+
+} // namespace sdm
+
+#endif // __HW_PRIMARY_H__
+
diff --git a/msm8909/sdm/libs/core/fb/hw_scale.cpp b/msm8909/sdm/libs/core/fb/hw_scale.cpp
new file mode 100644
index 0000000..0258570
--- /dev/null
+++ b/msm8909/sdm/libs/core/fb/hw_scale.cpp
@@ -0,0 +1,314 @@
+/*
+* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <utils/debug.h>
+#include "hw_scale.h"
+
+#define __CLASS__ "HWScale"
+
+namespace sdm {
+
+DisplayError HWScale::Create(HWScale **intf, bool has_qseed3) {
+ if (has_qseed3) {
+ *intf = new HWScaleV2();
+ } else {
+ *intf = new HWScaleV1();
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWScale::Destroy(HWScale *intf) {
+ delete intf;
+
+ return kErrorNone;
+}
+
+void HWScaleV1::SetHWScaleData(const HWScaleData &scale_data, uint32_t index,
+ mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) {
+ if (!scale_data.enable.scale) {
+ return;
+ }
+
+ if (sub_block_type == kHWDestinationScalar) {
+ return;
+ }
+
+ mdp_input_layer *mdp_layer = &mdp_commit->input_layers[index];
+ mdp_layer->flags |= MDP_LAYER_ENABLE_PIXEL_EXT;
+ mdp_scale_data *mdp_scale = &scale_data_v1_.at(index);
+ mdp_scale->enable_pxl_ext = scale_data.enable.scale;
+ for (int i = 0; i < MAX_PLANES; i++) {
+ const HWPlane &plane = scale_data.plane[i];
+ mdp_scale->init_phase_x[i] = plane.init_phase_x;
+ mdp_scale->phase_step_x[i] = plane.phase_step_x;
+ mdp_scale->init_phase_y[i] = plane.init_phase_y;
+ mdp_scale->phase_step_y[i] = plane.phase_step_y;
+
+ mdp_scale->num_ext_pxls_left[i] = plane.left.extension;
+ mdp_scale->left_ftch[i] = plane.left.overfetch;
+ mdp_scale->left_rpt[i] = plane.left.repeat;
+
+ mdp_scale->num_ext_pxls_top[i] = plane.top.extension;
+ mdp_scale->top_ftch[i] = plane.top.overfetch;
+ mdp_scale->top_rpt[i] = plane.top.repeat;
+
+ mdp_scale->num_ext_pxls_right[i] = plane.right.extension;
+ mdp_scale->right_ftch[i] = plane.right.overfetch;
+ mdp_scale->right_rpt[i] = plane.right.repeat;
+
+ mdp_scale->num_ext_pxls_btm[i] = plane.bottom.extension;
+ mdp_scale->btm_ftch[i] = plane.bottom.overfetch;
+ mdp_scale->btm_rpt[i] = plane.bottom.repeat;
+
+ mdp_scale->roi_w[i] = plane.roi_width;
+ }
+
+ return;
+}
+
+void* HWScaleV1::GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) {
+ if (sub_block_type != kHWDestinationScalar) {
+ return &scale_data_v1_.at(index);
+ }
+
+ return NULL;
+}
+
+void HWScaleV1::DumpScaleData(void *mdp_scale) {
+ if (!mdp_scale) {
+ return;
+ }
+
+ mdp_scale_data *scale = reinterpret_cast<mdp_scale_data *>(mdp_scale);
+ if (scale->enable_pxl_ext) {
+ DLOGD_IF(kTagDriverConfig, "Scale Enable = %d", scale->enable_pxl_ext);
+ for (int j = 0; j < MAX_PLANES; j++) {
+ DLOGV_IF(kTagDriverConfig, "Scale Data[%d] : Phase=[%x %x %x %x] Pixel_Ext=[%d %d %d %d]",
+ j, scale->init_phase_x[j], scale->phase_step_x[j], scale->init_phase_y[j],
+ scale->phase_step_y[j], scale->num_ext_pxls_left[j], scale->num_ext_pxls_top[j],
+ scale->num_ext_pxls_right[j], scale->num_ext_pxls_btm[j]);
+ DLOGV_IF(kTagDriverConfig, "Fetch=[%d %d %d %d] Repeat=[%d %d %d %d] roi_width = %d",
+ scale->left_ftch[j], scale->top_ftch[j], scale->right_ftch[j], scale->btm_ftch[j],
+ scale->left_rpt[j], scale->top_rpt[j], scale->right_rpt[j], scale->btm_rpt[j],
+ scale->roi_w[j]);
+ }
+ }
+
+ return;
+}
+
+void HWScaleV2::SetHWScaleData(const HWScaleData &scale_data, uint32_t index,
+ mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) {
+ if (!scale_data.enable.scale && !scale_data.enable.direction_detection &&
+ !scale_data.enable.detail_enhance ) {
+ return;
+ }
+
+ mdp_scale_data_v2 *mdp_scale;
+ if (sub_block_type != kHWDestinationScalar) {
+ mdp_input_layer *mdp_layer = &mdp_commit->input_layers[index];
+ mdp_layer->flags |= MDP_LAYER_ENABLE_QSEED3_SCALE;
+ mdp_scale = &scale_data_v2_.at(index);
+ } else {
+ mdp_scale_data_v2 mdp_dest_scale = {0};
+
+ dest_scale_data_v2_.insert(std::make_pair(index, mdp_dest_scale));
+ mdp_scale = &dest_scale_data_v2_[index];
+ }
+
+ mdp_scale->enable = (scale_data.enable.scale ? ENABLE_SCALE : 0) |
+ (scale_data.enable.direction_detection ? ENABLE_DIRECTION_DETECTION : 0) |
+ (scale_data.enable.detail_enhance ? ENABLE_DETAIL_ENHANCE : 0);
+
+ if (sub_block_type == kHWDestinationScalar) {
+ mdp_destination_scaler_data *mdp_dest_scalar =
+ reinterpret_cast<mdp_destination_scaler_data *>(mdp_commit->dest_scaler);
+
+ mdp_dest_scalar[index].flags = mdp_scale->enable ? MDP_DESTSCALER_ENABLE : 0;
+
+ if (scale_data.enable.detail_enhance) {
+ mdp_dest_scalar[index].flags |= MDP_DESTSCALER_ENHANCER_UPDATE;
+ }
+ }
+
+ for (int i = 0; i < MAX_PLANES; i++) {
+ const HWPlane &plane = scale_data.plane[i];
+ mdp_scale->init_phase_x[i] = plane.init_phase_x;
+ mdp_scale->phase_step_x[i] = plane.phase_step_x;
+ mdp_scale->init_phase_y[i] = plane.init_phase_y;
+ mdp_scale->phase_step_y[i] = plane.phase_step_y;
+
+ mdp_scale->num_ext_pxls_left[i] = UINT32(plane.left.extension);
+ mdp_scale->left_ftch[i] = plane.left.overfetch;
+ mdp_scale->left_rpt[i] = plane.left.repeat;
+
+ mdp_scale->num_ext_pxls_top[i] = UINT32(plane.top.extension);
+ mdp_scale->top_ftch[i] = UINT32(plane.top.overfetch);
+ mdp_scale->top_rpt[i] = UINT32(plane.top.repeat);
+
+ mdp_scale->num_ext_pxls_right[i] = UINT32(plane.right.extension);
+ mdp_scale->right_ftch[i] = plane.right.overfetch;
+ mdp_scale->right_rpt[i] = plane.right.repeat;
+
+ mdp_scale->num_ext_pxls_btm[i] = UINT32(plane.bottom.extension);
+ mdp_scale->btm_ftch[i] = UINT32(plane.bottom.overfetch);
+ mdp_scale->btm_rpt[i] = UINT32(plane.bottom.repeat);
+
+ mdp_scale->roi_w[i] = plane.roi_width;
+
+ mdp_scale->preload_x[i] = UINT32(plane.preload_x);
+ mdp_scale->preload_y[i] = UINT32(plane.preload_y);
+
+ mdp_scale->src_width[i] = plane.src_width;
+ mdp_scale->src_height[i] = plane.src_height;
+ }
+
+ mdp_scale->dst_width = scale_data.dst_width;
+ mdp_scale->dst_height = scale_data.dst_height;
+
+ mdp_scale->y_rgb_filter_cfg = GetMDPScalingFilter(scale_data.y_rgb_filter_cfg);
+ mdp_scale->uv_filter_cfg = GetMDPScalingFilter(scale_data.uv_filter_cfg);
+ mdp_scale->alpha_filter_cfg = GetMDPAlphaInterpolation(scale_data.alpha_filter_cfg);
+ mdp_scale->blend_cfg = scale_data.blend_cfg;
+
+ mdp_scale->lut_flag = (scale_data.lut_flag.lut_swap ? SCALER_LUT_SWAP : 0) |
+ (scale_data.lut_flag.lut_dir_wr ? SCALER_LUT_DIR_WR : 0) |
+ (scale_data.lut_flag.lut_y_cir_wr ? SCALER_LUT_Y_CIR_WR : 0) |
+ (scale_data.lut_flag.lut_uv_cir_wr ? SCALER_LUT_UV_CIR_WR : 0) |
+ (scale_data.lut_flag.lut_y_sep_wr ? SCALER_LUT_Y_SEP_WR : 0) |
+ (scale_data.lut_flag.lut_uv_sep_wr ? SCALER_LUT_UV_SEP_WR : 0);
+
+ mdp_scale->dir_lut_idx = scale_data.dir_lut_idx;
+ mdp_scale->y_rgb_cir_lut_idx = scale_data.y_rgb_cir_lut_idx;
+ mdp_scale->uv_cir_lut_idx = scale_data.uv_cir_lut_idx;
+ mdp_scale->y_rgb_sep_lut_idx = scale_data.y_rgb_sep_lut_idx;
+ mdp_scale->uv_sep_lut_idx = scale_data.uv_sep_lut_idx;
+
+ if (mdp_scale->enable & ENABLE_DETAIL_ENHANCE) {
+ mdp_det_enhance_data *mdp_det_enhance = &mdp_scale->detail_enhance;
+ mdp_det_enhance->enable = scale_data.detail_enhance.enable;
+ mdp_det_enhance->sharpen_level1 = scale_data.detail_enhance.sharpen_level1;
+ mdp_det_enhance->sharpen_level2 = scale_data.detail_enhance.sharpen_level2;
+ mdp_det_enhance->clip = scale_data.detail_enhance.clip;
+ mdp_det_enhance->limit = scale_data.detail_enhance.limit;
+ mdp_det_enhance->thr_quiet = scale_data.detail_enhance.thr_quiet;
+ mdp_det_enhance->thr_dieout = scale_data.detail_enhance.thr_dieout;
+ mdp_det_enhance->thr_low = scale_data.detail_enhance.thr_low;
+ mdp_det_enhance->thr_high = scale_data.detail_enhance.thr_high;
+ mdp_det_enhance->prec_shift = scale_data.detail_enhance.prec_shift;
+
+ for (int i = 0; i < MAX_DET_CURVES; i++) {
+ mdp_det_enhance->adjust_a[i] = scale_data.detail_enhance.adjust_a[i];
+ mdp_det_enhance->adjust_b[i] = scale_data.detail_enhance.adjust_b[i];
+ mdp_det_enhance->adjust_c[i] = scale_data.detail_enhance.adjust_c[i];
+ }
+ }
+
+ return;
+}
+
+void* HWScaleV2::GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) {
+ if (sub_block_type != kHWDestinationScalar) {
+ return &scale_data_v2_.at(index);
+ } else {
+ return &dest_scale_data_v2_[index];
+ }
+}
+
+uint32_t HWScaleV2::GetMDPScalingFilter(ScalingFilterConfig filter_cfg) {
+ switch (filter_cfg) {
+ case kFilterEdgeDirected:
+ return FILTER_EDGE_DIRECTED_2D;
+ case kFilterCircular:
+ return FILTER_CIRCULAR_2D;
+ case kFilterSeparable:
+ return FILTER_SEPARABLE_1D;
+ case kFilterBilinear:
+ return FILTER_BILINEAR;
+ default:
+ DLOGE("Invalid Scaling Filter");
+ return kFilterMax;
+ }
+}
+
+uint32_t HWScaleV2::GetMDPAlphaInterpolation(HWAlphaInterpolation alpha_filter_cfg) {
+ switch (alpha_filter_cfg) {
+ case kInterpolationPixelRepeat:
+ return FILTER_ALPHA_DROP_REPEAT;
+ case kInterpolationBilinear:
+ return FILTER_ALPHA_BILINEAR;
+ default:
+ DLOGE("Invalid Alpha Interpolation");
+ return kInterpolationMax;
+ }
+}
+
+void HWScaleV2::DumpScaleData(void *mdp_scale) {
+ if (!mdp_scale) {
+ return;
+ }
+
+ mdp_scale_data_v2 *scale = reinterpret_cast<mdp_scale_data_v2 *>(mdp_scale);
+ if (scale->enable) {
+ DLOGD_IF(kTagDriverConfig, "Scale Enable = %d", scale->enable);
+ for (int j = 0; j < MAX_PLANES; j++) {
+ DLOGV_IF(kTagDriverConfig, "Scale Data[%d]: Phase_init[x y]=[%x %x] Phase_step:[x y]=[%x %x]",
+ j, scale->init_phase_x[j], scale->init_phase_y[j], scale->phase_step_x[j],
+ scale->phase_step_y[j]);
+ DLOGV_IF(kTagDriverConfig, "Preload[x y]=[%x %x], Pixel Ext=[%d %d] Ovfetch=[%d %d %d %d]",
+ scale->preload_x[j], scale->preload_y[j], scale->num_ext_pxls_left[j],
+ scale->num_ext_pxls_top[j], scale->left_ftch[j], scale->top_ftch[j], scale->right_ftch[j],
+ scale->btm_ftch[j]);
+ DLOGV_IF(kTagDriverConfig, "Repeat=[%d %d %d %d] Src[w x h]=[%d %d] roi_width = %d",
+ scale->left_rpt[j], scale->top_rpt[j], scale->right_rpt[j], scale->btm_rpt[j],
+ scale->src_width[j], scale->src_height[j], scale->roi_w[j]);
+ }
+
+ DLOGD_IF(kTagDriverConfig, "LUT flags = %d", scale->lut_flag);
+ DLOGV_IF(kTagDriverConfig, "y_rgb_filter=%d, uv_filter=%d, alpha_filter=%d, blend_cfg=%d",
+ scale->y_rgb_filter_cfg, scale->uv_filter_cfg, scale->alpha_filter_cfg, scale->blend_cfg);
+ DLOGV_IF(kTagDriverConfig, "dir_lut=%d, y_rgb_cir=%d, uv_cir=%d, y_rgb_sep=%d, uv_sep=%d",
+ scale->dir_lut_idx, scale->y_rgb_cir_lut_idx, scale->uv_cir_lut_idx,
+ scale->y_rgb_sep_lut_idx, scale->uv_sep_lut_idx);
+ if (scale->enable & ENABLE_DETAIL_ENHANCE) {
+ mdp_det_enhance_data *de = &scale->detail_enhance;
+ DLOGV_IF(kTagDriverConfig, "Detail Enhance: enable: %d sharpen_level1: %d sharpen_level2: %d",
+ de->enable, de->sharpen_level1, de->sharpen_level2);
+ DLOGV_IF(kTagDriverConfig, "clip: %d limit:%d thr_quiet: %d thr_dieout: %d",
+ de->clip, de->limit, de->thr_quiet, de->thr_dieout);
+ DLOGV_IF(kTagDriverConfig, "thr_low: %d thr_high: %d prec_shift: %d", de->thr_low,
+ de->thr_high, de->prec_shift);
+ for (uint32_t i = 0; i < MAX_DET_CURVES; i++) {
+ DLOGV_IF(kTagDriverConfig, "adjust_a[%d]: %d adjust_b[%d]: %d adjust_c[%d]: %d", i,
+ de->adjust_a[i], i, de->adjust_b[i], i, de->adjust_c[i]);
+ }
+ }
+ }
+
+ return;
+}
+
+} // namespace sdm
diff --git a/sdm845/sdm/libs/core/fb/hw_scale.h b/msm8909/sdm/libs/core/fb/hw_scale.h
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_scale.h
rename to msm8909/sdm/libs/core/fb/hw_scale.h
diff --git a/sdm845/sdm/libs/core/fb/hw_virtual.cpp b/msm8909/sdm/libs/core/fb/hw_virtual.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_virtual.cpp
rename to msm8909/sdm/libs/core/fb/hw_virtual.cpp
diff --git a/sdm845/sdm/libs/core/fb/hw_virtual.h b/msm8909/sdm/libs/core/fb/hw_virtual.h
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_virtual.h
rename to msm8909/sdm/libs/core/fb/hw_virtual.h
diff --git a/sdm845/sdm/libs/core/hw_events_interface.cpp b/msm8909/sdm/libs/core/hw_events_interface.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/hw_events_interface.cpp
rename to msm8909/sdm/libs/core/hw_events_interface.cpp
diff --git a/sdm845/sdm/libs/core/hw_events_interface.h b/msm8909/sdm/libs/core/hw_events_interface.h
similarity index 95%
rename from sdm845/sdm/libs/core/hw_events_interface.h
rename to msm8909/sdm/libs/core/hw_events_interface.h
index 482e077..17fb7df 100644
--- a/sdm845/sdm/libs/core/hw_events_interface.h
+++ b/msm8909/sdm/libs/core/hw_events_interface.h
@@ -38,7 +38,6 @@
VSYNC = 0,
EXIT,
IDLE_NOTIFY,
- CEC_READ_MESSAGE,
SHOW_BLANK_EVENT,
THERMAL_LEVEL,
IDLE_POWER_COLLAPSE,
@@ -49,7 +48,6 @@
virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
const std::vector<HWEvent> &event_list) = 0;
virtual DisplayError Deinit() = 0;
- virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) = 0;
static DisplayError Create(int display_type, HWEventHandler *event_handler,
const std::vector<HWEvent> &event_list, HWEventsInterface **intf);
diff --git a/sdm845/sdm/libs/core/hw_info_interface.cpp b/msm8909/sdm/libs/core/hw_info_interface.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/hw_info_interface.cpp
rename to msm8909/sdm/libs/core/hw_info_interface.cpp
diff --git a/sdm845/sdm/libs/core/hw_info_interface.h b/msm8909/sdm/libs/core/hw_info_interface.h
similarity index 100%
rename from sdm845/sdm/libs/core/hw_info_interface.h
rename to msm8909/sdm/libs/core/hw_info_interface.h
diff --git a/sdm845/sdm/libs/core/hw_interface.cpp b/msm8909/sdm/libs/core/hw_interface.cpp
similarity index 93%
rename from sdm845/sdm/libs/core/hw_interface.cpp
rename to msm8909/sdm/libs/core/hw_interface.cpp
index a27c5f8..b5c9fe9 100644
--- a/sdm845/sdm/libs/core/hw_interface.cpp
+++ b/msm8909/sdm/libs/core/hw_interface.cpp
@@ -37,7 +37,6 @@
#include "fb/hw_virtual.h"
#ifdef COMPILE_DRM
#include "drm/hw_device_drm.h"
-#include "drm/hw_virtual_drm.h"
#endif
#define __CLASS__ "HWInterface"
@@ -70,11 +69,9 @@
break;
case kVirtual:
if (driver_type == DriverType::FB) {
- hw = new HWVirtual(buffer_sync_handler,hw_info_intf);
+ hw = new HWVirtual(buffer_sync_handler, hw_info_intf);
} else {
-#ifdef COMPILE_DRM
- hw = new HWVirtualDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
-#endif
+ return kErrorNotSupported;
}
break;
default:
diff --git a/sdm845/sdm/libs/core/hw_interface.h b/msm8909/sdm/libs/core/hw_interface.h
similarity index 98%
rename from sdm845/sdm/libs/core/hw_interface.h
rename to msm8909/sdm/libs/core/hw_interface.h
index 5dbeb11..312ad98 100644
--- a/sdm845/sdm/libs/core/hw_interface.h
+++ b/msm8909/sdm/libs/core/hw_interface.h
@@ -59,7 +59,6 @@
virtual DisplayError Blank(bool blank) = 0;
virtual void IdleTimeout() = 0;
virtual void ThermalEvent(int64_t thermal_level) = 0;
- virtual void CECMessage(char *message) = 0;
virtual void IdlePowerCollapse() = 0;
protected:
diff --git a/sdm845/sdm/libs/core/resource_default.cpp b/msm8909/sdm/libs/core/resource_default.cpp
similarity index 97%
rename from sdm845/sdm/libs/core/resource_default.cpp
rename to msm8909/sdm/libs/core/resource_default.cpp
index 2d74941..6a4f3e5 100644
--- a/sdm845/sdm/libs/core/resource_default.cpp
+++ b/msm8909/sdm/libs/core/resource_default.cpp
@@ -212,7 +212,7 @@
return kErrorNone;
}
-DisplayError ResourceDefault::Stop(Handle display_ctx) {
+DisplayError ResourceDefault::Stop(Handle display_ctx, HWLayers *hw_layers) {
locker_.Unlock();
return kErrorNone;
@@ -923,8 +923,14 @@
return kErrorNone;
}
-DisplayError ResourceDefault::ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
- int x, int y) {
+DisplayError ResourceDefault::ValidateCursorConfig(Handle display_ctx, const Layer *layer,
+ bool is_top) {
+ return kErrorNotSupported;
+}
+
+DisplayError ResourceDefault::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
+ int x, int y,
+ DisplayConfigVariableInfo *fb_config) {
return kErrorNotSupported;
}
diff --git a/sdm845/sdm/libs/core/resource_default.h b/msm8909/sdm/libs/core/resource_default.h
similarity index 96%
rename from sdm845/sdm/libs/core/resource_default.h
rename to msm8909/sdm/libs/core/resource_default.h
index f835410..a67eb09 100644
--- a/sdm845/sdm/libs/core/resource_default.h
+++ b/msm8909/sdm/libs/core/resource_default.h
@@ -50,7 +50,7 @@
const HWPanelInfo &hw_panel_info,
const HWMixerAttributes &mixer_attributes);
virtual DisplayError Start(Handle display_ctx);
- virtual DisplayError Stop(Handle display_ctx);
+ virtual DisplayError Stop(Handle display_ctx, HWLayers *hw_layers);
virtual DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers);
virtual DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
virtual DisplayError Commit(Handle display_ctx, HWLayers *hw_layers);
@@ -60,7 +60,8 @@
virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90,
BufferLayout layout, bool use_rotator_downscale);
DisplayError ValidateCursorConfig(Handle display_ctx, const Layer *layer, bool is_top);
- DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
+ DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y,
+ DisplayConfigVariableInfo *fb_config);
DisplayError SetMaxBandwidthMode(HWBwModes mode);
virtual DisplayError SetDetailEnhancerData(Handle display_ctx,
const DisplayDetailEnhancerData &de_data);
diff --git a/sdm845/sdm/libs/core/strategy.cpp b/msm8909/sdm/libs/core/strategy.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/strategy.cpp
rename to msm8909/sdm/libs/core/strategy.cpp
diff --git a/sdm845/sdm/libs/core/strategy.h b/msm8909/sdm/libs/core/strategy.h
similarity index 100%
rename from sdm845/sdm/libs/core/strategy.h
rename to msm8909/sdm/libs/core/strategy.h
diff --git a/sdm845/sdm/libs/hwc/Android.mk b/msm8909/sdm/libs/hwc/Android.mk
similarity index 100%
rename from sdm845/sdm/libs/hwc/Android.mk
rename to msm8909/sdm/libs/hwc/Android.mk
diff --git a/sdm845/sdm/libs/hwc/blit_engine.h b/msm8909/sdm/libs/hwc/blit_engine.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/blit_engine.h
rename to msm8909/sdm/libs/hwc/blit_engine.h
diff --git a/sdm845/sdm/libs/hwc/blit_engine_c2d.cpp b/msm8909/sdm/libs/hwc/blit_engine_c2d.cpp
similarity index 100%
rename from sdm845/sdm/libs/hwc/blit_engine_c2d.cpp
rename to msm8909/sdm/libs/hwc/blit_engine_c2d.cpp
diff --git a/sdm845/sdm/libs/hwc/blit_engine_c2d.h b/msm8909/sdm/libs/hwc/blit_engine_c2d.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/blit_engine_c2d.h
rename to msm8909/sdm/libs/hwc/blit_engine_c2d.h
diff --git a/msm8909/sdm/libs/hwc/cpuhint.cpp b/msm8909/sdm/libs/hwc/cpuhint.cpp
new file mode 100644
index 0000000..2675c9b
--- /dev/null
+++ b/msm8909/sdm/libs/hwc/cpuhint.cpp
@@ -0,0 +1,108 @@
+/* Copyright (c) 2015,2018 The Linux Foundataion. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#include <cutils/properties.h>
+#include <dlfcn.h>
+#include <utils/debug.h>
+
+#include "cpuhint.h"
+#include "hwc_debugger.h"
+
+#define __CLASS__ "CPUHint"
+
+namespace sdm {
+
+DisplayError CPUHint::Init(HWCDebugHandler *debug_handler) {
+ char path[PROPERTY_VALUE_MAX];
+ if (debug_handler->GetProperty("ro.vendor.extension_library", path) != kErrorNone) {
+ DLOGI("Vendor Extension Library not enabled");
+ return kErrorNotSupported;
+ }
+
+ int pre_enable_window = -1;
+ debug_handler->GetProperty(PERF_HINT_WINDOW_PROP, &pre_enable_window);
+ if (pre_enable_window <= 0) {
+ DLOGI("Invalid CPU Hint Pre-enable Window %d", pre_enable_window);
+ return kErrorNotSupported;
+ }
+
+ DLOGI("CPU Hint Pre-enable Window %d", pre_enable_window);
+ pre_enable_window_ = pre_enable_window;
+
+ if (vendor_ext_lib_.Open(path)) {
+ if (!vendor_ext_lib_.Sym("perf_lock_acq", reinterpret_cast<void **>(&fn_lock_acquire_)) ||
+ !vendor_ext_lib_.Sym("perf_lock_rel", reinterpret_cast<void **>(&fn_lock_release_))) {
+ DLOGW("Failed to load symbols for Vendor Extension Library");
+ return kErrorNotSupported;
+ }
+ DLOGI("Successfully Loaded Vendor Extension Library symbols");
+ enabled_ = true;
+ } else {
+ DLOGW("Failed to open %s : %s", path, vendor_ext_lib_.Error());
+ }
+
+ return kErrorNone;
+}
+
+void CPUHint::Set() {
+ if (!enabled_) {
+ return;
+ }
+ if (lock_acquired_) {
+ return;
+ }
+ if (frame_countdown_) {
+ --frame_countdown_;
+ return;
+ }
+
+ int hint = HINT;
+ lock_handle_ = fn_lock_acquire_(0 /*handle*/, 0/*duration*/,
+ &hint, sizeof(hint) / sizeof(int));
+ if (lock_handle_ >= 0) {
+ lock_acquired_ = true;
+ }
+}
+
+void CPUHint::Reset() {
+ if (!enabled_) {
+ return;
+ }
+
+ frame_countdown_ = pre_enable_window_;
+
+ if (!lock_acquired_) {
+ return;
+ }
+
+ fn_lock_release_(lock_handle_);
+ lock_acquired_ = false;
+}
+
+} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc/cpuhint.h b/msm8909/sdm/libs/hwc/cpuhint.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/cpuhint.h
rename to msm8909/sdm/libs/hwc/cpuhint.h
diff --git a/sdm845/sdm/libs/hwc/hwc_buffer_allocator.cpp b/msm8909/sdm/libs/hwc/hwc_buffer_allocator.cpp
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_buffer_allocator.cpp
rename to msm8909/sdm/libs/hwc/hwc_buffer_allocator.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_buffer_allocator.h b/msm8909/sdm/libs/hwc/hwc_buffer_allocator.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_buffer_allocator.h
rename to msm8909/sdm/libs/hwc/hwc_buffer_allocator.h
diff --git a/sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.cpp b/msm8909/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
similarity index 99%
copy from sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
copy to msm8909/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
index 784e91b..f2dacb2 100644
--- a/sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
+++ b/msm8909/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
@@ -27,6 +27,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <errno.h>
#include <sync/sync.h>
#include <utils/constants.h>
#include <utils/debug.h>
diff --git a/sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.h b/msm8909/sdm/libs/hwc/hwc_buffer_sync_handler.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.h
rename to msm8909/sdm/libs/hwc/hwc_buffer_sync_handler.h
diff --git a/sdm845/sdm/libs/hwc/hwc_color_manager.cpp b/msm8909/sdm/libs/hwc/hwc_color_manager.cpp
similarity index 99%
rename from sdm845/sdm/libs/hwc/hwc_color_manager.cpp
rename to msm8909/sdm/libs/hwc/hwc_color_manager.cpp
index 471ca49..a02f1ce 100644
--- a/sdm845/sdm/libs/hwc/hwc_color_manager.cpp
+++ b/msm8909/sdm/libs/hwc/hwc_color_manager.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -424,7 +424,6 @@
PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
if (de_tuning_cfg_data->cfg_pending == true) {
if (!de_tuning_cfg_data->cfg_en) {
- de_data.override_flags = kOverrideDEEnable;
de_data.enable = 0;
} else {
de_data.override_flags = kOverrideDEEnable;
diff --git a/sdm845/sdm/libs/hwc/hwc_color_manager.h b/msm8909/sdm/libs/hwc/hwc_color_manager.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_color_manager.h
rename to msm8909/sdm/libs/hwc/hwc_color_manager.h
diff --git a/sdm845/sdm/libs/hwc/hwc_debugger.cpp b/msm8909/sdm/libs/hwc/hwc_debugger.cpp
similarity index 83%
copy from sdm845/sdm/libs/hwc/hwc_debugger.cpp
copy to msm8909/sdm/libs/hwc/hwc_debugger.cpp
index 0cc0501..18a448d 100644
--- a/sdm845/sdm/libs/hwc/hwc_debugger.cpp
+++ b/msm8909/sdm/libs/hwc/hwc_debugger.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,6 +29,7 @@
#include <utils/constants.h>
#include <cutils/properties.h>
+#include <utils/debug.h>
#include "hwc_debugger.h"
@@ -41,6 +42,10 @@
void HWCDebugHandler::DebugAll(bool enable, int verbose_level) {
if (enable) {
debug_flags_ = 0x7FFFFFFF;
+ if (verbose_level) {
+ // Enable verbose scalar logs only when explicitely enabled
+ debug_flags_[kTagScalar] = 0;
+ }
verbose_level_ = verbose_level;
} else {
debug_flags_ = 0x1; // kTagNone should always be printed.
@@ -98,6 +103,16 @@
}
}
+void HWCDebugHandler::DebugScalar(bool enable, int verbose_level) {
+ if (enable) {
+ debug_flags_[kTagScalar] = 1;
+ verbose_level_ = verbose_level;
+ } else {
+ debug_flags_[kTagScalar] = 0;
+ verbose_level_ = 0;
+ }
+}
+
void HWCDebugHandler::DebugQdcm(bool enable, int verbose_level) {
if (enable) {
debug_flags_[kTagQDCM] = 1;
@@ -108,6 +123,26 @@
}
}
+void HWCDebugHandler::DebugClient(bool enable, int verbose_level) {
+ if (enable) {
+ debug_flags_[kTagClient] = 1;
+ verbose_level_ = verbose_level;
+ } else {
+ debug_flags_[kTagClient] = 0;
+ verbose_level_ = 0;
+ }
+}
+
+void HWCDebugHandler::DebugDisplay(bool enable, int verbose_level) {
+ if (enable) {
+ debug_flags_[kTagDisplay] = 1;
+ verbose_level_ = verbose_level;
+ } else {
+ debug_flags_[kTagDisplay] = 0;
+ verbose_level_ = 0;
+ }
+}
+
void HWCDebugHandler::Error(DebugTag tag, const char *format, ...) {
if (debug_flags_[tag]) {
va_list list;
@@ -150,11 +185,9 @@
void HWCDebugHandler::BeginTrace(const char *class_name, const char *function_name,
const char *custom_string) {
- if (atrace_is_tag_enabled(ATRACE_TAG)) {
- char name[PATH_MAX] = {0};
- snprintf(name, sizeof(name), "%s::%s::%s", class_name, function_name, custom_string);
- atrace_begin(ATRACE_TAG, name);
- }
+ char name[PATH_MAX] = {0};
+ snprintf(name, sizeof(name), "%s::%s::%s", class_name, function_name, custom_string);
+ atrace_begin(ATRACE_TAG, name);
}
void HWCDebugHandler::EndTrace() {
@@ -163,7 +196,7 @@
int HWCDebugHandler::GetIdleTimeoutMs() {
int value = IDLE_TIMEOUT_DEFAULT_MS;
- debug_handler_.GetProperty("sdm.idle_time", &value);
+ debug_handler_.GetProperty(IDLE_TIME_PROP, &value);
return value;
}
diff --git a/sdm845/sdm/libs/hwc/hwc_debugger.h b/msm8909/sdm/libs/hwc/hwc_debugger.h
similarity index 90%
copy from sdm845/sdm/libs/hwc/hwc_debugger.h
copy to msm8909/sdm/libs/hwc/hwc_debugger.h
index 01319ab..3a3d787 100644
--- a/sdm845/sdm/libs/hwc/hwc_debugger.h
+++ b/msm8909/sdm/libs/hwc/hwc_debugger.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -34,7 +34,7 @@
#include <core/sdm_types.h>
#include <core/debug_interface.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <utils/Trace.h>
#include <bitset>
@@ -43,6 +43,7 @@
class HWCDebugHandler : public DebugHandler {
public:
static inline DebugHandler* Get() { return &debug_handler_; }
+ static const char* DumpDir() { return "/data/vendor/display"; }
static void DebugAll(bool enable, int verbose_level);
static void DebugResources(bool enable, int verbose_level);
@@ -50,7 +51,10 @@
static void DebugCompManager(bool enable, int verbose_level);
static void DebugDriverConfig(bool enable, int verbose_level);
static void DebugRotator(bool enable, int verbose_level);
+ static void DebugScalar(bool enable, int verbose_level);
static void DebugQdcm(bool enable, int verbose_level);
+ static void DebugClient(bool enable, int verbose_level);
+ static void DebugDisplay(bool enable, int verbose_level);
static int GetIdleTimeoutMs();
virtual void Error(DebugTag tag, const char *format, ...);
diff --git a/sdm845/sdm/libs/hwc/hwc_display.cpp b/msm8909/sdm/libs/hwc/hwc_display.cpp
similarity index 99%
rename from sdm845/sdm/libs/hwc/hwc_display.cpp
rename to msm8909/sdm/libs/hwc/hwc_display.cpp
index 2c5c885..47915c7 100644
--- a/sdm845/sdm/libs/hwc/hwc_display.cpp
+++ b/msm8909/sdm/libs/hwc/hwc_display.cpp
@@ -943,7 +943,7 @@
case kCompositionGPUTarget: *target = HWC_FRAMEBUFFER_TARGET; break;
case kCompositionGPU: *target = HWC_FRAMEBUFFER; break;
case kCompositionGPUS3D: *target = HWC_FRAMEBUFFER; break;
- case kCompositionCursor: *target = HWC_CURSOR_OVERLAY; break;
+ case kCompositionHWCursor: *target = HWC_CURSOR_OVERLAY; break;
default: *target = HWC_OVERLAY; break;
}
}
diff --git a/sdm845/sdm/libs/hwc/hwc_display.h b/msm8909/sdm/libs/hwc/hwc_display.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_display.h
rename to msm8909/sdm/libs/hwc/hwc_display.h
diff --git a/sdm845/sdm/libs/hwc/hwc_display_external.cpp b/msm8909/sdm/libs/hwc/hwc_display_external.cpp
similarity index 97%
rename from sdm845/sdm/libs/hwc/hwc_display_external.cpp
rename to msm8909/sdm/libs/hwc/hwc_display_external.cpp
index da216f7..a535819 100644
--- a/sdm845/sdm/libs/hwc/hwc_display_external.cpp
+++ b/msm8909/sdm/libs/hwc/hwc_display_external.cpp
@@ -137,11 +137,12 @@
bool one_video_updating_layer = SingleVideoLayerUpdating(UINT32(content_list->numHwLayers - 1));
uint32_t refresh_rate = GetOptimalRefreshRate(one_video_updating_layer);
- bool final_rate = force_refresh_rate_ ? true : false;
- error = display_intf_->SetRefreshRate(refresh_rate, final_rate);
- if (error == kErrorNone) {
- // On success, set current refresh rate to new refresh rate
- current_refresh_rate_ = refresh_rate;
+ if (current_refresh_rate_ != refresh_rate) {
+ error = display_intf_->SetRefreshRate(refresh_rate);
+ if (error == kErrorNone) {
+ // On success, set current refresh rate to new refresh rate
+ current_refresh_rate_ = refresh_rate;
+ }
}
status = PrepareLayerStack(content_list);
diff --git a/sdm845/sdm/libs/hwc/hwc_display_external.h b/msm8909/sdm/libs/hwc/hwc_display_external.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_display_external.h
rename to msm8909/sdm/libs/hwc/hwc_display_external.h
diff --git a/sdm845/sdm/libs/hwc/hwc_display_external_test.cpp b/msm8909/sdm/libs/hwc/hwc_display_external_test.cpp
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_display_external_test.cpp
rename to msm8909/sdm/libs/hwc/hwc_display_external_test.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_display_external_test.h b/msm8909/sdm/libs/hwc/hwc_display_external_test.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_display_external_test.h
rename to msm8909/sdm/libs/hwc/hwc_display_external_test.h
diff --git a/sdm845/sdm/libs/hwc/hwc_display_null.cpp b/msm8909/sdm/libs/hwc/hwc_display_null.cpp
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_display_null.cpp
rename to msm8909/sdm/libs/hwc/hwc_display_null.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_display_null.h b/msm8909/sdm/libs/hwc/hwc_display_null.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_display_null.h
rename to msm8909/sdm/libs/hwc/hwc_display_null.h
diff --git a/sdm845/sdm/libs/hwc/hwc_display_primary.cpp b/msm8909/sdm/libs/hwc/hwc_display_primary.cpp
similarity index 97%
rename from sdm845/sdm/libs/hwc/hwc_display_primary.cpp
rename to msm8909/sdm/libs/hwc/hwc_display_primary.cpp
index 8d6f31b..ba351b5 100644
--- a/sdm845/sdm/libs/hwc/hwc_display_primary.cpp
+++ b/msm8909/sdm/libs/hwc/hwc_display_primary.cpp
@@ -192,13 +192,21 @@
}
uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
- bool final_rate = force_refresh_rate_ ? true : false;
- error = display_intf_->SetRefreshRate(refresh_rate, final_rate);
+ // TODO(user): Need to read current refresh rate to avoid
+ // redundant calls to set refresh rate during idle fall back.
+ if ((current_refresh_rate_ != refresh_rate) || (handle_idle_timeout_)) {
+ error = display_intf_->SetRefreshRate(refresh_rate);
+ }
+
if (error == kErrorNone) {
// On success, set current refresh rate to new refresh rate
current_refresh_rate_ = refresh_rate;
}
+ if (handle_idle_timeout_) {
+ handle_idle_timeout_ = false;
+ }
+
if (content_list->numHwLayers <= 1) {
flush_ = true;
}
@@ -362,6 +370,8 @@
uint32_t HWCDisplayPrimary::GetOptimalRefreshRate(bool one_updating_layer) {
if (force_refresh_rate_) {
return force_refresh_rate_;
+ } else if (handle_idle_timeout_) {
+ return min_refresh_rate_;
} else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
return metadata_refresh_rate_;
}
@@ -378,6 +388,7 @@
}
hwc_procs->invalidate(hwc_procs);
+ handle_idle_timeout_ = true;
return error;
}
diff --git a/sdm845/sdm/libs/hwc/hwc_display_primary.h b/msm8909/sdm/libs/hwc/hwc_display_primary.h
similarity index 98%
rename from sdm845/sdm/libs/hwc/hwc_display_primary.h
rename to msm8909/sdm/libs/hwc/hwc_display_primary.h
index e937980..8a2ff87 100644
--- a/sdm845/sdm/libs/hwc/hwc_display_primary.h
+++ b/msm8909/sdm/libs/hwc/hwc_display_primary.h
@@ -69,6 +69,7 @@
BufferAllocator *buffer_allocator_ = nullptr;
CPUHint cpu_hint_;
+ bool handle_idle_timeout_ = false;
// Primary output buffer configuration
LayerBuffer output_buffer_ = {};
diff --git a/sdm845/sdm/libs/hwc/hwc_display_virtual.cpp b/msm8909/sdm/libs/hwc/hwc_display_virtual.cpp
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_display_virtual.cpp
rename to msm8909/sdm/libs/hwc/hwc_display_virtual.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_display_virtual.h b/msm8909/sdm/libs/hwc/hwc_display_virtual.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_display_virtual.h
rename to msm8909/sdm/libs/hwc/hwc_display_virtual.h
diff --git a/sdm845/sdm/libs/hwc/hwc_session.cpp b/msm8909/sdm/libs/hwc/hwc_session.cpp
similarity index 97%
rename from sdm845/sdm/libs/hwc/hwc_session.cpp
rename to msm8909/sdm/libs/hwc/hwc_session.cpp
index 98e14ee..3159440 100644
--- a/sdm845/sdm/libs/hwc/hwc_session.cpp
+++ b/msm8909/sdm/libs/hwc/hwc_session.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -289,7 +289,7 @@
}
if (hwc_session->need_invalidate_) {
- hwc_session->AsyncRefresh();
+ hwc_procs->invalidate(hwc_procs);
hwc_session->need_invalidate_ = false;
}
@@ -420,8 +420,6 @@
hwc_session->bw_mode_release_fd_ = dup(content_list->retireFenceFd);
}
- locker_.Signal();
-
// This is only indicative of how many times SurfaceFlinger posts
// frames to the display.
CALC_FPS();
@@ -695,14 +693,6 @@
return 0;
}
-static void PostRefresh(hwc_procs_t const *hwc_procs) {
- hwc_procs->invalidate(hwc_procs);
-}
-
-void HWCSession::AsyncRefresh() {
- future_ = std::async(PostRefresh, hwc_procs_);
-}
-
android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
SEQUENCE_WAIT_SCOPE_LOCK(locker_);
@@ -715,7 +705,7 @@
break;
case qService::IQService::SCREEN_REFRESH:
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case qService::IQService::SET_IDLE_TIMEOUT:
@@ -866,7 +856,7 @@
}
android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
+ android::Parcel *out) {
DisplayError error = kErrorNone;
int ret = 0;
uint32_t disp_id = UINT32(input_parcel->readInt32());
@@ -875,14 +865,14 @@
if (disp_id != HWC_DISPLAY_PRIMARY) {
DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
ret = -EINVAL;
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
DLOGE("primary display object is not instantiated");
ret = -EINVAL;
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
@@ -891,30 +881,31 @@
if (error == kErrorNone) {
if (!pending) {
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
} else if (error == kErrorNotSupported) {
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
} else {
ret = -EINVAL;
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
- AsyncRefresh();
+ // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
+ hwc_procs_->invalidate(hwc_procs_);
// Wait until partial update control is complete
ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
+ android::Parcel *output_parcel) {
int config = input_parcel->readInt32();
int dpy = input_parcel->readInt32();
int error = android::BAD_VALUE;
@@ -926,7 +917,7 @@
if (hwc_display_[dpy]) {
error = hwc_display_[dpy]->SetActiveDisplayConfig(config);
if (error == 0) {
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
}
}
@@ -1018,7 +1009,7 @@
DisplayPort sdm_disp_port = kPortDefault;
int hwc_disp_port = qdutils::DISPLAY_PORT_DEFAULT;
- if (dpy > HWC_DISPLAY_VIRTUAL) {
+ if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
return android::BAD_VALUE;
}
@@ -1137,7 +1128,7 @@
HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault;
// trigger invalidate to apply new bw caps.
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
error = core_intf_->SetMaxBandwidthMode(mode);
if (error != kErrorNone) {
@@ -1334,7 +1325,7 @@
switch (pending_action.action) {
case kInvalidating:
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kEnterQDCMMode:
ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
@@ -1345,12 +1336,12 @@
case kApplySolidFill:
ret = color_mgr_->SetSolidFill(pending_action.params,
true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kDisableSolidFill:
ret = color_mgr_->SetSolidFill(pending_action.params,
false, hwc_display_[HWC_DISPLAY_PRIMARY]);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kSetPanelBrightness:
brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
@@ -1364,7 +1355,7 @@
case kEnableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params,
true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kDisableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params,
@@ -1373,7 +1364,7 @@
case kConfigureDetailedEnhancer:
ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
hwc_display_[HWC_DISPLAY_PRIMARY]);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kInvalidatingAndkSetPanelBrightness:
brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
@@ -1383,7 +1374,7 @@
}
if (HWC_DISPLAY_PRIMARY == display_id)
ret = hwc_display_[HWC_DISPLAY_PRIMARY]->CachePanelBrightness(*brightness_value);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kNoAction:
break;
@@ -1469,7 +1460,7 @@
if (panel_reset == 0) {
if (hwc_procs_) {
reset_panel_ = true;
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
} else {
DLOGW("Ignore resetpanel - hwc_proc not registered");
}
@@ -1699,7 +1690,7 @@
android::Parcel *output_parcel) {
int dpy = input_parcel->readInt32();
- if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) {
+ if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
return android::BAD_VALUE;;
}
diff --git a/sdm845/sdm/libs/hwc/hwc_session.h b/msm8909/sdm/libs/hwc/hwc_session.h
similarity index 97%
rename from sdm845/sdm/libs/hwc/hwc_session.h
rename to msm8909/sdm/libs/hwc/hwc_session.h
index ce21c46..1cd3e33 100644
--- a/sdm845/sdm/libs/hwc/hwc_session.h
+++ b/msm8909/sdm/libs/hwc/hwc_session.h
@@ -28,7 +28,6 @@
#include <hardware/hwcomposer.h>
#include <core/core_interface.h>
#include <utils/locker.h>
-#include <future> // NOLINT
#include "hwc_display_primary.h"
#include "hwc_display_external.h"
@@ -89,7 +88,6 @@
int GetVsyncPeriod(int disp);
int CreateExternalDisplay(int disp, uint32_t primary_width, uint32_t primary_height,
bool use_primary_res);
- void AsyncRefresh();
// QClient methods
virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
@@ -105,8 +103,7 @@
android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
- android::status_t ControlPartialUpdate(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
+ android::status_t ControlPartialUpdate(const android::Parcel *input_parcel, android::Parcel *out);
android::status_t OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
android::status_t SetPanelBrightness(const android::Parcel *input_parcel,
@@ -154,7 +151,6 @@
qService::QService *qservice_ = NULL;
bool is_hdmi_primary_ = false;
bool is_hdmi_yuv_ = false;
- std::future<void> future_;
std::bitset<HWC_NUM_DISPLAY_TYPES> connected_displays_; // Bit mask of connected displays
HWCSocketHandler socket_handler_;
Locker uevent_locker_;
diff --git a/sdm845/sdm/libs/hwc/hwc_socket_handler.cpp b/msm8909/sdm/libs/hwc/hwc_socket_handler.cpp
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_socket_handler.cpp
rename to msm8909/sdm/libs/hwc/hwc_socket_handler.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_socket_handler.h b/msm8909/sdm/libs/hwc/hwc_socket_handler.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_socket_handler.h
rename to msm8909/sdm/libs/hwc/hwc_socket_handler.h
diff --git a/sdm845/sdm/libs/hwc/hwc_tonemapper.cpp b/msm8909/sdm/libs/hwc/hwc_tonemapper.cpp
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_tonemapper.cpp
rename to msm8909/sdm/libs/hwc/hwc_tonemapper.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_tonemapper.h b/msm8909/sdm/libs/hwc/hwc_tonemapper.h
similarity index 100%
rename from sdm845/sdm/libs/hwc/hwc_tonemapper.h
rename to msm8909/sdm/libs/hwc/hwc_tonemapper.h
diff --git a/sdm845/sdm/libs/hwc2/Android.mk b/msm8909/sdm/libs/hwc2/Android.mk
similarity index 73%
copy from sdm845/sdm/libs/hwc2/Android.mk
copy to msm8909/sdm/libs/hwc2/Android.mk
index 557b55f..2d03c13 100644
--- a/sdm845/sdm/libs/hwc2/Android.mk
+++ b/msm8909/sdm/libs/hwc2/Android.mk
@@ -15,18 +15,29 @@
-std=c++11 -fcolor-diagnostics\
-DLOG_TAG=\"SDM\" $(common_flags) \
-I $(display_top)/sdm/libs/hwc
+ifeq ($(TARGET_EXCLUDES_DISPLAY_PP), true)
+LOCAL_CFLAGS += -DEXCLUDE_DISPLAY_PP
+endif
+
LOCAL_CLANG := true
+# TODO: Remove libui after addressing gpu_tonemapper issues
LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware libhardware_legacy \
- libutils libcutils libsync libqdutils libqdMetaData libdl \
- libpowermanager libsdmutils libc++ liblog libgrallocutils \
+ libutils libcutils libsync libqdutils libqdMetaData libdl libdrmutils \
+ libsdmutils libc++ liblog libgrallocutils libdl \
+ vendor.display.config@1.0 libhidlbase libhidltransport \
libui libgpu_tonemapper
ifneq ($(TARGET_USES_GRALLOC1), true)
LOCAL_SHARED_LIBRARIES += libmemalloc
endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_1)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+endif
+
LOCAL_SRC_FILES := hwc_session.cpp \
+ hwc_session_services.cpp \
hwc_display.cpp \
hwc_display_primary.cpp \
hwc_display_external.cpp \
@@ -38,7 +49,9 @@
hwc_callbacks.cpp \
../hwc/cpuhint.cpp \
../hwc/hwc_socket_handler.cpp \
- hwc_tonemapper.cpp
+ display_null.cpp \
+ hwc_tonemapper.cpp \
+ hwc_display_external_test.cpp
ifneq ($(TARGET_USES_GRALLOC1), true)
LOCAL_SRC_FILES += ../hwc/hwc_buffer_allocator.cpp
diff --git a/msm8909/sdm/libs/hwc2/display_null.cpp b/msm8909/sdm/libs/hwc2/display_null.cpp
new file mode 100644
index 0000000..16f4da6
--- /dev/null
+++ b/msm8909/sdm/libs/hwc2/display_null.cpp
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "display_null.h"
+
+#define __CLASS__ "DisplayNull"
+
+namespace sdm {
+
+DisplayError DisplayNull::Commit(LayerStack *layer_stack) {
+ for (Layer *layer : layer_stack->layers) {
+ if (layer->composition != kCompositionGPUTarget) {
+ layer->composition = kCompositionSDE;
+ layer->input_buffer.release_fence_fd = -1;
+ }
+ }
+ layer_stack->retire_fence_fd = -1;
+
+ return kErrorNone;
+}
+
+DisplayError DisplayNull::GetDisplayState(DisplayState *state) {
+ *state = state_;
+ return kErrorNone;
+}
+
+DisplayError DisplayNull::SetDisplayState(DisplayState state) {
+ state_ = state;
+ return kErrorNone;
+}
+
+DisplayError DisplayNull::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
+ fb_config_ = variable_info;
+ return kErrorNone;
+}
+
+DisplayError DisplayNull::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
+ *variable_info = fb_config_;
+ return kErrorNone;
+}
+
+} // namespace sdm
diff --git a/msm8909/sdm/libs/hwc2/display_null.h b/msm8909/sdm/libs/hwc2/display_null.h
new file mode 100644
index 0000000..c2db54e
--- /dev/null
+++ b/msm8909/sdm/libs/hwc2/display_null.h
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DISPLAY_NULL_H__
+#define __DISPLAY_NULL_H__
+
+#include <core/display_interface.h>
+#include <string>
+#include <vector>
+
+namespace sdm {
+
+#define MAKE_NO_OP(virtual_method_name) \
+ virtual DisplayError virtual_method_name { return kErrorNone; }
+
+class DisplayNull : public DisplayInterface {
+ public:
+ virtual ~DisplayNull() { }
+ virtual DisplayError Commit(LayerStack *layer_stack);
+ virtual DisplayError GetDisplayState(DisplayState *state);
+ virtual DisplayError SetDisplayState(DisplayState state);
+ virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info);
+ virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
+ virtual bool IsUnderscanSupported() { return true; }
+ virtual void SetIdleTimeoutMs(uint32_t active_ms) { }
+ virtual bool IsPrimaryDisplay() { return true; }
+
+ void SetActive(bool active) {
+ active_ = active;
+ }
+
+ bool IsActive() {
+ return active_;
+ }
+
+ MAKE_NO_OP(Prepare(LayerStack *))
+ MAKE_NO_OP(Flush())
+ MAKE_NO_OP(GetNumVariableInfoConfigs(uint32_t *))
+ MAKE_NO_OP(GetConfig(uint32_t, DisplayConfigVariableInfo *))
+ MAKE_NO_OP(GetConfig(DisplayConfigFixedInfo *))
+ MAKE_NO_OP(GetActiveConfig(uint32_t *))
+ MAKE_NO_OP(GetVSyncState(bool *))
+ MAKE_NO_OP(SetActiveConfig(uint32_t))
+ MAKE_NO_OP(SetActiveConfig(DisplayConfigVariableInfo *))
+ MAKE_NO_OP(SetMaxMixerStages(uint32_t))
+ MAKE_NO_OP(ControlPartialUpdate(bool, uint32_t *))
+ MAKE_NO_OP(DisablePartialUpdateOneFrame())
+ MAKE_NO_OP(SetDisplayMode(uint32_t))
+ MAKE_NO_OP(SetPanelBrightness(int))
+ MAKE_NO_OP(CachePanelBrightness(int))
+ MAKE_NO_OP(OnMinHdcpEncryptionLevelChange(uint32_t))
+ MAKE_NO_OP(ColorSVCRequestRoute(const PPDisplayAPIPayload &, PPDisplayAPIPayload *,
+ PPPendingParams *))
+ MAKE_NO_OP(GetColorModeCount(uint32_t *))
+ MAKE_NO_OP(GetColorModes(uint32_t *, std::vector<std::string> *))
+ MAKE_NO_OP(GetColorModeAttr(const std::string &, AttrVal *))
+ MAKE_NO_OP(SetColorMode(const std::string &))
+ MAKE_NO_OP(SetColorModeById(int32_t))
+ MAKE_NO_OP(SetColorTransform(const uint32_t, const double *))
+ MAKE_NO_OP(GetDefaultColorMode(std::string *))
+ MAKE_NO_OP(ApplyDefaultDisplayMode())
+ MAKE_NO_OP(SetCursorPosition(int, int))
+ MAKE_NO_OP(GetRefreshRateRange(uint32_t *, uint32_t *))
+ MAKE_NO_OP(SetRefreshRate(uint32_t))
+ MAKE_NO_OP(GetPanelBrightness(int *))
+ MAKE_NO_OP(SetVSyncState(bool))
+ MAKE_NO_OP(SetMixerResolution(uint32_t, uint32_t))
+ MAKE_NO_OP(GetMixerResolution(uint32_t *, uint32_t *))
+ MAKE_NO_OP(SetDetailEnhancerData(const DisplayDetailEnhancerData &))
+ MAKE_NO_OP(GetDisplayPort(DisplayPort *))
+ MAKE_NO_OP(SetCompositionState(LayerComposition, bool))
+ MAKE_NO_OP(GetClientTargetSupport(uint32_t, uint32_t, LayerBufferFormat,
+ const ColorMetaData &))
+ std::string Dump() { return ""; }
+
+ private:
+ bool active_ = false;
+ DisplayState state_ = kStateOff;
+ DisplayConfigVariableInfo fb_config_ = {};
+};
+
+} // namespace sdm
+
+#endif // __DISPLAY_NULL_H__
diff --git a/sdm845/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/msm8909/sdm/libs/hwc2/hwc_buffer_allocator.cpp
similarity index 86%
copy from sdm845/sdm/libs/hwc2/hwc_buffer_allocator.cpp
copy to msm8909/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index 3c8d460..a179663 100644
--- a/sdm845/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -41,23 +41,45 @@
namespace sdm {
-HWCBufferAllocator::HWCBufferAllocator() {
+DisplayError HWCBufferAllocator::Init() {
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module_);
if (err != 0) {
- DLOGE("FATAL: can not open GRALLOC module");
- } else {
- gralloc1_open(module_, &gralloc_device_);
+ DLOGE("FATAL: can not get GRALLOC module");
+ return kErrorResources;
}
+
+ err = gralloc1_open(module_, &gralloc_device_);
+ if (err != 0) {
+ DLOGE("FATAL: can not open GRALLOC device");
+ return kErrorResources;
+ }
+
+ if (gralloc_device_ == nullptr) {
+ DLOGE("FATAL: gralloc device is null");
+ return kErrorResources;
+ }
+
ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
+ Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>(
+ gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK));
+ Unlock_ = reinterpret_cast<GRALLOC1_PFN_UNLOCK>(
+ gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_UNLOCK));
+
+ return kErrorNone;
}
-HWCBufferAllocator::~HWCBufferAllocator() {
+DisplayError HWCBufferAllocator::Deinit() {
if (gralloc_device_ != nullptr) {
- gralloc1_close(gralloc_device_);
+ int err = gralloc1_close(gralloc_device_);
+ if (err != 0) {
+ DLOGE("FATAL: can not close GRALLOC device");
+ return kErrorResources;
+ }
}
+ return kErrorNone;
}
DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
@@ -76,6 +98,10 @@
alloc_flags |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
}
+ if (buffer_config.secure_camera) {
+ alloc_flags |= GRALLOC1_PRODUCER_USAGE_CAMERA;
+ }
+
if (!buffer_config.cache) {
// Allocate uncached buffers
alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
@@ -86,7 +112,7 @@
}
uint64_t producer_usage = alloc_flags;
- uint64_t consumer_usage = alloc_flags;
+ uint64_t consumer_usage = (alloc_flags | GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
// CreateBuffer
private_handle_t *hnd = nullptr;
Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format,
@@ -95,6 +121,8 @@
if (hnd) {
alloc_buffer_info->fd = hnd->fd;
alloc_buffer_info->stride = UINT32(hnd->width);
+ alloc_buffer_info->aligned_width = UINT32(hnd->width);
+ alloc_buffer_info->aligned_height = UINT32(hnd->height);
alloc_buffer_info->size = hnd->size;
} else {
DLOGE("Failed to allocate memory");
@@ -133,6 +161,9 @@
if (alloc_type & GRALLOC_USAGE_HW_FB) {
consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
}
+ if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
+ producer_usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ }
Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format,
producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled);
@@ -354,4 +385,25 @@
return kErrorNone;
}
+DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) {
+ void* buffer_ptr = NULL;
+ const gralloc1_rect_t accessRegion = {
+ .left = 0,
+ .top = 0,
+ .width = 0,
+ .height = 0
+ };
+ Lock_(gralloc_device_, handle, GRALLOC1_PRODUCER_USAGE_CPU_READ, GRALLOC1_CONSUMER_USAGE_NONE,
+ &accessRegion, &buffer_ptr, acquire_fence);
+ if (!buffer_ptr) {
+ return kErrorUndefined;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWCBufferAllocator::UnmapBuffer(const private_handle_t *handle, int* release_fence) {
+ return (DisplayError)(Unlock_(gralloc_device_, handle, release_fence));
+}
+
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_buffer_allocator.h b/msm8909/sdm/libs/hwc2/hwc_buffer_allocator.h
similarity index 91%
copy from sdm845/sdm/libs/hwc2/hwc_buffer_allocator.h
copy to msm8909/sdm/libs/hwc2/hwc_buffer_allocator.h
index d574401..2cc50b1 100644
--- a/sdm845/sdm/libs/hwc2/hwc_buffer_allocator.h
+++ b/msm8909/sdm/libs/hwc2/hwc_buffer_allocator.h
@@ -45,9 +45,8 @@
class HWCBufferAllocator : public BufferAllocator {
public:
- HWCBufferAllocator();
- ~HWCBufferAllocator();
-
+ DisplayError Init();
+ DisplayError Deinit();
DisplayError AllocateBuffer(BufferInfo *buffer_info);
DisplayError FreeBuffer(BufferInfo *buffer_info);
uint32_t GetBufferSize(BufferInfo *buffer_info);
@@ -61,12 +60,16 @@
uint32_t stride[4], uint32_t offset[4],
uint32_t *num_planes);
int SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags);
+ DisplayError MapBuffer(const private_handle_t *handle, int acquire_fence);
+ DisplayError UnmapBuffer(const private_handle_t *handle, int* release_fence);
private:
gralloc1_device_t *gralloc_device_ = nullptr;
const hw_module_t *module_;
GRALLOC1_PFN_RELEASE ReleaseBuffer_ = nullptr;
GRALLOC1_PFN_PERFORM Perform_ = nullptr;
+ GRALLOC1_PFN_LOCK Lock_ = nullptr;
+ GRALLOC1_PFN_UNLOCK Unlock_ = nullptr;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_callbacks.cpp b/msm8909/sdm/libs/hwc2/hwc_callbacks.cpp
similarity index 78%
rename from sdm845/sdm/libs/hwc2/hwc_callbacks.cpp
rename to msm8909/sdm/libs/hwc2/hwc_callbacks.cpp
index 48ae398..3be3bf6 100644
--- a/sdm845/sdm/libs/hwc2/hwc_callbacks.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_callbacks.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -34,22 +34,28 @@
namespace sdm {
-void HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
- if (hotplug_) {
- hotplug_(hotplug_data_, display, INT32(state));
+HWC2::Error HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
+ if (!hotplug_) {
+ return HWC2::Error::NoResources;
}
+ hotplug_(hotplug_data_, display, INT32(state));
+ return HWC2::Error::None;
}
-void HWCCallbacks::Refresh(hwc2_display_t display) {
- if (refresh_) {
- refresh_(refresh_data_, display);
+HWC2::Error HWCCallbacks::Refresh(hwc2_display_t display) {
+ if (!refresh_) {
+ return HWC2::Error::NoResources;
}
+ refresh_(refresh_data_, display);
+ return HWC2::Error::None;
}
-void HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
- if (vsync_) {
- vsync_(vsync_data_, display, timestamp);
+HWC2::Error HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
+ if (!vsync_) {
+ return HWC2::Error::NoResources;
}
+ vsync_(vsync_data_, display, timestamp);
+ return HWC2::Error::None;
}
HWC2::Error HWCCallbacks::Register(HWC2::Callback descriptor, hwc2_callback_data_t callback_data,
diff --git a/sdm845/sdm/libs/hwc2/hwc_callbacks.h b/msm8909/sdm/libs/hwc2/hwc_callbacks.h
similarity index 92%
rename from sdm845/sdm/libs/hwc2/hwc_callbacks.h
rename to msm8909/sdm/libs/hwc2/hwc_callbacks.h
index 015bf5d..d3f4e52 100644
--- a/sdm845/sdm/libs/hwc2/hwc_callbacks.h
+++ b/msm8909/sdm/libs/hwc2/hwc_callbacks.h
@@ -40,9 +40,9 @@
class HWCCallbacks {
public:
- void Hotplug(hwc2_display_t display, HWC2::Connection state);
- void Refresh(hwc2_display_t display);
- void Vsync(hwc2_display_t display, int64_t timestamp);
+ HWC2::Error Hotplug(hwc2_display_t display, HWC2::Connection state);
+ HWC2::Error Refresh(hwc2_display_t display);
+ HWC2::Error Vsync(hwc2_display_t display, int64_t timestamp);
HWC2::Error Register(HWC2::Callback, hwc2_callback_data_t callback_data,
hwc2_function_pointer_t pointer);
diff --git a/sdm845/sdm/libs/hwc2/hwc_color_manager.cpp b/msm8909/sdm/libs/hwc2/hwc_color_manager.cpp
similarity index 91%
rename from sdm845/sdm/libs/hwc2/hwc_color_manager.cpp
rename to msm8909/sdm/libs/hwc2/hwc_color_manager.cpp
index 9f336a0..5578fde 100644
--- a/sdm845/sdm/libs/hwc2/hwc_color_manager.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_color_manager.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,7 +28,6 @@
*/
#include <dlfcn.h>
-#include <powermanager/IPowerManager.h>
#include <cutils/sockets.h>
#include <cutils/native_handle.h>
#include <utils/String16.h>
@@ -38,7 +37,6 @@
#include <hardware/hwcomposer_defs.h>
#include <QService.h>
-#include <core/dump_interface.h>
#include <utils/constants.h>
#include <utils/debug.h>
#include <core/buffer_allocator.h>
@@ -235,7 +233,7 @@
return -EFAULT;
} else {
frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer);
- frame_capture_data->buffer_stride = buffer_info.buffer_config.width;
+ frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.stride;
frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size;
}
ret = hwc_display->FrameCaptureAsync(buffer_info, 1);
@@ -272,7 +270,6 @@
PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
if (de_tuning_cfg_data->cfg_pending == true) {
if (!de_tuning_cfg_data->cfg_en) {
- de_data.override_flags = kOverrideDEEnable;
de_data.enable = 0;
} else {
de_data.override_flags = kOverrideDEEnable;
@@ -386,17 +383,6 @@
// retrieve system GPU idle timeout value for later to recover.
mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs());
-
- // acquire the binder handle to Android system PowerManager for later use.
- android::sp<android::IBinder> binder =
- android::defaultServiceManager()->checkService(android::String16("power"));
- if (binder == NULL) {
- DLOGW("Application can't connect to power manager service");
- delete mode_mgr;
- mode_mgr = NULL;
- } else {
- mode_mgr->power_mgr_ = android::interface_cast<android::IPowerManager>(binder);
- }
}
return mode_mgr;
@@ -407,30 +393,6 @@
::close(socket_fd_);
}
-int HWCQDCMModeManager::AcquireAndroidWakeLock(bool enable) {
- int ret = 0;
-
- if (enable) {
- if (wakelock_token_ == NULL) {
- android::sp<android::IBinder> binder = new android::BBinder();
- android::status_t status = power_mgr_->acquireWakeLock(
- (kFullWakeLock | kAcquireCauseWakeup | kONAfterRelease), binder,
- android::String16(kTagName), android::String16(kPackageName));
- if (status == android::NO_ERROR) {
- wakelock_token_ = binder;
- }
- }
- } else {
- if (wakelock_token_ != NULL && power_mgr_ != NULL) {
- power_mgr_->releaseWakeLock(wakelock_token_, 0);
- wakelock_token_.clear();
- wakelock_token_ = NULL;
- }
- }
-
- return ret;
-}
-
int HWCQDCMModeManager::EnableActiveFeatures(bool enable,
const HWCQDCMModeManager::ActiveFeatureCMD &cmds,
bool *was_running) {
@@ -486,7 +448,6 @@
ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature],
&cabl_was_running_);
- ret = AcquireAndroidWakeLock(enable);
// if enter QDCM mode, disable GPU fallback idle timeout.
if (hwc_display) {
@@ -497,4 +458,4 @@
return ret;
}
-} // namespace sdm
+} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_color_manager.h b/msm8909/sdm/libs/hwc2/hwc_color_manager.h
similarity index 97%
rename from sdm845/sdm/libs/hwc2/hwc_color_manager.h
rename to msm8909/sdm/libs/hwc2/hwc_color_manager.h
index 62d5535..f88a5bb 100644
--- a/sdm845/sdm/libs/hwc2/hwc_color_manager.h
+++ b/msm8909/sdm/libs/hwc2/hwc_color_manager.h
@@ -32,7 +32,6 @@
#include <stdlib.h>
#include <binder/Parcel.h>
-#include <powermanager/IPowerManager.h>
#include <binder/BinderService.h>
#include <core/sdm_types.h>
#include <utils/locker.h>
@@ -94,7 +93,6 @@
bool cabl_was_running_ = false;
int socket_fd_ = -1;
android::sp<android::IBinder> wakelock_token_ = NULL;
- android::sp<android::IPowerManager> power_mgr_ = NULL;
uint32_t entry_timeout_ = 0;
static const char *const kSocketName;
static const char *const kTagName;
diff --git a/sdm845/sdm/libs/hwc2/hwc_display.cpp b/msm8909/sdm/libs/hwc2/hwc_display.cpp
similarity index 84%
copy from sdm845/sdm/libs/hwc2/hwc_display.cpp
copy to msm8909/sdm/libs/hwc2/hwc_display.cpp
index 4f623ce..3a159ba 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_display.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -54,6 +54,8 @@
namespace sdm {
+std::bitset<kDisplayMax> HWCDisplay::validated_ = 0;
+
// This weight function is needed because the color primaries are not sorted by gamut size
static ColorPrimaries WidestPrimaries(ColorPrimaries p1, ColorPrimaries p2) {
int weight = 10;
@@ -87,8 +89,11 @@
uint32_t HWCColorMode::GetColorModeCount() {
uint32_t count = UINT32(color_mode_transform_map_.size());
DLOGI("Supported color mode count = %d", count);
-
+#ifdef EXCLUDE_DISPLAY_PP
+ return count;
+#else
return std::max(1U, count);
+#endif
}
HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
@@ -104,32 +109,35 @@
HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
// first mode in 2D matrix is the mode (identity)
- if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
+ if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_P3) {
DLOGE("Could not find mode: %d", mode);
return HWC2::Error::BadParameter;
}
+ if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
+ return HWC2::Error::Unsupported;
+ }
+
auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
if (status != HWC2::Error::None) {
DLOGE("failed for mode = %d", mode);
}
+ DLOGV_IF(kTagClient, "Color mode %d successfully set.", mode);
return status;
}
-HWC2::Error HWCColorMode::SetColorModeById(int32_t color_mode_id) {
- DLOGI("Applying mode: %d", color_mode_id);
- DisplayError error = display_intf_->SetColorModeById(color_mode_id);
+HWC2::Error HWCColorMode::RestoreColorTransform() {
+ DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, color_matrix_);
if (error != kErrorNone) {
+ DLOGI_IF(kTagClient,"Failed to set Color Transform");
return HWC2::Error::BadParameter;
}
+
return HWC2::Error::None;
}
HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
- if (!matrix) {
- return HWC2::Error::BadParameter;
- }
-
+ DTRACE_SCOPED();
double color_matrix[kColorTransformMatrixCount] = {0};
CopyColorTransformMatrix(matrix, color_matrix);
@@ -162,7 +170,7 @@
// if the mode count is 1, then only native mode is supported, so just apply matrix w/o
// setting mode
- if (color_mode_transform_map_.size() > 1U) {
+ if (color_mode_transform_map_.size() > 1U && current_color_mode_ != mode) {
color_mode_transform = color_mode_transform_map_[mode][transform_hint];
DisplayError error = display_intf_->SetColorMode(color_mode_transform);
if (error != kErrorNone) {
@@ -170,6 +178,7 @@
// failure to force client composition
return HWC2::Error::Unsupported;
}
+ DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
}
if (use_matrix) {
@@ -184,7 +193,6 @@
current_color_mode_ = mode;
current_color_transform_ = hint;
CopyColorTransformMatrix(matrix, color_matrix_);
- DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
return HWC2::Error::None;
}
@@ -194,23 +202,25 @@
// SDM returns modes which is string combination of mode + transform.
DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
if (error != kErrorNone || (color_mode_count == 0)) {
+#ifndef EXCLUDE_DISPLAY_PP
DLOGW("GetColorModeCount failed, use native color mode");
PopulateTransform(HAL_COLOR_MODE_NATIVE, "native", "identity");
+#endif
return;
}
- DLOGV_IF(kTagQDCM, "Color Modes supported count = %d", color_mode_count);
+ DLOGV_IF(kTagClient, "Color Modes supported count = %d", color_mode_count);
const std::string color_transform = "identity";
std::vector<std::string> color_modes(color_mode_count);
error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
for (uint32_t i = 0; i < color_mode_count; i++) {
std::string &mode_string = color_modes.at(i);
- DLOGV_IF(kTagQDCM, "Color Mode[%d] = %s", i, mode_string.c_str());
+ DLOGV_IF(kTagClient, "Color Mode[%d] = %s", i, mode_string.c_str());
AttrVal attr;
error = display_intf_->GetColorModeAttr(mode_string, &attr);
+ std::string color_gamut, dynamic_range, pic_quality;
if (!attr.empty()) {
- std::string color_gamut, dynamic_range, pic_quality;
for (auto &it : attr) {
if (it.first.find(kColorGamutAttribute) != std::string::npos) {
color_gamut = it.second;
@@ -220,6 +230,10 @@
pic_quality = it.second;
}
}
+
+ DLOGV_IF(kTagClient, "color_gamut : %s, dynamic_range : %s, pic_quality : %s",
+ color_gamut.c_str(), dynamic_range.c_str(), pic_quality.c_str());
+
if (dynamic_range == kHdr) {
continue;
}
@@ -231,12 +245,15 @@
PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, color_transform);
} else if ((color_gamut == kDcip3) &&
(pic_quality.empty() || pic_quality == kStandard)) {
- PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string, color_transform);
+ PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
} else if ((color_gamut == kDisplayP3) &&
(pic_quality.empty() || pic_quality == kStandard)) {
PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
}
- } else {
+ }
+
+ // Look at the mode name, if no color gamut is found
+ if (color_gamut.empty()) {
if (mode_string.find("hal_native") != std::string::npos) {
PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, mode_string);
} else if (mode_string.find("hal_srgb") != std::string::npos) {
@@ -345,7 +362,8 @@
return -EINVAL;
}
- HWCDebugHandler::Get()->GetProperty("sys.hwc_disable_hdr", &disable_hdr_handling_);
+ validated_.reset();
+ HWCDebugHandler::Get()->GetProperty(DISABLE_HDR, &disable_hdr_handling_);
if (disable_hdr_handling_) {
DLOGI("HDR Handling disabled");
}
@@ -359,16 +377,25 @@
client_target_ = new HWCLayer(id_, buffer_allocator_);
int blit_enabled = 0;
- HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled);
+ HWCDebugHandler::Get()->GetProperty(DISABLE_BLIT_COMPOSITION_PROP, &blit_enabled);
if (needs_blit_ && blit_enabled) {
// TODO(user): Add blit engine when needed
}
+ error = display_intf_->GetNumVariableInfoConfigs(&num_configs_);
+ if (error != kErrorNone) {
+ DLOGE("Getting config count failed. Error = %d", error);
+ return -EINVAL;
+ }
+
tone_mapper_ = new HWCToneMapper(buffer_allocator_);
display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
current_refresh_rate_ = max_refresh_rate_;
+
+ GetUnderScanConfig();
DLOGI("Display created with id: %d", id_);
+
return 0;
}
@@ -380,6 +407,9 @@
}
delete client_target_;
+ for (auto hwc_layer : layer_set_) {
+ delete hwc_layer;
+ }
if (color_mode_) {
color_mode_->DeInit();
@@ -397,8 +427,8 @@
HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_, buffer_allocator_));
layer_map_.emplace(std::make_pair(layer->GetId(), layer));
*out_layer_id = layer->GetId();
- validated_ = false;
geometry_changes_ |= GeometryChanges::kAdded;
+ validated_.reset();
return HWC2::Error::None;
}
@@ -428,9 +458,9 @@
break;
}
}
- validated_ = false;
geometry_changes_ |= GeometryChanges::kRemoved;
+ validated_.reset();
return HWC2::Error::None;
}
@@ -440,13 +470,12 @@
display_rect_ = LayerRect();
metadata_refresh_rate_ = 0;
auto working_primaries = ColorPrimaries_BT709_5;
+ bool secure_display_active = false;
+ layer_stack_.flags.animating = animating_;
// Add one layer for fb target
// TODO(user): Add blit target layers
for (auto hwc_layer : layer_set_) {
- // Reset layer data which SDM may change
- hwc_layer->ResetPerFrameData();
-
Layer *layer = hwc_layer->GetSDMLayer();
layer->flags = {}; // Reset earlier flags
if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) {
@@ -455,12 +484,11 @@
layer->flags.solid_fill = true;
}
+ if (!hwc_layer->ValidateAndSetCSC()) {
#ifdef FEATURE_WIDE_COLOR
- if (!hwc_layer->SupportedDataspace()) {
- layer->flags.skip = true;
- DLOGW_IF(kTagStrategy, "Unsupported dataspace: 0x%x", hwc_layer->GetLayerDataspace());
- }
+ layer->flags.skip = true;
#endif
+ }
working_primaries = WidestPrimaries(working_primaries,
layer->input_buffer.color_metadata.colorPrimaries);
@@ -499,6 +527,10 @@
layer_stack_.flags.skip_present = true;
}
+ if (layer->input_buffer.flags.secure_display) {
+ secure_display_active = true;
+ }
+
if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
// Currently we support only one HWCursor & only at top most z-order
if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
@@ -519,7 +551,9 @@
// TODO(user): Move to a getter if this is needed at other places
hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
- ApplyScanAdjustment(&scaled_display_frame);
+ if (hwc_layer->GetGeometryChanges() & kDisplayFrame) {
+ ApplyScanAdjustment(&scaled_display_frame);
+ }
hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
// SDM requires these details even for solid fill
if (layer->flags.solid_fill) {
@@ -569,7 +603,19 @@
// TODO(user): Set correctly when SDM supports geometry_changes as bitmask
layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
// Append client target to the layer stack
- layer_stack_.layers.push_back(client_target_->GetSDMLayer());
+
+ Layer *sdm_client_target = client_target_->GetSDMLayer();
+ layer_stack_.layers.push_back(sdm_client_target);
+ // fall back frame composition to GPU when client target is 10bit
+ // TODO(user): clarify the behaviour from Client(SF) and SDM Extn -
+ // when handling 10bit FBT, as it would affect blending
+ if (Is10BitFormat(sdm_client_target->input_buffer.format)) {
+ // Must fall back to client composition
+ MarkLayersForClientComposition();
+ }
+
+ // set secure display
+ SetSecureDisplay(secure_display_active);
}
void HWCDisplay::BuildSolidFillStack() {
@@ -588,7 +634,6 @@
DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
return HWC2::Error::BadLayer;
}
- validated_ = false;
const auto layer = map_layer->second;
const auto z_range = layer_set_.equal_range(layer);
@@ -681,6 +726,8 @@
}
DisplayError error = display_intf_->SetDisplayState(state);
+ validated_.reset();
+
if (error == kErrorNone) {
flush_on_error_ = flush_on_error;
} else {
@@ -697,15 +744,20 @@
HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
int32_t dataspace) {
- DisplayConfigVariableInfo variable_config;
- display_intf_->GetFrameBufferConfig(&variable_config);
- // TODO(user): Support scaled configurations, other formats and other dataspaces
- if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
- width != variable_config.x_pixels || height != variable_config.y_pixels) {
- return HWC2::Error::Unsupported;
- } else {
- return HWC2::Error::None;
+ ColorMetaData color_metadata = {};
+ if (dataspace != HAL_DATASPACE_UNKNOWN) {
+ GetColorPrimary(dataspace, &(color_metadata.colorPrimaries));
+ GetTransfer(dataspace, &(color_metadata.transfer));
+ GetRange(dataspace, &(color_metadata.range));
}
+
+ LayerBufferFormat sdm_format = GetSDMFormat(format, 0);
+ if (display_intf_->GetClientTargetSupport(width, height, sdm_format,
+ color_metadata) != kErrorNone) {
+ return HWC2::Error::Unsupported;
+ }
+
+ return HWC2::Error::None;
}
HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
@@ -718,12 +770,15 @@
}
HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
- // TODO(user): Actually handle multiple configs
if (out_configs == nullptr) {
- *out_num_configs = 1;
- } else {
- *out_num_configs = 1;
- out_configs[0] = 0;
+ *out_num_configs = num_configs_;
+ return HWC2::Error::None;
+ }
+
+ *out_num_configs = num_configs_;
+
+ for (uint32_t i = 0; i < num_configs_; i++) {
+ out_configs[i] = i;
}
return HWC2::Error::None;
@@ -732,14 +787,18 @@
HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
int32_t *out_value) {
DisplayConfigVariableInfo variable_config;
- DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
- if (error != kErrorNone) {
- DLOGV("Get variable config failed. Error = %d", error);
- return HWC2::Error::BadDisplay;
- }
-
- if (config != 0) { // We only use config[0] - see TODO above
- return HWC2::Error::BadConfig;
+ // Get display attributes from config index only if resolution switch is supported.
+ // Otherwise always send mixer attributes. This is to support destination scaler.
+ if (num_configs_ > 1) {
+ if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
+ DLOGE("Get variable config failed");
+ return HWC2::Error::BadDisplay;
+ }
+ } else {
+ if (display_intf_->GetFrameBufferConfig(&variable_config) != kErrorNone) {
+ DLOGV("Get variable config failed");
+ return HWC2::Error::BadDisplay;
+ }
}
switch (attribute) {
@@ -806,14 +865,19 @@
}
}
-// TODO(user): Store configurations and hook them up here
HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
- if (out_config != nullptr) {
- *out_config = 0;
- return HWC2::Error::None;
- } else {
- return HWC2::Error::BadParameter;
+ if (out_config == nullptr) {
+ return HWC2::Error::BadDisplay;
}
+
+ uint32_t active_index = 0;
+ if (GetActiveDisplayConfig(&active_index) != kErrorNone) {
+ return HWC2::Error::BadConfig;
+ }
+
+ *out_config = active_index;
+
+ return HWC2::Error::None;
}
HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
@@ -833,15 +897,22 @@
client_target_->SetLayerBuffer(target, acquire_fence);
client_target_->SetLayerSurfaceDamage(damage);
- // Ignoring dataspace for now
+ if (client_target_->GetLayerDataspace() != dataspace) {
+ client_target_->SetLayerDataspace(dataspace);
+ Layer *sdm_layer = client_target_->GetSDMLayer();
+ // Data space would be validated at GetClientTargetSupport, so just use here.
+ sdm::GetSDMColorSpace(dataspace, &sdm_layer->input_buffer.color_metadata);
+ }
+
return HWC2::Error::None;
}
HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
- if (config != 0) {
+ if (SetActiveDisplayConfig(config) != kErrorNone) {
return HWC2::Error::BadConfig;
}
- // We have only one config right now - do nothing
+
+ validated_.reset();
return HWC2::Error::None;
}
@@ -859,6 +930,7 @@
}
DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
+ validated_.reset();
}
HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
@@ -884,6 +956,21 @@
return kErrorNone;
}
+DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
+ switch (event) {
+ case kIdleTimeout:
+ break;
+ case kThermalEvent:
+ validated_.reset();
+ break;
+ default:
+ DLOGW("Unknown event: %d", event);
+ break;
+ }
+
+ return kErrorNone;
+}
+
HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
layer_changes_.clear();
layer_requests_.clear();
@@ -903,6 +990,8 @@
flush_ = true;
}
return HWC2::Error::BadDisplay;
+ } else {
+ validated_.set(type_);
}
} else {
// Skip is not set
@@ -931,10 +1020,12 @@
if (requested_composition != device_composition) {
layer_changes_[hwc_layer->GetId()] = device_composition;
}
+ hwc_layer->ResetValidation();
}
+ client_target_->ResetValidation();
*out_num_types = UINT32(layer_changes_.size());
*out_num_requests = UINT32(layer_requests_.size());
- validated_ = true;
+ skip_validate_ = false;
if (*out_num_types > 0) {
return HWC2::Error::HasChanges;
} else {
@@ -947,7 +1038,7 @@
return HWC2::Error::None;
}
- if (!validated_) {
+ if (!validated_.test(type_)) {
return HWC2::Error::NotValidated;
}
@@ -969,10 +1060,11 @@
return HWC2::Error::None;
}
- if (!validated_) {
+ if (!validated_.test(type_)) {
DLOGW("Display is not validated");
return HWC2::Error::NotValidated;
}
+
*out_num_elements = UINT32(layer_changes_.size());
if (out_layers != nullptr && out_types != nullptr) {
int i = 0;
@@ -1002,18 +1094,19 @@
HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
uint32_t *out_num_elements, hwc2_layer_t *out_layers,
int32_t *out_layer_requests) {
- // No display requests for now
- // Use for sharing blit buffers and
- // writing wfd buffer directly to output if there is full GPU composition
- // and no color conversion needed
if (layer_set_.empty()) {
return HWC2::Error::None;
}
- if (!validated_) {
+ // No display requests for now
+ // Use for sharing blit buffers and
+ // writing wfd buffer directly to output if there is full GPU composition
+ // and no color conversion needed
+ if (!validated_.test(type_)) {
DLOGW("Display is not validated");
return HWC2::Error::NotValidated;
}
+
*out_display_requests = 0;
*out_num_elements = UINT32(layer_requests_.size());
if (out_layers != nullptr && out_layer_requests != nullptr) {
@@ -1068,8 +1161,12 @@
return HWC2::Error::None;
}
- if (!validated_) {
- DLOGW("Display is not validated");
+ if (skip_validate_ && !CanSkipValidate()) {
+ validated_.reset(type_);
+ }
+
+ if (!validated_.test(type_)) {
+ DLOGV_IF(kTagClient, "Display %d is not validated", id_);
return HWC2::Error::NotValidated;
}
@@ -1089,7 +1186,6 @@
}
}
error = display_intf_->Commit(&layer_stack_);
- validated_ = false;
if (error == kErrorNone) {
// A commit is successfully submitted, start flushing on failure now onwards.
@@ -1098,6 +1194,9 @@
if (error == kErrorShutDown) {
shutdown_pending_ = true;
return HWC2::Error::Unsupported;
+ } else if (error == kErrorNotValidated) {
+ validated_.reset(type_);
+ return HWC2::Error::NotValidated;
} else if (error != kErrorPermission) {
DLOGE("Commit failed. Error = %d", error);
// To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
@@ -1107,6 +1206,7 @@
}
}
+ skip_validate_ = true;
return HWC2::Error::None;
}
@@ -1116,6 +1216,7 @@
// Do no call flush on errors, if a successful buffer is never submitted.
if (flush_ && flush_on_error_) {
display_intf_->Flush();
+ validated_.reset();
}
if (tone_mapper_ && tone_mapper_->IsActive()) {
@@ -1129,6 +1230,7 @@
close(client_target_release_fence);
client_target_release_fence = -1;
}
+ client_target_->ResetGeometryChanges();
for (auto hwc_layer : layer_set_) {
hwc_layer->ResetGeometryChanges();
@@ -1140,15 +1242,19 @@
// release fences and discard fences from driver
if (swap_interval_zero_ || layer->flags.single_buffer) {
close(layer_buffer->release_fence_fd);
- layer_buffer->release_fence_fd = -1;
} else if (layer->composition != kCompositionGPU) {
hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
- layer_buffer->release_fence_fd = -1;
} else {
hwc_layer->PushReleaseFence(-1);
}
+ } else {
+ // In case of flush, we don't return an error to f/w, so it will get a release fence out of
+ // the hwc_layer's release fence queue. We should push a -1 to preserve release fence
+ // circulation semantics.
+ hwc_layer->PushReleaseFence(-1);
}
+ layer_buffer->release_fence_fd = -1;
if (layer_buffer->acquire_fence_fd >= 0) {
close(layer_buffer->acquire_fence_fd);
layer_buffer->acquire_fence_fd = -1;
@@ -1163,6 +1269,7 @@
layer_stack_.retire_fence_fd = -1;
}
*out_retire_fence = layer_stack_.retire_fence_fd;
+ layer_stack_.retire_fence_fd = -1;
if (dump_frame_count_) {
dump_frame_count_--;
@@ -1187,6 +1294,7 @@
if (display_intf_) {
error = display_intf_->SetMaxMixerStages(max_mixer_stages);
+ validated_.reset();
}
return error;
@@ -1336,7 +1444,9 @@
return;
}
- snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
+ DLOGI("dump_frame_count %d dump_input_layers %d", dump_frame_count_, dump_input_layers_);
+ snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
+ GetDisplayString());
if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
@@ -1363,29 +1473,51 @@
}
}
- if (pvt_handle && pvt_handle->base) {
- char dump_file_name[PATH_MAX];
- size_t result = 0;
+ DLOGI("Dump layer[%d] of %d pvt_handle %x pvt_handle->base %x", i, layer_stack_.layers.size(),
+ pvt_handle, pvt_handle? pvt_handle->base : 0);
- snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
- dir_path, i, pvt_handle->width, pvt_handle->height,
- qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
-
- FILE *fp = fopen(dump_file_name, "w+");
- if (fp) {
- result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
- fclose(fp);
- }
-
- DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
+ if (!pvt_handle) {
+ DLOGE("Buffer handle is null");
+ return;
}
+
+ if (!pvt_handle->base) {
+ DisplayError error = buffer_allocator_->MapBuffer(pvt_handle, -1);
+ if (error != kErrorNone) {
+ DLOGE("Failed to map buffer, error = %d", error);
+ return;
+ }
+ }
+
+ char dump_file_name[PATH_MAX];
+ size_t result = 0;
+
+ snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
+ dir_path, i, pvt_handle->width, pvt_handle->height,
+ qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
+
+ FILE *fp = fopen(dump_file_name, "w+");
+ if (fp) {
+ result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
+ fclose(fp);
+ }
+
+ int release_fence = -1;
+ DisplayError error = buffer_allocator_->UnmapBuffer(pvt_handle, &release_fence);
+ if (error != kErrorNone) {
+ DLOGE("Failed to unmap buffer, error = %d", error);
+ return;
+ }
+
+ DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
}
}
void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
char dir_path[PATH_MAX];
- snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
+ snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
+ GetDisplayString());
if (mkdir(dir_path, 777) != 0 && errno != EEXIST) {
DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
@@ -1461,19 +1593,24 @@
// Create rects to represent the new source and destination crops
LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
- LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels));
+ hwc_rect_t scaled_display_frame = {0, 0, INT(x_pixels), INT(y_pixels)};
+ ApplyScanAdjustment(&scaled_display_frame);
+ client_target_->SetLayerDisplayFrame(scaled_display_frame);
+
auto client_target_layer = client_target_->GetSDMLayer();
client_target_layer->src_rect = crop;
- client_target_layer->dst_rect = dst;
int aligned_width;
int aligned_height;
uint32_t usage = GRALLOC_USAGE_HW_FB;
int format = HAL_PIXEL_FORMAT_RGBA_8888;
- int ubwc_enabled = 0;
+ int ubwc_disabled = 0;
int flags = 0;
- HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
- if (ubwc_enabled == 1) {
+
+ // By default UBWC is enabled and below property is global enable/disable for all
+ // buffers allocated through gralloc , including framebuffer targets.
+ HWCDebugHandler::Get()->GetProperty(DISABLE_UBWC_PROP, &ubwc_disabled);
+ if (!ubwc_disabled) {
usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
}
@@ -1523,7 +1660,7 @@
*y_pixels = display_config.y_pixels;
}
-int HWCDisplay::SetDisplayStatus(uint32_t display_status) {
+int HWCDisplay::SetDisplayStatus(DisplayStatus display_status) {
int status = 0;
switch (display_status) {
@@ -1544,6 +1681,7 @@
if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ validated_.reset();
}
return status;
@@ -1554,9 +1692,18 @@
return HWC2::Error::None;
}
- if (GetHWCLayer(layer) == nullptr) {
+ HWCLayer *hwc_layer = GetHWCLayer(layer);
+ if (hwc_layer == nullptr) {
return HWC2::Error::BadLayer;
}
+ if (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Cursor) {
+ return HWC2::Error::None;
+ }
+ if (!skip_validate_ && validated_.test(type_)) {
+ // the device is currently in the middle of the validate/present sequence,
+ // cannot set the Position(as per HWC2 spec)
+ return HWC2::Error::NotValidated;
+ }
DisplayState state;
if (display_intf_->GetDisplayState(&state) == kErrorNone) {
@@ -1565,9 +1712,9 @@
}
}
- if (!validated_) {
- return HWC2::Error::NotValidated;
- }
+ // TODO(user): HWC1.5 was not letting SetCursorPosition before validateDisplay,
+ // but HWC2.0 doesn't let setting cursor position after validate before present.
+ // Need to revisit.
auto error = display_intf_->SetCursorPosition(x, y);
if (error != kErrorNone) {
@@ -1590,6 +1737,7 @@
return -1;
}
+ validated_.reset();
return 0;
}
@@ -1598,16 +1746,19 @@
auto layer = hwc_layer->GetSDMLayer();
layer->composition = kCompositionSDE;
}
+ validated_.set(type_);
}
void HWCDisplay::MarkLayersForClientComposition() {
- // ClientComposition - GPU comp, to acheive this, set skip flag so that
+ // ClientComposition - GPU comp, to achieve this, set skip flag so that
// SDM does not handle this layer and hwc_layer composition will be
// set correctly at the end of Prepare.
+ DLOGV_IF(kTagClient, "HWC Layers marked for GPU comp");
for (auto hwc_layer : layer_set_) {
Layer *layer = hwc_layer->GetSDMLayer();
layer->flags.skip = true;
}
+ layer_stack_.flags.skip_present = true;
}
void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
@@ -1615,10 +1766,12 @@
int HWCDisplay::SetPanelBrightness(int level) {
int ret = 0;
- if (display_intf_)
+ if (display_intf_) {
ret = display_intf_->SetPanelBrightness(level);
- else
+ validated_.reset();
+ } else {
ret = -EINVAL;
+ }
return ret;
}
@@ -1630,6 +1783,7 @@
int HWCDisplay::ToggleScreenUpdates(bool enable) {
display_paused_ = enable ? false : true;
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ validated_.reset();
return 0;
}
@@ -1722,12 +1876,19 @@
}
void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
- secure_display_active_ = secure_display_active;
+ if (secure_display_active_ != secure_display_active) {
+ DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
+ secure_display_active);
+ secure_display_active_ = secure_display_active;
+ skip_prepare_ = true;
+ }
return;
}
-int HWCDisplay::SetActiveDisplayConfig(int config) {
- return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1;
+int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
+ int status = (display_intf_->SetActiveConfig(config) == kErrorNone) ? 0 : -1;
+ validated_.reset();
+ return status;
}
int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
@@ -1743,7 +1904,7 @@
return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
}
-bool HWCDisplay::SingleLayerUpdating(void) {
+uint32_t HWCDisplay::GetUpdatingLayersCount(void) {
uint32_t updating_count = 0;
for (uint i = 0; i < layer_stack_.layers.size(); i++) {
@@ -1753,7 +1914,7 @@
}
}
- return (updating_count == 1);
+ return updating_count;
}
bool HWCDisplay::IsLayerUpdating(const Layer *layer) {
@@ -1819,7 +1980,7 @@
std::string HWCDisplay::Dump() {
std::ostringstream os;
- os << "-------------------------------" << std::endl;
+ os << "\n------------HWC----------------\n";
os << "HWC2 display_id: " << id_ << std::endl;
for (auto layer : layer_set_) {
auto sdm_layer = layer->GetSDMLayer();
@@ -1839,10 +2000,50 @@
os << " buffer_id: " << std::hex << "0x" << sdm_layer->input_buffer.buffer_id << std::dec
<< std::endl;
}
+
if (color_mode_) {
+ os << "\n----------Color Modes---------\n";
color_mode_->Dump(&os);
}
- os << "-------------------------------" << std::endl;
+
+ if (display_intf_) {
+ os << "\n------------SDM----------------\n";
+ os << display_intf_->Dump();
+ }
+
+ os << "\n";
+
return os.str();
}
+
+bool HWCDisplay::CanSkipValidate() {
+ // Layer Stack checks
+ if (layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) {
+ DLOGV_IF(kTagClient, "HDR content present with tone mapping enabled. Returning false.");
+ return false;
+ }
+
+ if (client_target_->NeedsValidation()) {
+ DLOGV_IF(kTagClient, "Framebuffer target needs validation. Returning false.");
+ return false;
+ }
+
+ for (auto hwc_layer : layer_set_) {
+ if (hwc_layer->NeedsValidation()) {
+ DLOGV_IF(kTagClient, "hwc_layer[%d] needs validation. Returning false.",
+ hwc_layer->GetId());
+ return false;
+ }
+
+ // Do not allow Skip Validate, if any layer needs GPU Composition.
+ if (hwc_layer->GetDeviceSelectedCompositionType() == HWC2::Composition::Client) {
+ DLOGV_IF(kTagClient, "hwc_layer[%d] is GPU composed. Returning false.",
+ hwc_layer->GetId());
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_display.h b/msm8909/sdm/libs/hwc2/hwc_display.h
similarity index 92%
copy from sdm845/sdm/libs/hwc2/hwc_display.h
copy to msm8909/sdm/libs/hwc2/hwc_display.h
index 1b04c84..0c69be7 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display.h
+++ b/msm8909/sdm/libs/hwc2/hwc_display.h
@@ -20,6 +20,7 @@
#ifndef __HWC_DISPLAY_H__
#define __HWC_DISPLAY_H__
+#include <sys/stat.h>
#include <QService.h>
#include <core/core_interface.h>
#include <hardware/hwcomposer.h>
@@ -60,8 +61,8 @@
uint32_t GetColorModeCount();
HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
HWC2::Error SetColorMode(android_color_mode_t mode);
- HWC2::Error SetColorModeById(int32_t color_mode_id);
HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
+ HWC2::Error RestoreColorTransform();
private:
static const uint32_t kColorTransformMatrixCount = 16;
@@ -92,6 +93,14 @@
class HWCDisplay : public DisplayEventHandler {
public:
+ enum DisplayStatus {
+ kDisplayStatusInvalid = -1,
+ kDisplayStatusOffline,
+ kDisplayStatusOnline,
+ kDisplayStatusPause,
+ kDisplayStatusResume,
+ };
+
virtual ~HWCDisplay() {}
virtual int Init();
virtual int Deinit();
@@ -106,14 +115,14 @@
virtual HWC2::PowerMode GetLastPowerMode();
virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
- virtual int SetDisplayStatus(uint32_t display_status);
+ virtual int SetDisplayStatus(DisplayStatus display_status);
virtual int OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
virtual int Perform(uint32_t operation, ...);
virtual void SetSecureDisplay(bool secure_display_active);
virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height);
virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
virtual void GetPanelResolution(uint32_t *width, uint32_t *height);
- virtual std::string Dump(void);
+ virtual std::string Dump();
// Captures frame output in the buffer specified by output_buffer_info. The API is
// non-blocking and the client is expected to check operation status later on.
@@ -132,24 +141,14 @@
}
// Display Configurations
- virtual int SetActiveDisplayConfig(int config);
+ virtual int SetActiveDisplayConfig(uint32_t config);
virtual int GetActiveDisplayConfig(uint32_t *config);
virtual int GetDisplayConfigCount(uint32_t *count);
virtual int GetDisplayAttributesForConfig(int config,
DisplayConfigVariableInfo *display_attributes);
- template <typename... Args>
- int32_t CallLayerFunction(hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args... ),
- Args... args) {
- auto status = HWC2::Error::BadLayer;
- validated_ = false;
- auto hwc_layer = GetHWCLayer(layer);
- if (hwc_layer != nullptr) {
- status = (hwc_layer->*member)(std::forward<Args>(args)...);
- }
-
- return INT32(status);
+ virtual int SetState(bool connected) {
+ return kErrorNotSupported;
}
-
int SetPanelBrightness(int level);
int GetPanelBrightness(int *level);
int ToggleScreenUpdates(bool enable);
@@ -162,6 +161,8 @@
void BuildLayerStack(void);
void BuildSolidFillStack(void);
HWCLayer *GetHWCLayer(hwc2_layer_t layer);
+ void ResetValidation() { validated_.reset(); }
+ uint32_t GetGeometryChanges() { return geometry_changes_; }
// HWC2 APIs
virtual HWC2::Error AcceptDisplayChanges(void);
@@ -172,7 +173,7 @@
virtual HWC2::Error SetColorMode(android_color_mode_t mode) {
return HWC2::Error::Unsupported;
}
- virtual HWC2::Error SetColorModeById(int32_t color_mode_id) {
+ virtual HWC2::Error RestoreColorTransform() {
return HWC2::Error::Unsupported;
}
virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint) {
@@ -209,15 +210,13 @@
float* out_max_luminance,
float* out_max_average_luminance,
float* out_min_luminance);
+ virtual HWC2::Error SetDisplayAnimating(bool animating) {
+ animating_ = animating;
+ validated_ = false;
+ return HWC2::Error::None;
+ }
protected:
- enum DisplayStatus {
- kDisplayStatusOffline = 0,
- kDisplayStatusOnline,
- kDisplayStatusPause,
- kDisplayStatusResume,
- };
-
// Maximum number of layers supported by display manager.
static const uint32_t kMaxLayerCount = 32;
@@ -229,6 +228,7 @@
virtual DisplayError VSync(const DisplayEventVSync &vsync);
virtual DisplayError Refresh();
virtual DisplayError CECMessage(char *message);
+ virtual DisplayError HandleEvent(DisplayEvent event);
virtual void DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence);
virtual HWC2::Error PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests);
virtual HWC2::Error CommitLayerStack(void);
@@ -241,18 +241,20 @@
void MarkLayersForGPUBypass(void);
void MarkLayersForClientComposition(void);
virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
- bool SingleLayerUpdating(void);
+ uint32_t GetUpdatingLayersCount(void);
bool IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions);
bool IsLayerUpdating(const Layer *layer);
uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
virtual void CloseAcquireFds();
virtual void ClearRequestFlags();
+ virtual void GetUnderScanConfig() { }
enum {
INPUT_LAYER_DUMP,
OUTPUT_LAYER_DUMP,
};
+ static std::bitset<kDisplayMax> validated_;
CoreInterface *core_intf_ = nullptr;
HWCCallbacks *callbacks_ = nullptr;
HWCBufferAllocator *buffer_allocator_ = NULL;
@@ -290,17 +292,20 @@
LayerRect solid_fill_rect_ = {};
uint32_t solid_fill_color_ = 0;
LayerRect display_rect_;
- bool validated_ = false;
bool color_tranform_failed_ = false;
HWCColorMode *color_mode_ = NULL;
HWCToneMapper *tone_mapper_ = nullptr;
+ uint32_t num_configs_ = 0;
int disable_hdr_handling_ = 0; // disables HDR handling.
private:
void DumpInputBuffers(void);
+ bool CanSkipValidate();
qService::QService *qservice_ = NULL;
DisplayClass display_class_;
uint32_t geometry_changes_ = GeometryChanges::kNone;
+ bool skip_validate_ = false;
+ bool animating_ = false;
};
inline int HWCDisplay::Perform(uint32_t operation, ...) {
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_external.cpp b/msm8909/sdm/libs/hwc2/hwc_display_external.cpp
similarity index 72%
copy from sdm845/sdm/libs/hwc2/hwc_display_external.cpp
copy to msm8909/sdm/libs/hwc2/hwc_display_external.cpp
index a8f8480..440d80a 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_external.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_display_external.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -64,6 +64,7 @@
error = hwc_display_external->GetMixerResolution(&external_width, &external_height);
if (error != kErrorNone) {
+ Destroy(hwc_display_external);
return -EINVAL;
}
@@ -75,7 +76,7 @@
external_height = primary_height;
} else {
int downscale_enabled = 0;
- HWCDebugHandler::Get()->GetProperty("sdm.debug.downscale_external", &downscale_enabled);
+ HWCDebugHandler::Get()->GetProperty(ENABLE_EXTERNAL_DOWNSCALE_PROP, &downscale_enabled);
if (downscale_enabled) {
GetDownscaleResolution(primary_width, primary_height, &external_width, &external_height);
}
@@ -121,8 +122,6 @@
return status;
}
- // TODO(user): SetRefreshRate need to follow new interface when added.
-
status = PrepareLayerStack(out_num_types, out_num_requests);
return status;
}
@@ -141,20 +140,12 @@
}
void HWCDisplayExternal::ApplyScanAdjustment(hwc_rect_t *display_frame) {
- if (display_intf_->IsUnderscanSupported()) {
+ if ((underscan_width_ <= 0) || (underscan_height_ <= 0)) {
return;
}
- // Read user defined width and height ratio
- int width = 0, height = 0;
- HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_width", &width);
- float width_ratio = FLOAT(width) / 100.0f;
- HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_height", &height);
- float height_ratio = FLOAT(height) / 100.0f;
-
- if (width_ratio == 0.0f || height_ratio == 0.0f) {
- return;
- }
+ float width_ratio = FLOAT(underscan_width_) / 100.0f;
+ float height_ratio = FLOAT(underscan_height_) / 100.0f;
uint32_t mixer_width = 0;
uint32_t mixer_height = 0;
@@ -187,6 +178,7 @@
if (secure_display_active_) {
DisplayError error = display_intf_->Flush();
+ validated_.reset();
if (error != kErrorNone) {
DLOGE("Flush failed. Error = %d", error);
}
@@ -215,4 +207,74 @@
}
}
+int HWCDisplayExternal::SetState(bool connected) {
+ DisplayError error = kErrorNone;
+ DisplayState state = kStateOff;
+ DisplayConfigVariableInfo fb_config = {};
+
+ if (connected) {
+ if (display_null_.IsActive()) {
+ error = core_intf_->CreateDisplay(type_, this, &display_intf_);
+ if (error != kErrorNone) {
+ DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p",
+ error, type_, this, &display_intf_);
+ return -EINVAL;
+ }
+
+ // Restore HDMI attributes when display is reconnected.
+ // This is to ensure that surfaceflinger & sdm are in sync.
+ display_null_.GetFrameBufferConfig(&fb_config);
+ int status = SetFrameBufferResolution(fb_config.x_pixels, fb_config.y_pixels);
+ if (status) {
+ DLOGW("Set frame buffer config failed. Error = %d", error);
+ return -1;
+ }
+
+ display_null_.GetDisplayState(&state);
+ display_intf_->SetDisplayState(state);
+ validated_.reset();
+
+ SetVsyncEnabled(HWC2::Vsync::Enable);
+
+ display_null_.SetActive(false);
+ DLOGI("Display is connected successfully.");
+ } else {
+ DLOGI("Display is already connected.");
+ }
+ } else {
+ if (!display_null_.IsActive()) {
+ // Preserve required attributes of HDMI display that surfaceflinger sees.
+ // Restore HDMI attributes when display is reconnected.
+ display_intf_->GetDisplayState(&state);
+ display_null_.SetDisplayState(state);
+
+ error = display_intf_->GetFrameBufferConfig(&fb_config);
+ if (error != kErrorNone) {
+ DLOGW("Get frame buffer config failed. Error = %d", error);
+ return -1;
+ }
+ display_null_.SetFrameBufferConfig(fb_config);
+
+ SetVsyncEnabled(HWC2::Vsync::Disable);
+ core_intf_->DestroyDisplay(display_intf_);
+ display_intf_ = &display_null_;
+
+ display_null_.SetActive(true);
+ DLOGI("Display is disconnected successfully.");
+ } else {
+ DLOGI("Display is already disconnected.");
+ }
+ }
+
+ return 0;
+}
+
+void HWCDisplayExternal::GetUnderScanConfig() {
+ if (!display_intf_->IsUnderscanSupported()) {
+ // Read user defined underscan width and height
+ HWCDebugHandler::Get()->GetProperty(EXTERNAL_ACTION_SAFE_WIDTH_PROP, &underscan_width_);
+ HWCDebugHandler::Get()->GetProperty(EXTERNAL_ACTION_SAFE_HEIGHT_PROP, &underscan_height_);
+ }
+}
+
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_external.h b/msm8909/sdm/libs/hwc2/hwc_display_external.h
similarity index 91%
rename from sdm845/sdm/libs/hwc2/hwc_display_external.h
rename to msm8909/sdm/libs/hwc2/hwc_display_external.h
index 802a77c..fbee6a3 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_external.h
+++ b/msm8909/sdm/libs/hwc2/hwc_display_external.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,6 +31,7 @@
#define __HWC_DISPLAY_EXTERNAL_H__
#include "hwc_display.h"
+#include "display_null.h"
namespace sdm {
@@ -47,13 +48,19 @@
virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
virtual HWC2::Error Present(int32_t *out_retire_fence);
virtual void SetSecureDisplay(bool secure_display_active);
+ virtual int SetState(bool connected);
private:
HWCDisplayExternal(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
HWCCallbacks *callbacks, qService::QService *qservice);
void ApplyScanAdjustment(hwc_rect_t *display_frame);
+ void GetUnderScanConfig();
static void GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height,
uint32_t *virtual_width, uint32_t *virtual_height);
+
+ DisplayNull display_null_;
+ int underscan_width_ = 0;
+ int underscan_height_ = 0;
};
} // namespace sdm
diff --git a/msm8909/sdm/libs/hwc2/hwc_display_external_test.cpp b/msm8909/sdm/libs/hwc2/hwc_display_external_test.cpp
new file mode 100644
index 0000000..fcbe326
--- /dev/null
+++ b/msm8909/sdm/libs/hwc2/hwc_display_external_test.cpp
@@ -0,0 +1,750 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <cutils/properties.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <utils/constants.h>
+#include <utils/debug.h>
+#include <utils/formats.h>
+#include <algorithm>
+#include <array>
+#include <sstream>
+#include <string>
+#include <fstream>
+
+#include "hwc_display_external_test.h"
+#include "hwc_debugger.h"
+
+#define __CLASS__ "HWCDisplayExternalTest"
+
+namespace sdm {
+
+using std::array;
+
+int HWCDisplayExternalTest::Create(CoreInterface *core_intf,
+ HWCBufferAllocator *buffer_allocator,
+ HWCCallbacks *callbacks,
+ qService::QService *qservice, uint32_t panel_bpp,
+ uint32_t pattern_type, HWCDisplay **hwc_display) {
+ HWCDisplay *hwc_external_test = new HWCDisplayExternalTest(core_intf, buffer_allocator,
+ callbacks, qservice,
+ panel_bpp, pattern_type);
+
+ int status = static_cast<HWCDisplayExternalTest *>(hwc_external_test)->Init();
+ if (status) {
+ delete hwc_external_test;
+ return status;
+ }
+
+ *hwc_display = hwc_external_test;
+
+ DLOGE("EXTERNAL panel_bpp %d, pattern_type %d", panel_bpp, pattern_type);
+
+ return status;
+}
+
+void HWCDisplayExternalTest::Destroy(HWCDisplay *hwc_display) {
+ static_cast<HWCDisplayExternalTest *>(hwc_display)->Deinit();
+
+ delete hwc_display;
+}
+
+HWCDisplayExternalTest::HWCDisplayExternalTest(CoreInterface *core_intf,
+ HWCBufferAllocator *buffer_allocator,
+ HWCCallbacks *callbacks,
+ qService::QService *qservice, uint32_t panel_bpp,
+ uint32_t pattern_type)
+ : HWCDisplay(core_intf, callbacks, kHDMI, HWC_DISPLAY_EXTERNAL, false, qservice,
+ DISPLAY_CLASS_EXTERNAL, buffer_allocator), panel_bpp_(panel_bpp),
+ pattern_type_(pattern_type) {
+}
+
+int HWCDisplayExternalTest::Init() {
+ uint32_t external_width = 0;
+ uint32_t external_height = 0;
+
+ int status = HWCDisplay::Init();
+ if (status) {
+ DLOGE("HWCDisplayExternalTest::Init status = %d ", status);
+ return status;
+ }
+
+ status = CreateLayerStack();
+ if (status) {
+ Deinit();
+ return status;
+ }
+
+ DisplayError error = HWCDisplay::GetMixerResolution(&external_width, &external_height);
+ if (error != kErrorNone) {
+ Deinit();
+ return -EINVAL;
+ }
+
+ status = HWCDisplay::SetFrameBufferResolution(external_width, external_height);
+ if (status) {
+ Deinit();
+ DLOGE("HWCDisplayExternalTest:: set fb resolution status = %d ", status);
+ return status;
+ }
+
+ return status;
+}
+
+int HWCDisplayExternalTest::Deinit() {
+ DestroyLayerStack();
+ return HWCDisplay::Deinit();
+}
+
+
+HWC2::Error HWCDisplayExternalTest::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
+ auto status = HWC2::Error::None;
+ if (secure_display_active_) {
+ MarkLayersForGPUBypass();
+ return status;
+ }
+
+ if (layer_set_.empty()) {
+ flush_ = true;
+ return status;
+ }
+
+ if (shutdown_pending_) {
+ return status;
+ }
+ DisplayError error = display_intf_->Prepare(&layer_stack_);
+ if (error != kErrorNone) {
+ if (error == kErrorShutDown) {
+ shutdown_pending_ = true;
+ } else if (error != kErrorPermission) {
+ DLOGE("Prepare failed. Error = %d", error);
+ // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
+ // so that previous buffer and fences are released, and override the error.
+ flush_ = true;
+ }
+ }
+
+ MarkLayersForGPUBypass();
+
+ return status;
+}
+
+HWC2::Error HWCDisplayExternalTest::Present(int32_t *out_retire_fence) {
+ auto status = HWC2::Error::None;
+
+ if (secure_display_active_) {
+ return status;
+ }
+
+ if (shutdown_pending_) {
+ return status;
+ }
+
+ DumpInputBuffer();
+
+ if (!flush_) {
+ DisplayError error = kErrorUndefined;
+ error = display_intf_->Commit(&layer_stack_);
+ if (error == kErrorNone) {
+ // A commit is successfully submitted, start flushing on failure now onwards.
+ flush_on_error_ = true;
+ } else {
+ if (error == kErrorShutDown) {
+ shutdown_pending_ = true;
+ return status;
+ } else if (error != kErrorPermission) {
+ DLOGE("Commit failed. Error = %d", error);
+ // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
+ // so that previous buffer and fences are released, and override the error.
+ flush_ = true;
+ }
+ }
+ }
+
+ return PostCommit(out_retire_fence);
+}
+
+void HWCDisplayExternalTest::SetSecureDisplay(bool secure_display_active) {
+ if (secure_display_active_ != secure_display_active) {
+ secure_display_active_ = secure_display_active;
+
+ if (secure_display_active_) {
+ DisplayError error = display_intf_->Flush();
+ if (error != kErrorNone) {
+ DLOGE("Flush failed. Error = %d", error);
+ }
+ }
+ }
+ return;
+}
+
+int HWCDisplayExternalTest::Perform(uint32_t operation, ...) {
+ return 0;
+}
+
+void HWCDisplayExternalTest::DumpInputBuffer() {
+ if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
+ return;
+ }
+
+ const char *dir_path = "/data/vendor/display/frame_dump_external";
+ uint32_t width = buffer_info_.alloc_buffer_info.aligned_width;
+ uint32_t height = buffer_info_.alloc_buffer_info.aligned_height;
+ string format_str = GetFormatString(buffer_info_.buffer_config.format);
+
+ char *buffer = reinterpret_cast<char *>(mmap(NULL, buffer_info_.alloc_buffer_info.size,
+ PROT_READ|PROT_WRITE, MAP_SHARED,
+ buffer_info_.alloc_buffer_info.fd, 0));
+ if (buffer == MAP_FAILED) {
+ DLOGW("mmap failed. err = %d", errno);
+ return;
+ }
+
+ if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
+ DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
+ return;
+ }
+
+ // if directory exists already, need to explicitly change the permission.
+ if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
+ DLOGW("Failed to change permissions on %s directory", dir_path);
+ return;
+ }
+
+ if (buffer) {
+ std::stringstream dump_file_name;
+ dump_file_name << dir_path;
+ dump_file_name << "/input_layer_" << width << "x" << height << "_" << format_str << ".raw";
+
+ std::fstream fs;
+ fs.open(dump_file_name.str().c_str(), std::fstream::in | std::fstream::out | std::fstream::app);
+ if (!fs.is_open()) {
+ DLOGI("File open failed %s", dump_file_name.str().c_str());
+ return;
+ }
+
+ fs.write(buffer, (std::streamsize)buffer_info_.alloc_buffer_info.size);
+ fs.close();
+
+ DLOGI("Frame Dump %s: is successful", dump_file_name.str().c_str());
+ }
+
+ // Dump only once as the content is going to be same for all draw cycles
+ if (dump_frame_count_) {
+ dump_frame_count_ = 0;
+ }
+
+ if (munmap(buffer, buffer_info_.alloc_buffer_info.size) != 0) {
+ DLOGW("munmap failed. err = %d", errno);
+ return;
+ }
+}
+
+void HWCDisplayExternalTest::CalcCRC(uint32_t color_val, std::bitset<16> *crc_data) {
+ std::bitset<16> color = {};
+ std::bitset<16> temp_crc = {};
+
+ switch (panel_bpp_) {
+ case kDisplayBpp18:
+ color = (color_val & 0xFC) << 8;
+ break;
+ case kDisplayBpp24:
+ color = color_val << 8;
+ break;
+ case kDisplayBpp30:
+ color = color_val << 6;
+ break;
+ default:
+ return;
+ }
+
+ temp_crc[15] = (*crc_data)[0] ^ (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[3] ^
+ (*crc_data)[4] ^ (*crc_data)[5] ^ (*crc_data)[6] ^ (*crc_data)[7] ^
+ (*crc_data)[8] ^ (*crc_data)[9] ^ (*crc_data)[10] ^ (*crc_data)[11] ^
+ (*crc_data)[12] ^ (*crc_data)[14] ^ (*crc_data)[15] ^ color[0] ^ color[1] ^
+ color[2] ^ color[3] ^ color[4] ^ color[5] ^ color[6] ^ color[7] ^ color[8] ^
+ color[9] ^ color[10] ^ color[11] ^ color[12] ^ color[14] ^ color[15];
+
+ temp_crc[14] = (*crc_data)[12] ^ (*crc_data)[13] ^ color[12] ^ color[13];
+ temp_crc[13] = (*crc_data)[11] ^ (*crc_data)[12] ^ color[11] ^ color[12];
+ temp_crc[12] = (*crc_data)[10] ^ (*crc_data)[11] ^ color[10] ^ color[11];
+ temp_crc[11] = (*crc_data)[9] ^ (*crc_data)[10] ^ color[9] ^ color[10];
+ temp_crc[10] = (*crc_data)[8] ^ (*crc_data)[9] ^ color[8] ^ color[9];
+ temp_crc[9] = (*crc_data)[7] ^ (*crc_data)[8] ^ color[7] ^ color[8];
+ temp_crc[8] = (*crc_data)[6] ^ (*crc_data)[7] ^ color[6] ^ color[7];
+ temp_crc[7] = (*crc_data)[5] ^ (*crc_data)[6] ^ color[5] ^ color[6];
+ temp_crc[6] = (*crc_data)[4] ^ (*crc_data)[5] ^ color[4] ^ color[5];
+ temp_crc[5] = (*crc_data)[3] ^ (*crc_data)[4] ^ color[3] ^ color[4];
+ temp_crc[4] = (*crc_data)[2] ^ (*crc_data)[3] ^ color[2] ^ color[3];
+ temp_crc[3] = (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[15] ^ color[1] ^ color[2] ^ color[15];
+ temp_crc[2] = (*crc_data)[0] ^ (*crc_data)[1] ^ (*crc_data)[14] ^ color[0] ^ color[1] ^ color[14];
+
+ temp_crc[1] = (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[3] ^ (*crc_data)[4] ^ (*crc_data)[5] ^
+ (*crc_data)[6] ^ (*crc_data)[7] ^ (*crc_data)[8] ^ (*crc_data)[9] ^
+ (*crc_data)[10] ^ (*crc_data)[11] ^ (*crc_data)[12] ^ (*crc_data)[13] ^
+ (*crc_data)[14] ^ color[1] ^ color[2] ^ color[3] ^ color[4] ^ color[5] ^ color[6] ^
+ color[7] ^ color[8] ^ color[9] ^ color[10] ^ color[11] ^ color[12] ^ color[13] ^
+ color[14];
+
+ temp_crc[0] = (*crc_data)[0] ^ (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[3] ^ (*crc_data)[4] ^
+ (*crc_data)[5] ^ (*crc_data)[6] ^ (*crc_data)[7] ^ (*crc_data)[8] ^ (*crc_data)[9] ^
+ (*crc_data)[10] ^ (*crc_data)[11] ^ (*crc_data)[12] ^ (*crc_data)[13] ^
+ (*crc_data)[15] ^ color[0] ^ color[1] ^ color[2] ^ color[3] ^ color[4] ^ color[5] ^
+ color[6] ^ color[7] ^ color[8] ^ color[9] ^ color[10] ^ color[11] ^ color[12] ^
+ color[13] ^ color[15];
+
+ (*crc_data) = temp_crc;
+}
+
+int HWCDisplayExternalTest::FillBuffer() {
+ uint8_t *buffer = reinterpret_cast<uint8_t *>(mmap(NULL, buffer_info_.alloc_buffer_info.size,
+ PROT_READ|PROT_WRITE, MAP_SHARED,
+ buffer_info_.alloc_buffer_info.fd, 0));
+ if (buffer == MAP_FAILED) {
+ DLOGE("mmap failed. err = %d", errno);
+ return -EFAULT;
+ }
+
+ switch (pattern_type_) {
+ case kPatternColorRamp:
+ GenerateColorRamp(buffer);
+ break;
+ case kPatternBWVertical:
+ GenerateBWVertical(buffer);
+ break;
+ case kPatternColorSquare:
+ GenerateColorSquare(buffer);
+ break;
+ default:
+ DLOGW("Invalid Pattern type %d", pattern_type_);
+ return -EINVAL;
+ }
+
+ if (munmap(buffer, buffer_info_.alloc_buffer_info.size) != 0) {
+ DLOGE("munmap failed. err = %d", errno);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int HWCDisplayExternalTest::GetStride(LayerBufferFormat format, uint32_t width, uint32_t *stride) {
+ switch (format) {
+ case kFormatRGBA8888:
+ case kFormatRGBA1010102:
+ *stride = width * 4;
+ break;
+ case kFormatRGB888:
+ *stride = width * 3;
+ break;
+ default:
+ DLOGE("Unsupported format type %d", format);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void HWCDisplayExternalTest::PixelCopy(uint32_t red, uint32_t green, uint32_t blue, uint32_t alpha,
+ uint8_t **buffer) {
+ LayerBufferFormat format = buffer_info_.buffer_config.format;
+
+ switch (format) {
+ case kFormatRGBA8888:
+ *(*buffer)++ = UINT8(red & 0xFF);
+ *(*buffer)++ = UINT8(green & 0xFF);
+ *(*buffer)++ = UINT8(blue & 0xFF);
+ *(*buffer)++ = UINT8(alpha & 0xFF);
+ break;
+ case kFormatRGB888:
+ *(*buffer)++ = UINT8(red & 0xFF);
+ *(*buffer)++ = UINT8(green & 0xFF);
+ *(*buffer)++ = UINT8(blue & 0xFF);
+ break;
+ case kFormatRGBA1010102:
+ // Lower 8 bits of red
+ *(*buffer)++ = UINT8(red & 0xFF);
+
+ // Upper 2 bits of Red + Lower 6 bits of green
+ *(*buffer)++ = UINT8(((green & 0x3F) << 2) | ((red >> 0x8) & 0x3));
+
+ // Upper 4 bits of green + Lower 4 bits of blue
+ *(*buffer)++ = UINT8(((blue & 0xF) << 4) | ((green >> 6) & 0xF));
+
+ // Upper 6 bits of blue + Lower 2 bits of alpha
+ *(*buffer)++ = UINT8(((alpha & 0x3) << 6) | ((blue >> 4) & 0x3F));
+ break;
+ default:
+ DLOGW("format not supported format = %d", format);
+ break;
+ }
+}
+
+void HWCDisplayExternalTest::GenerateColorRamp(uint8_t *buffer) {
+ uint32_t width = buffer_info_.buffer_config.width;
+ uint32_t height = buffer_info_.buffer_config.height;
+ LayerBufferFormat format = buffer_info_.buffer_config.format;
+ uint32_t aligned_width = buffer_info_.alloc_buffer_info.aligned_width;
+ uint32_t buffer_stride = 0;
+
+ uint32_t color_ramp = 0;
+ uint32_t start_color_val = 0;
+ uint32_t step_size = 1;
+ uint32_t ramp_width = 0;
+ uint32_t ramp_height = 0;
+ uint32_t shift_by = 0;
+
+ std::bitset<16> crc_red = {};
+ std::bitset<16> crc_green = {};
+ std::bitset<16> crc_blue = {};
+
+ switch (panel_bpp_) {
+ case kDisplayBpp18:
+ ramp_height = 64;
+ ramp_width = 64;
+ shift_by = 2;
+ break;
+ case kDisplayBpp24:
+ ramp_height = 64;
+ ramp_width = 256;
+ break;
+ case kDisplayBpp30:
+ ramp_height = 32;
+ ramp_width = 256;
+ start_color_val = 0x180;
+ break;
+ default:
+ return;
+ }
+
+ GetStride(format, aligned_width, &buffer_stride);
+
+ for (uint32_t loop_height = 0; loop_height < height; loop_height++) {
+ uint32_t color_value = start_color_val;
+ uint8_t *temp = buffer + (loop_height * buffer_stride);
+
+ for (uint32_t loop_width = 0; loop_width < width; loop_width++) {
+ if (color_ramp == kColorRedRamp) {
+ PixelCopy(color_value, 0, 0, 0, &temp);
+ CalcCRC(color_value, &crc_red);
+ CalcCRC(0, &crc_green);
+ CalcCRC(0, &crc_blue);
+ }
+ if (color_ramp == kColorGreenRamp) {
+ PixelCopy(0, color_value, 0, 0, &temp);
+ CalcCRC(0, &crc_red);
+ CalcCRC(color_value, &crc_green);
+ CalcCRC(0, &crc_blue);
+ }
+ if (color_ramp == kColorBlueRamp) {
+ PixelCopy(0, 0, color_value, 0, &temp);
+ CalcCRC(0, &crc_red);
+ CalcCRC(0, &crc_green);
+ CalcCRC(color_value, &crc_blue);
+ }
+ if (color_ramp == kColorWhiteRamp) {
+ PixelCopy(color_value, color_value, color_value, 0, &temp);
+ CalcCRC(color_value, &crc_red);
+ CalcCRC(color_value, &crc_green);
+ CalcCRC(color_value, &crc_blue);
+ }
+
+ color_value = (start_color_val + (((loop_width + 1) % ramp_width) * step_size)) << shift_by;
+ }
+
+ if (panel_bpp_ == kDisplayBpp30 && ((loop_height + 1) % ramp_height) == 0) {
+ if (start_color_val == 0x180) {
+ start_color_val = 0;
+ step_size = 4;
+ } else {
+ start_color_val = 0x180;
+ step_size = 1;
+ color_ramp = (color_ramp + 1) % 4;
+ }
+ continue;
+ }
+
+ if (((loop_height + 1) % ramp_height) == 0) {
+ color_ramp = (color_ramp + 1) % 4;
+ }
+ }
+
+ DLOGI("CRC red %x", crc_red.to_ulong());
+ DLOGI("CRC green %x", crc_green.to_ulong());
+ DLOGI("CRC blue %x", crc_blue.to_ulong());
+}
+
+void HWCDisplayExternalTest::GenerateBWVertical(uint8_t *buffer) {
+ uint32_t width = buffer_info_.buffer_config.width;
+ uint32_t height = buffer_info_.buffer_config.height;
+ LayerBufferFormat format = buffer_info_.buffer_config.format;
+ uint32_t aligned_width = buffer_info_.alloc_buffer_info.aligned_width;
+ uint32_t buffer_stride = 0;
+ uint32_t bits_per_component = panel_bpp_ / 3;
+ uint32_t max_color_val = (1 << bits_per_component) - 1;
+
+ std::bitset<16> crc_red = {};
+ std::bitset<16> crc_green = {};
+ std::bitset<16> crc_blue = {};
+
+ if (panel_bpp_ == kDisplayBpp18) {
+ max_color_val <<= 2;
+ }
+
+ GetStride(format, aligned_width, &buffer_stride);
+
+ for (uint32_t loop_height = 0; loop_height < height; loop_height++) {
+ uint32_t color = 0;
+ uint8_t *temp = buffer + (loop_height * buffer_stride);
+
+ for (uint32_t loop_width = 0; loop_width < width; loop_width++) {
+ if (color == kColorBlack) {
+ PixelCopy(0, 0, 0, 0, &temp);
+ CalcCRC(0, &crc_red);
+ CalcCRC(0, &crc_green);
+ CalcCRC(0, &crc_blue);
+ }
+ if (color == kColorWhite) {
+ PixelCopy(max_color_val, max_color_val, max_color_val, 0, &temp);
+ CalcCRC(max_color_val, &crc_red);
+ CalcCRC(max_color_val, &crc_green);
+ CalcCRC(max_color_val, &crc_blue);
+ }
+
+ color = (color + 1) % 2;
+ }
+ }
+
+ DLOGI("CRC red %x", crc_red.to_ulong());
+ DLOGI("CRC green %x", crc_green.to_ulong());
+ DLOGI("CRC blue %x", crc_blue.to_ulong());
+}
+
+void HWCDisplayExternalTest::GenerateColorSquare(uint8_t *buffer) {
+ uint32_t width = buffer_info_.buffer_config.width;
+ uint32_t height = buffer_info_.buffer_config.height;
+ LayerBufferFormat format = buffer_info_.buffer_config.format;
+ uint32_t aligned_width = buffer_info_.alloc_buffer_info.aligned_width;
+ uint32_t buffer_stride = 0;
+ uint32_t max_color_val = 0;
+ uint32_t min_color_val = 0;
+
+ std::bitset<16> crc_red = {};
+ std::bitset<16> crc_green = {};
+ std::bitset<16> crc_blue = {};
+
+ switch (panel_bpp_) {
+ case kDisplayBpp18:
+ max_color_val = 63 << 2; // CEA Dynamic range for 18bpp 0 - 63
+ min_color_val = 0;
+ break;
+ case kDisplayBpp24:
+ max_color_val = 235; // CEA Dynamic range for 24bpp 16 - 235
+ min_color_val = 16;
+ break;
+ case kDisplayBpp30:
+ max_color_val = 940; // CEA Dynamic range for 30bpp 64 - 940
+ min_color_val = 64;
+ break;
+ default:
+ return;
+ }
+
+ array<array<uint32_t, 3>, 8> colors = {{
+ {{max_color_val, max_color_val, max_color_val}}, // White Color
+ {{max_color_val, max_color_val, min_color_val}}, // Yellow Color
+ {{min_color_val, max_color_val, max_color_val}}, // Cyan Color
+ {{min_color_val, max_color_val, min_color_val}}, // Green Color
+ {{max_color_val, min_color_val, max_color_val}}, // Megenta Color
+ {{max_color_val, min_color_val, min_color_val}}, // Red Color
+ {{min_color_val, min_color_val, max_color_val}}, // Blue Color
+ {{min_color_val, min_color_val, min_color_val}}, // Black Color
+ }};
+
+ GetStride(format, aligned_width, &buffer_stride);
+
+ for (uint32_t loop_height = 0; loop_height < height; loop_height++) {
+ uint32_t color = 0;
+ uint8_t *temp = buffer + (loop_height * buffer_stride);
+
+ for (uint32_t loop_width = 0; loop_width < width; loop_width++) {
+ PixelCopy(colors[color][0], colors[color][1], colors[color][2], 0, &temp);
+ CalcCRC(colors[color][0], &crc_red);
+ CalcCRC(colors[color][1], &crc_green);
+ CalcCRC(colors[color][2], &crc_blue);
+
+ if (((loop_width + 1) % 64) == 0) {
+ color = (color + 1) % colors.size();
+ }
+ }
+
+ if (((loop_height + 1) % 64) == 0) {
+ std::reverse(colors.begin(), (colors.end() - 1));
+ }
+ }
+
+ DLOGI("CRC red %x", crc_red.to_ulong());
+ DLOGI("CRC green %x", crc_green.to_ulong());
+ DLOGI("CRC blue %x", crc_blue.to_ulong());
+}
+
+int HWCDisplayExternalTest::InitLayer(Layer *layer) {
+ uint32_t active_config = 0;
+ DisplayConfigVariableInfo var_info = {};
+
+ GetActiveDisplayConfig(&active_config);
+
+ GetDisplayAttributesForConfig(INT32(active_config), &var_info);
+
+ layer->flags.updating = 1;
+ layer->src_rect = LayerRect(0, 0, var_info.x_pixels, var_info.y_pixels);
+ layer->dst_rect = layer->src_rect;
+ layer->frame_rate = var_info.fps;
+ layer->blending = kBlendingPremultiplied;
+
+ layer->input_buffer.unaligned_width = var_info.x_pixels;
+ layer->input_buffer.unaligned_height = var_info.y_pixels;
+ buffer_info_.buffer_config.format = kFormatRGBA8888;
+
+ if (layer->composition != kCompositionGPUTarget) {
+ buffer_info_.buffer_config.width = var_info.x_pixels;
+ buffer_info_.buffer_config.height = var_info.y_pixels;
+ switch (panel_bpp_) {
+ case kDisplayBpp18:
+ case kDisplayBpp24:
+ buffer_info_.buffer_config.format = kFormatRGB888;
+ break;
+ case kDisplayBpp30:
+ buffer_info_.buffer_config.format = kFormatRGBA1010102;
+ break;
+ default:
+ DLOGW("panel bpp not supported %d", panel_bpp_);
+ return -EINVAL;
+ }
+ buffer_info_.buffer_config.buffer_count = 1;
+
+ int ret = buffer_allocator_->AllocateBuffer(&buffer_info_);
+ if (ret != 0) {
+ DLOGE("Buffer allocation failed. ret: %d", ret);
+ return -ENOMEM;
+ }
+
+ ret = FillBuffer();
+ if (ret != 0) {
+ buffer_allocator_->FreeBuffer(&buffer_info_);
+ return ret;
+ }
+
+ layer->input_buffer.width = buffer_info_.alloc_buffer_info.aligned_width;
+ layer->input_buffer.height = buffer_info_.alloc_buffer_info.aligned_height;
+ layer->input_buffer.size = buffer_info_.alloc_buffer_info.size;
+ layer->input_buffer.planes[0].fd = buffer_info_.alloc_buffer_info.fd;
+ layer->input_buffer.planes[0].stride = buffer_info_.alloc_buffer_info.stride;
+ layer->input_buffer.format = buffer_info_.buffer_config.format;
+
+ DLOGI("Input buffer WxH %dx%d format %s size %d fd %d stride %d", layer->input_buffer.width,
+ layer->input_buffer.height, GetFormatString(layer->input_buffer.format),
+ layer->input_buffer.size, layer->input_buffer.planes[0].fd,
+ layer->input_buffer.planes[0].stride);
+ }
+
+ return 0;
+}
+
+int HWCDisplayExternalTest::DeinitLayer(Layer *layer) {
+ if (layer->composition != kCompositionGPUTarget) {
+ int ret = buffer_allocator_->FreeBuffer(&buffer_info_);
+ if (ret != 0) {
+ DLOGE("Buffer deallocation failed. ret: %d", ret);
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+int HWCDisplayExternalTest::CreateLayerStack() {
+ for (uint32_t i = 0; i < (kTestLayerCnt + 1 /* one dummy gpu_target layer */); i++) {
+ Layer *layer = new Layer();
+
+ if (i == kTestLayerCnt) {
+ layer->composition = kCompositionGPUTarget;
+ }
+ DLOGE("External :: CreateLayerStack %d", i);
+ int ret = InitLayer(layer);
+ if (ret != 0) {
+ delete layer;
+ return ret;
+ }
+ layer_stack_.layers.push_back(layer);
+ }
+
+ return 0;
+}
+
+int HWCDisplayExternalTest::DestroyLayerStack() {
+ for (uint32_t i = 0; i < UINT32(layer_stack_.layers.size()); i++) {
+ Layer *layer = layer_stack_.layers.at(i);
+ int ret = DeinitLayer(layer);
+ if (ret != 0) {
+ return ret;
+ }
+ delete layer;
+ }
+ layer_stack_.layers = {};
+ return 0;
+}
+
+HWC2::Error HWCDisplayExternalTest::PostCommit(int32_t *out_retire_fence) {
+ auto status = HWC2::Error::None;
+ // Do no call flush on errors, if a successful buffer is never submitted.
+ if (flush_ && flush_on_error_) {
+ display_intf_->Flush();
+ }
+ if (!flush_) {
+ for (size_t i = 0; i < layer_stack_.layers.size(); i++) {
+ Layer *layer = layer_stack_.layers.at(i);
+ LayerBuffer &layer_buffer = layer->input_buffer;
+
+ close(layer_buffer.release_fence_fd);
+ layer_buffer.release_fence_fd = -1;
+ }
+ close(layer_stack_.retire_fence_fd);
+ layer_stack_.retire_fence_fd = -1;
+ *out_retire_fence = -1;
+ }
+
+ flush_ = false;
+ return status;
+}
+
+} // namespace sdm
+
diff --git a/msm8909/sdm/libs/hwc2/hwc_display_external_test.h b/msm8909/sdm/libs/hwc2/hwc_display_external_test.h
new file mode 100644
index 0000000..e2c13f5
--- /dev/null
+++ b/msm8909/sdm/libs/hwc2/hwc_display_external_test.h
@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HWC_DISPLAY_EXTERNAL_TEST_H__
+#define __HWC_DISPLAY_EXTERNAL_TEST_H__
+
+#include<bitset>
+
+#include "hwc_display.h"
+#include "hwc_buffer_allocator.h"
+
+namespace sdm {
+
+class HWCDisplayExternalTest : public HWCDisplay {
+ public:
+ static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
+ HWCCallbacks *callbacks, qService::QService *qservice,
+ uint32_t panel_bpp, uint32_t pattern_type, HWCDisplay **hwc_display);
+ static void Destroy(HWCDisplay *hwc_display);
+ virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
+ virtual HWC2::Error Present(int32_t *out_retire_fence);
+ virtual void SetSecureDisplay(bool secure_display_active);
+ virtual int Perform(uint32_t operation, ...);
+
+ protected:
+ BufferInfo buffer_info_ = {};
+ uint32_t panel_bpp_ = 0;
+ uint32_t pattern_type_ = 0;
+
+ enum ColorPatternType {
+ kPatternNone = 0,
+ kPatternColorRamp,
+ kPatternBWVertical,
+ kPatternColorSquare,
+ };
+
+ enum DisplayBpp {
+ kDisplayBpp18 = 18,
+ kDisplayBpp24 = 24,
+ kDisplayBpp30 = 30,
+ };
+
+ enum ColorRamp {
+ kColorRedRamp = 0,
+ kColorGreenRamp = 1,
+ kColorBlueRamp = 2,
+ kColorWhiteRamp = 3,
+ };
+
+ enum Colors {
+ kColorBlack = 0,
+ kColorWhite = 1,
+ };
+
+ private:
+ HWCDisplayExternalTest(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
+ HWCCallbacks *callbacks, qService::QService *qservice,
+ uint32_t panel_bpp, uint32_t pattern_type);
+ int Init();
+ int Deinit();
+ void DumpInputBuffer();
+ void CalcCRC(uint32_t color_value, std::bitset<16> *crc_data);
+ int FillBuffer();
+ int GetStride(LayerBufferFormat format, uint32_t width, uint32_t *stride);
+ void PixelCopy(uint32_t red, uint32_t green, uint32_t blue, uint32_t alpha, uint8_t **buffer);
+ void GenerateColorRamp(uint8_t *buffer);
+ void GenerateBWVertical(uint8_t *buffer);
+ void GenerateColorSquare(uint8_t *buffer);
+ int InitLayer(Layer *layer);
+ int DeinitLayer(Layer *layer);
+ int CreateLayerStack();
+ int DestroyLayerStack();
+ HWC2::Error PostCommit(int32_t *out_retire_fence);
+
+ static const uint32_t kTestLayerCnt = 1;
+};
+
+} // namespace sdm
+
+#endif // __HWC_DISPLAY_EXTERNAL_TEST_H__
+
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_primary.cpp b/msm8909/sdm/libs/hwc2/hwc_display_primary.cpp
similarity index 87%
copy from sdm845/sdm/libs/hwc2/hwc_display_primary.cpp
copy to msm8909/sdm/libs/hwc2/hwc_display_primary.cpp
index 2fcf2a9..5a6bddd 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -62,8 +62,8 @@
hwc_display_primary->GetMixerResolution(&primary_width, &primary_height);
int width = 0, height = 0;
- HWCDebugHandler::Get()->GetProperty("sdm.fb_size_width", &width);
- HWCDebugHandler::Get()->GetProperty("sdm.fb_size_height", &height);
+ HWCDebugHandler::Get()->GetProperty(FB_WIDTH_PROP, &width);
+ HWCDebugHandler::Get()->GetProperty(FB_HEIGHT_PROP, &height);
if (width > 0 && height > 0) {
primary_width = UINT32(width);
primary_height = UINT32(height);
@@ -102,7 +102,7 @@
use_metadata_refresh_rate_ = true;
int disable_metadata_dynfps = 0;
- HWCDebugHandler::Get()->GetProperty("persist.metadata_dynfps.disable", &disable_metadata_dynfps);
+ HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
if (disable_metadata_dynfps) {
use_metadata_refresh_rate_ = false;
}
@@ -113,6 +113,7 @@
}
color_mode_ = new HWCColorMode(display_intf_);
color_mode_->Init();
+ HWCDebugHandler::Get()->GetProperty(ENABLE_DEFAULT_COLOR_MODE, &default_mode_status_);
return status;
}
@@ -151,8 +152,10 @@
boot_animation_completed_ = true;
// Applying default mode after bootanimation is finished And
// If Data is Encrypted, it is ready for access.
- if (display_intf_)
+ if (display_intf_) {
display_intf_->ApplyDefaultDisplayMode();
+ RestoreColorTransform();
+ }
}
}
@@ -160,18 +163,24 @@
auto status = HWC2::Error::None;
DisplayError error = kErrorNone;
+ if (default_mode_status_ && !boot_animation_completed_) {
+ ProcessBootAnimCompleted();
+ }
+
if (display_paused_) {
MarkLayersForGPUBypass();
return status;
}
+
+ // Fill in the remaining blanks in the layers and add them to the SDM layerstack
+ BuildLayerStack();
+
if (color_tranform_failed_) {
// Must fall back to client composition
MarkLayersForClientComposition();
}
- // Fill in the remaining blanks in the layers and add them to the SDM layerstack
- BuildLayerStack();
// Checks and replaces layer stack for solid fill
SolidFillPrepare();
@@ -184,19 +193,31 @@
layer_stack_.flags.post_processed_output = post_processed_output_;
}
- bool one_updating_layer = SingleLayerUpdating();
- ToggleCPUHint(one_updating_layer);
+ uint32_t num_updating_layers = GetUpdatingLayersCount();
+ bool one_updating_layer = (num_updating_layers == 1);
+ if (num_updating_layers != 0) {
+ ToggleCPUHint(one_updating_layer);
+ }
uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
- bool final_rate = force_refresh_rate_ ? true : false;
- error = display_intf_->SetRefreshRate(refresh_rate, final_rate);
+ if (current_refresh_rate_ != refresh_rate || handle_idle_timeout_) {
+ error = display_intf_->SetRefreshRate(refresh_rate);
+ }
+
if (error == kErrorNone) {
// On success, set current refresh rate to new refresh rate
current_refresh_rate_ = refresh_rate;
}
+ if (handle_idle_timeout_) {
+ handle_idle_timeout_ = false;
+ }
+
if (layer_set_.empty()) {
- flush_ = true;
+ // Avoid flush for Command mode panel.
+ DisplayConfigFixedInfo display_config;
+ display_intf_->GetConfig(&display_config);
+ flush_ = !display_config.is_cmdmode;
return status;
}
@@ -246,14 +267,15 @@
}
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ validated_.reset();
return status;
}
-HWC2::Error HWCDisplayPrimary::SetColorModeById(int32_t color_mode_id) {
- auto status = color_mode_->SetColorModeById(color_mode_id);
+HWC2::Error HWCDisplayPrimary::RestoreColorTransform() {
+ auto status = color_mode_->RestoreColorTransform();
if (status != HWC2::Error::None) {
- DLOGE("failed for mode = %d", color_mode_id);
+ DLOGE("failed to RestoreColorTransform");
return status;
}
@@ -269,7 +291,7 @@
}
auto status = color_mode_->SetColorTransform(matrix, hint);
- if (status != HWC2::Error::None) {
+ if ((hint != HAL_COLOR_TRANSFORM_IDENTITY) && (status != HWC2::Error::None)) {
DLOGE("failed for hint = %d", hint);
color_tranform_failed_ = true;
return status;
@@ -277,6 +299,7 @@
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
color_tranform_failed_ = false;
+ validated_.reset();
return status;
}
@@ -318,6 +341,7 @@
return -EINVAL;
}
va_end(args);
+ validated_.reset();
return 0;
}
@@ -335,7 +359,7 @@
void HWCDisplayPrimary::SetMetaDataRefreshRateFlag(bool enable) {
int disable_metadata_dynfps = 0;
- HWCDebugHandler::Get()->GetProperty("persist.metadata_dynfps.disable", &disable_metadata_dynfps);
+ HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
if (disable_metadata_dynfps) {
return;
}
@@ -365,9 +389,12 @@
DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
secure_display_active);
secure_display_active_ = secure_display_active;
- skip_prepare_ = true;
+
+ // Avoid flush for Command mode panel.
+ DisplayConfigFixedInfo display_config;
+ display_intf_->GetConfig(&display_config);
+ skip_prepare_ = !display_config.is_cmdmode;
}
- return;
}
void HWCDisplayPrimary::ForceRefreshRate(uint32_t refresh_rate) {
@@ -387,6 +414,8 @@
uint32_t HWCDisplayPrimary::GetOptimalRefreshRate(bool one_updating_layer) {
if (force_refresh_rate_) {
return force_refresh_rate_;
+ } else if (handle_idle_timeout_) {
+ return min_refresh_rate_;
} else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
return metadata_refresh_rate_;
}
@@ -398,12 +427,14 @@
DisplayError error = kErrorNone;
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ handle_idle_timeout_ = true;
return error;
}
void HWCDisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
display_intf_->SetIdleTimeoutMs(timeout_ms);
+ validated_.reset();
}
static void SetLayerBuffer(const BufferInfo &output_buffer_info, LayerBuffer *output_buffer) {
@@ -503,6 +534,7 @@
output_buffer_base_ = buffer;
post_processed_output_ = true;
DisablePartialUpdateOneFrame();
+ validated_.reset();
}
int HWCDisplayPrimary::FrameCaptureAsync(const BufferInfo &output_buffer_info,
@@ -521,12 +553,12 @@
GetPanelResolution(&panel_width, &panel_height);
GetFrameBufferResolution(&fb_width, &fb_height);
- if (post_processed_output && (output_buffer_info_.buffer_config.width < panel_width ||
- output_buffer_info_.buffer_config.height < panel_height)) {
+ if (post_processed_output && (output_buffer_info.buffer_config.width < panel_width ||
+ output_buffer_info.buffer_config.height < panel_height)) {
DLOGE("Buffer dimensions should not be less than panel resolution");
return -1;
- } else if (!post_processed_output && (output_buffer_info_.buffer_config.width < fb_width ||
- output_buffer_info_.buffer_config.height < fb_height)) {
+ } else if (!post_processed_output && (output_buffer_info.buffer_config.width < fb_width ||
+ output_buffer_info.buffer_config.height < fb_height)) {
DLOGE("Buffer dimensions should not be less than FB resolution");
return -1;
}
@@ -547,6 +579,7 @@
if (display_intf_) {
error = display_intf_->SetDetailEnhancerData(de_data);
+ validated_.reset();
}
return error;
}
@@ -556,6 +589,7 @@
if (display_intf_) {
error = display_intf_->ControlPartialUpdate(enable, pending);
+ validated_.reset();
}
return error;
@@ -566,6 +600,7 @@
if (display_intf_) {
error = display_intf_->DisablePartialUpdateOneFrame();
+ validated_.reset();
}
return error;
@@ -573,7 +608,9 @@
DisplayError HWCDisplayPrimary::SetMixerResolution(uint32_t width, uint32_t height) {
- return display_intf_->SetMixerResolution(width, height);
+ DisplayError error = display_intf_->SetMixerResolution(width, height);
+ validated_.reset();
+ return error;
}
DisplayError HWCDisplayPrimary::GetMixerResolution(uint32_t *width, uint32_t *height) {
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_primary.h b/msm8909/sdm/libs/hwc2/hwc_display_primary.h
similarity index 97%
rename from sdm845/sdm/libs/hwc2/hwc_display_primary.h
rename to msm8909/sdm/libs/hwc2/hwc_display_primary.h
index 4df65b3..b5a522d 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_primary.h
+++ b/msm8909/sdm/libs/hwc2/hwc_display_primary.h
@@ -57,8 +57,8 @@
virtual HWC2::Error Present(int32_t *out_retire_fence);
virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
virtual HWC2::Error SetColorMode(android_color_mode_t mode);
- virtual HWC2::Error SetColorModeById(int32_t color_mode_id);
virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
+ virtual HWC2::Error RestoreColorTransform();
virtual int Perform(uint32_t operation, ...);
virtual void SetSecureDisplay(bool secure_display_active);
virtual DisplayError Refresh();
@@ -88,6 +88,7 @@
BufferAllocator *buffer_allocator_ = nullptr;
CPUHint *cpu_hint_ = nullptr;
+ bool handle_idle_timeout_ = false;
// Primary output buffer configuration
LayerBuffer output_buffer_ = {};
@@ -101,6 +102,7 @@
bool dump_output_to_file_ = false;
BufferInfo output_buffer_info_ = {};
void *output_buffer_base_ = nullptr;
+ int default_mode_status_ = 0;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_virtual.cpp b/msm8909/sdm/libs/hwc2/hwc_display_virtual.cpp
similarity index 88%
copy from sdm845/sdm/libs/hwc2/hwc_display_virtual.cpp
copy to msm8909/sdm/libs/hwc2/hwc_display_virtual.cpp
index f77e9c9..232819e 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -105,6 +105,10 @@
int HWCDisplayVirtual::Deinit() {
int status = 0;
if (output_buffer_) {
+ if (output_buffer_->acquire_fence_fd >= 0) {
+ close(output_buffer_->acquire_fence_fd);
+ output_buffer_->acquire_fence_fd = -1;
+ }
delete output_buffer_;
output_buffer_ = nullptr;
}
@@ -123,6 +127,11 @@
BuildLayerStack();
layer_stack_.output_buffer = output_buffer_;
+
+ if (layer_set_.empty()) {
+ DLOGI("Skipping Validate and Commit");
+ return status;
+ }
status = PrepareLayerStack(out_num_types, out_num_requests);
return status;
}
@@ -138,10 +147,18 @@
status = HWCDisplay::CommitLayerStack();
if (status == HWC2::Error::None) {
if (dump_frame_count_ && !flush_ && dump_output_layer_) {
- if (output_handle_ && output_handle_->base) {
+ if (output_handle_) {
BufferInfo buffer_info;
const private_handle_t *output_handle =
reinterpret_cast<const private_handle_t *>(output_buffer_->buffer_id);
+ DisplayError error = kErrorNone;
+ if (!output_handle->base) {
+ error = buffer_allocator_->MapBuffer(output_handle, -1);
+ if (error != kErrorNone) {
+ DLOGE("Failed to map output buffer, error = %d", error);
+ return HWC2::Error::BadParameter;
+ }
+ }
buffer_info.buffer_config.width = static_cast<uint32_t>(output_handle->width);
buffer_info.buffer_config.height = static_cast<uint32_t>(output_handle->height);
buffer_info.buffer_config.format =
@@ -149,6 +166,13 @@
buffer_info.alloc_buffer_info.size = static_cast<uint32_t>(output_handle->size);
DumpOutputBuffer(buffer_info, reinterpret_cast<void *>(output_handle->base),
layer_stack_.retire_fence_fd);
+
+ int release_fence = -1;
+ error = buffer_allocator_->UnmapBuffer(output_handle, &release_fence);
+ if (error != kErrorNone) {
+ DLOGE("Failed to unmap buffer, error = %d", error);
+ return HWC2::Error::BadParameter;
+ }
}
}
@@ -156,7 +180,10 @@
}
}
CloseAcquireFds();
- close(output_buffer_->acquire_fence_fd);
+ if (output_buffer_->acquire_fence_fd >= 0) {
+ close(output_buffer_->acquire_fence_fd);
+ output_buffer_->acquire_fence_fd = -1;
+ }
return status;
}
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_virtual.h b/msm8909/sdm/libs/hwc2/hwc_display_virtual.h
similarity index 100%
rename from sdm845/sdm/libs/hwc2/hwc_display_virtual.h
rename to msm8909/sdm/libs/hwc2/hwc_display_virtual.h
diff --git a/sdm845/sdm/libs/hwc2/hwc_layers.cpp b/msm8909/sdm/libs/hwc2/hwc_layers.cpp
similarity index 73%
copy from sdm845/sdm/libs/hwc2/hwc_layers.cpp
copy to msm8909/sdm/libs/hwc2/hwc_layers.cpp
index 7fcd56b..23c42aa 100644
--- a/sdm845/sdm/libs/hwc2/hwc_layers.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_layers.cpp
@@ -68,6 +68,105 @@
return kErrorNone;
}
+// Returns true when color primary is supported
+bool GetColorPrimary(const int32_t &dataspace, ColorPrimaries *color_primary) {
+ auto standard = dataspace & HAL_DATASPACE_STANDARD_MASK;
+ bool supported_csc = true;
+ switch (standard) {
+ case HAL_DATASPACE_STANDARD_BT709:
+ *color_primary = ColorPrimaries_BT709_5;
+ break;
+ case HAL_DATASPACE_STANDARD_BT601_525:
+ case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
+ *color_primary = ColorPrimaries_BT601_6_525;
+ break;
+ case HAL_DATASPACE_STANDARD_BT601_625:
+ case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
+ *color_primary = ColorPrimaries_BT601_6_625;
+ break;
+ case HAL_DATASPACE_STANDARD_DCI_P3:
+ *color_primary = ColorPrimaries_DCIP3;
+ break;
+ case HAL_DATASPACE_STANDARD_BT2020:
+ *color_primary = ColorPrimaries_BT2020;
+ break;
+ default:
+ DLOGV_IF(kTagClient, "Unsupported Standard Request = %d", standard);
+ supported_csc = false;
+ }
+ return supported_csc;
+}
+
+bool GetTransfer(const int32_t &dataspace, GammaTransfer *gamma_transfer) {
+ auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK;
+ bool supported_transfer = true;
+ switch (transfer) {
+ case HAL_DATASPACE_TRANSFER_SRGB:
+ *gamma_transfer = Transfer_sRGB;
+ break;
+ case HAL_DATASPACE_TRANSFER_SMPTE_170M:
+ *gamma_transfer = Transfer_SMPTE_170M;
+ break;
+ case HAL_DATASPACE_TRANSFER_ST2084:
+ *gamma_transfer = Transfer_SMPTE_ST2084;
+ break;
+ case HAL_DATASPACE_TRANSFER_HLG:
+ *gamma_transfer = Transfer_HLG;
+ break;
+ case HAL_DATASPACE_TRANSFER_LINEAR:
+ *gamma_transfer = Transfer_Linear;
+ break;
+ case HAL_DATASPACE_TRANSFER_GAMMA2_2:
+ *gamma_transfer = Transfer_Gamma2_2;
+ break;
+ default:
+ DLOGV_IF(kTagClient, "Unsupported Transfer Request = %d", transfer);
+ supported_transfer = false;
+ }
+ return supported_transfer;
+}
+
+void GetRange(const int32_t &dataspace, ColorRange *color_range) {
+ auto range = dataspace & HAL_DATASPACE_RANGE_MASK;
+ switch (range) {
+ case HAL_DATASPACE_RANGE_FULL:
+ *color_range = Range_Full;
+ break;
+ case HAL_DATASPACE_RANGE_LIMITED:
+ *color_range = Range_Limited;
+ break;
+ default:
+ DLOGV_IF(kTagClient, "Unsupported Range Request = %d", range);
+ break;
+ }
+}
+
+bool IsBT2020(const ColorPrimaries &color_primary) {
+ switch (color_primary) {
+ case ColorPrimaries_BT2020:
+ return true;
+ break;
+ default:
+ return false;
+ }
+}
+
+// Retrieve ColorMetaData from android_data_space_t (STANDARD|TRANSFER|RANGE)
+bool GetSDMColorSpace(const int32_t &dataspace, ColorMetaData *color_metadata) {
+ bool valid = false;
+ valid = GetColorPrimary(dataspace, &(color_metadata->colorPrimaries));
+ if (!valid) {
+ return valid;
+ }
+ valid = GetTransfer(dataspace, &(color_metadata->transfer));
+ if (!valid) {
+ return valid;
+ }
+ GetRange(dataspace, &(color_metadata->range));
+
+ return true;
+}
+
// Layer operations
HWCLayer::HWCLayer(hwc2_display_t display_id, HWCBufferAllocator *buf_allocator)
: id_(next_id_++), display_id_(display_id), buffer_allocator_(buf_allocator) {
@@ -119,34 +218,38 @@
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(handle, aligned_width, aligned_height);
#endif
+ LayerBufferFormat format = GetSDMFormat(handle->format, handle->flags);
+ if ((format != layer_buffer->format) || (UINT32(aligned_width) != layer_buffer->width) ||
+ (UINT32(aligned_height) != layer_buffer->height)) {
+ // Layer buffer geometry has changed.
+ geometry_changes_ |= kBufferGeometry;
+ }
+
+ layer_buffer->format = format;
layer_buffer->width = UINT32(aligned_width);
layer_buffer->height = UINT32(aligned_height);
layer_buffer->unaligned_width = UINT32(handle->unaligned_width);
layer_buffer->unaligned_height = UINT32(handle->unaligned_height);
- layer_buffer->format = GetSDMFormat(handle->format, handle->flags);
if (SetMetaData(const_cast<private_handle_t *>(handle), layer_) != kErrorNone) {
return HWC2::Error::BadLayer;
}
-#ifdef USE_GRALLOC1
- // TODO(user): Clean this up
- if (handle->buffer_type == BUFFER_TYPE_VIDEO) {
-#else
- if (handle->bufferType == BUFFER_TYPE_VIDEO) {
-#endif
- layer_buffer->flags.video = true;
- }
+ layer_buffer->flags.video = (handle->buffer_type == BUFFER_TYPE_VIDEO) ? true : false;
+
// TZ Protected Buffer - L1
- if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
- layer_buffer->flags.secure = true;
- if (handle->flags & private_handle_t::PRIV_FLAGS_CAMERA_WRITE) {
- layer_buffer->flags.secure_camera = true;
- }
+ bool secure = (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER);
+ bool secure_camera = secure && (handle->flags & private_handle_t::PRIV_FLAGS_CAMERA_WRITE);
+ bool secure_display = (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY);
+ if (secure != layer_buffer->flags.secure || secure_camera != layer_buffer->flags.secure_camera ||
+ secure_display != layer_buffer->flags.secure_display) {
+ // Secure attribute of layer buffer has changed.
+ needs_validate_ = true;
}
- if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
- layer_buffer->flags.secure_display = true;
- }
+
+ layer_buffer->flags.secure = secure;
+ layer_buffer->flags.secure_camera = secure_camera;
+ layer_buffer->flags.secure_display = secure_display;
layer_buffer->planes[0].fd = ion_fd_;
layer_buffer->planes[0].offset = handle->offset;
@@ -159,6 +262,20 @@
}
HWC2::Error HWCLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
+ // Check if there is an update in SurfaceDamage rects
+ if (layer_->dirty_regions.size() != damage.numRects) {
+ needs_validate_ = true;
+ } else {
+ for (uint32_t j = 0; j < damage.numRects; j++) {
+ LayerRect damage_rect;
+ SetRect(damage.rects[j], &damage_rect);
+ if (damage_rect != layer_->dirty_regions.at(j)) {
+ needs_validate_ = true;
+ break;
+ }
+ }
+ }
+
layer_->dirty_regions.clear();
for (uint32_t i = 0; i < damage.numRects; i++) {
LayerRect rect;
@@ -192,9 +309,12 @@
}
HWC2::Error HWCLayer::SetLayerColor(hwc_color_t color) {
+ if (client_requested_ != HWC2::Composition::SolidColor) {
+ return HWC2::Error::None;
+ }
layer_->solid_fill_color = GetUint32Color(color);
layer_->input_buffer.format = kFormatARGB8888;
- DLOGV_IF(kTagCompManager, "[%" PRIu64 "][%" PRIu64 "] Layer color set to %x", display_id_, id_,
+ DLOGV_IF(kTagClient, "[%" PRIu64 "][%" PRIu64 "] Layer color set to %x", display_id_, id_,
layer_->solid_fill_color);
return HWC2::Error::None;
}
@@ -245,10 +365,11 @@
break;
default:
// unknown legacy dataspace
- DLOGW_IF(kTagQDCM, "Unsupported dataspace type %d", dataspace);
+ DLOGW_IF(kTagClient, "Unsupported dataspace type %d", dataspace);
}
}
+ // cache the dataspace, to be used later to update SDM ColorMetaData
if (dataspace_ != dataspace) {
geometry_changes_ |= kDataspace;
dataspace_ = dataspace;
@@ -258,19 +379,23 @@
HWC2::Error HWCLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
LayerRect dst_rect = {};
-
SetRect(frame, &dst_rect);
- if (dst_rect_ != dst_rect) {
+ if (layer_->dst_rect != dst_rect) {
geometry_changes_ |= kDisplayFrame;
- dst_rect_ = dst_rect;
+ layer_->dst_rect = dst_rect;
}
-
return HWC2::Error::None;
}
-void HWCLayer::ResetPerFrameData() {
- layer_->dst_rect = dst_rect_;
- layer_->transform = layer_transform_;
+HWC2::Error HWCLayer::SetCursorPosition(int32_t x, int32_t y) {
+ hwc_rect_t frame = {};
+ frame.left = x;
+ frame.top = y;
+ frame.right = x + INT(layer_->dst_rect.right - layer_->dst_rect.left);
+ frame.bottom = y + INT(layer_->dst_rect.bottom - layer_->dst_rect.top);
+ SetLayerDisplayFrame(frame);
+
+ return HWC2::Error::None;
}
HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) {
@@ -329,11 +454,10 @@
break;
}
- if (layer_transform_ != layer_transform) {
+ if (layer_->transform != layer_transform) {
geometry_changes_ |= kTransform;
- layer_transform_ = layer_transform;
+ layer_->transform = layer_transform;
}
-
return HWC2::Error::None;
}
@@ -535,35 +659,29 @@
DisplayError HWCLayer::SetMetaData(const private_handle_t *pvt_handle, Layer *layer) {
LayerBuffer *layer_buffer = &layer->input_buffer;
- bool use_color_metadata = true;
-
-#ifdef FEATURE_WIDE_COLOR
- // Only use color metadata if Android framework metadata is not set
- use_color_metadata = (dataspace_ == HAL_DATASPACE_UNKNOWN);
-#endif
-
- if (use_color_metadata) {
- if (sdm::SetCSC(pvt_handle, &layer_buffer->color_metadata) != kErrorNone) {
- return kErrorNotSupported;
- }
- }
-
private_handle_t *handle = const_cast<private_handle_t *>(pvt_handle);
IGC_t igc = {};
+ LayerIGC layer_igc = layer_buffer->igc;
if (getMetaData(handle, GET_IGC, &igc) == 0) {
- if (SetIGC(igc, &layer_buffer->igc) != kErrorNone) {
+ if (SetIGC(igc, &layer_igc) != kErrorNone) {
return kErrorNotSupported;
}
}
- uint32_t fps = 0;
- if (getMetaData(handle, GET_REFRESH_RATE , &fps) == 0) {
- layer->frame_rate = RoundToStandardFPS(fps);
+ float fps = 0;
+ uint32_t frame_rate = layer->frame_rate;
+ if (getMetaData(handle, GET_REFRESH_RATE, &fps) == 0) {
+ frame_rate = RoundToStandardFPS(fps);
}
int32_t interlaced = 0;
+ bool interlace = layer_buffer->flags.interlace;
if (getMetaData(handle, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
- layer_buffer->flags.interlace = interlaced ? true : false;
+ interlace = interlaced ? true : false;
+ }
+ if (interlace != layer_buffer->flags.interlace) {
+ DLOGI("Layer buffer interlaced metadata has changed. old=%d, new=%d",
+ layer_buffer->flags.interlace, interlace);
}
uint32_t linear_format = 0;
@@ -572,8 +690,19 @@
}
uint32_t s3d = 0;
+ LayerBufferS3DFormat s3d_format = layer_buffer->s3d_format;
if (getMetaData(handle, GET_S3D_FORMAT, &s3d) == 0) {
- layer_buffer->s3d_format = GetS3DFormat(s3d);
+ s3d_format = GetS3DFormat(s3d);
+ }
+
+ if ((layer_igc != layer_buffer->igc) || (interlace != layer_buffer->flags.interlace) ||
+ (frame_rate != layer->frame_rate) || (s3d_format != layer_buffer->s3d_format)) {
+ // Layer buffer metadata has changed.
+ needs_validate_ = true;
+ layer_buffer->igc = layer_igc;
+ layer->frame_rate = frame_rate;
+ layer_buffer->s3d_format = s3d_format;
+ layer_buffer->flags.interlace = interlace;
}
return kErrorNone;
@@ -605,84 +734,44 @@
return false;
}
-bool HWCLayer::SupportedDataspace() {
- if (dataspace_ == HAL_DATASPACE_UNKNOWN) {
- // Pick values from metadata
+bool HWCLayer::ValidateAndSetCSC() {
+ if (client_requested_ != HWC2::Composition::Device &&
+ client_requested_ != HWC2::Composition::Cursor) {
+ // Check the layers which are configured to Device
return true;
}
LayerBuffer *layer_buffer = &layer_->input_buffer;
-
- GammaTransfer sdm_transfer = {};
- ColorPrimaries sdm_primaries = {};
- ColorRange sdm_range = {};
-
- auto transfer = dataspace_ & HAL_DATASPACE_TRANSFER_MASK;
- // Handle transfer
- switch (transfer) {
- case HAL_DATASPACE_TRANSFER_SRGB:
- sdm_transfer = Transfer_sRGB;
- break;
- case HAL_DATASPACE_TRANSFER_SMPTE_170M:
- sdm_transfer = Transfer_SMPTE_170M;
- break;
- case HAL_DATASPACE_TRANSFER_ST2084:
- sdm_transfer = Transfer_SMPTE_ST2084;
- break;
- case HAL_DATASPACE_TRANSFER_HLG:
- sdm_transfer = Transfer_HLG;
- break;
- case HAL_DATASPACE_TRANSFER_LINEAR:
- sdm_transfer = Transfer_Linear;
- break;
- case HAL_DATASPACE_TRANSFER_GAMMA2_2:
- sdm_transfer = Transfer_Gamma2_2;
- break;
- default:
+ bool use_color_metadata = true;
+#ifdef FEATURE_WIDE_COLOR
+ ColorMetaData csc = {};
+ if (dataspace_ != HAL_DATASPACE_UNKNOWN) {
+ use_color_metadata = false;
+ bool valid_csc = GetSDMColorSpace(dataspace_, &csc);
+ if (!valid_csc) {
return false;
+ }
+ // if we are here here, update the sdm layer csc.
+ layer_buffer->color_metadata.transfer = csc.transfer;
+ layer_buffer->color_metadata.colorPrimaries = csc.colorPrimaries;
+ layer_buffer->color_metadata.range = csc.range;
+ }
+#endif
+
+ if (IsBT2020(layer_buffer->color_metadata.colorPrimaries)) {
+ // android_dataspace_t doesnt support mastering display and light levels
+ // so retrieve it from metadata for BT2020(HDR)
+ use_color_metadata = true;
}
- // Handle standard
- auto standard = dataspace_ & HAL_DATASPACE_STANDARD_MASK;
- switch (standard) {
- case HAL_DATASPACE_STANDARD_BT709:
- sdm_primaries = ColorPrimaries_BT709_5;
- break;
- case HAL_DATASPACE_STANDARD_BT601_525:
- case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
- sdm_primaries = ColorPrimaries_BT601_6_525;
- break;
- case HAL_DATASPACE_STANDARD_BT601_625:
- case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
- sdm_primaries = ColorPrimaries_BT601_6_625;
- break;
- case HAL_DATASPACE_STANDARD_DCI_P3:
- sdm_primaries = ColorPrimaries_DCIP3;
- break;
- case HAL_DATASPACE_STANDARD_BT2020:
- sdm_primaries = ColorPrimaries_BT2020;
- break;
- default:
+ if (use_color_metadata) {
+ const private_handle_t *handle =
+ reinterpret_cast<const private_handle_t *>(layer_buffer->buffer_id);
+ if (sdm::SetCSC(handle, &layer_buffer->color_metadata) != kErrorNone) {
return false;
- }
- // TODO(user): Check transfer + primary combination
-
- // Handle range
- auto range = dataspace_ & HAL_DATASPACE_RANGE_MASK;
- switch (range) {
- case HAL_DATASPACE_RANGE_FULL:
- sdm_range = Range_Full;
- break;
- case HAL_DATASPACE_RANGE_LIMITED:
- default:
- sdm_range = Range_Limited;
- break;
+ }
}
- // If we got here, the value is supported, update the layer
- layer_buffer->color_metadata.transfer = sdm_transfer;
- layer_buffer->color_metadata.colorPrimaries = sdm_primaries;
- layer_buffer->color_metadata.range = sdm_range;
return true;
}
@@ -709,7 +798,7 @@
case kCompositionGPU:
hwc_composition = HWC2::Composition::Client;
break;
- case kCompositionCursor:
+ case kCompositionHWCursor:
hwc_composition = HWC2::Composition::Cursor;
break;
default:
diff --git a/sdm845/sdm/libs/hwc2/hwc_layers.h b/msm8909/sdm/libs/hwc2/hwc_layers.h
similarity index 87%
copy from sdm845/sdm/libs/hwc2/hwc_layers.h
copy to msm8909/sdm/libs/hwc2/hwc_layers.h
index f536cb7..1d71ca8 100644
--- a/sdm845/sdm/libs/hwc2/hwc_layers.h
+++ b/msm8909/sdm/libs/hwc2/hwc_layers.h
@@ -40,7 +40,11 @@
namespace sdm {
DisplayError SetCSC(const private_handle_t *pvt_handle, ColorMetaData *color_metadata);
-
+bool GetColorPrimary(const int32_t &dataspace, ColorPrimaries *color_primary);
+bool GetTransfer(const int32_t &dataspace, GammaTransfer *gamma_transfer);
+void GetRange(const int32_t &dataspace, ColorRange *color_range);
+bool GetSDMColorSpace(const int32_t &dataspace, ColorMetaData *color_metadata);
+bool IsBT2020(const ColorPrimaries &color_primary);
enum GeometryChanges {
kNone = 0x000,
kBlendMode = 0x001,
@@ -52,6 +56,7 @@
kZOrder = 0x040,
kAdded = 0x080,
kRemoved = 0x100,
+ kBufferGeometry = 0x200,
};
class HWCLayer {
@@ -61,7 +66,6 @@
uint32_t GetZ() const { return z_; }
hwc2_layer_t GetId() const { return id_; }
Layer *GetSDMLayer() { return layer_; }
- void ResetPerFrameData();
HWC2::Error SetLayerBlendMode(HWC2::BlendMode mode);
HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
@@ -69,6 +73,7 @@
HWC2::Error SetLayerCompositionType(HWC2::Composition type);
HWC2::Error SetLayerDataspace(int32_t dataspace);
HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
+ HWC2::Error SetCursorPosition(int32_t x, int32_t y);
HWC2::Error SetLayerPlaneAlpha(float alpha);
HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
@@ -84,8 +89,10 @@
void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; }
void PushReleaseFence(int32_t fence);
int32_t PopReleaseFence(void);
- bool SupportedDataspace();
+ bool ValidateAndSetCSC();
bool SupportLocalConversion(ColorPrimaries working_primaries);
+ void ResetValidation() { needs_validate_ = false; }
+ bool NeedsValidation() { return (needs_validate_ || geometry_changes_); }
private:
Layer *layer_ = nullptr;
@@ -97,8 +104,7 @@
int ion_fd_ = -1;
HWCBufferAllocator *buffer_allocator_ = NULL;
int32_t dataspace_ = HAL_DATASPACE_UNKNOWN;
- LayerTransform layer_transform_ = {};
- LayerRect dst_rect_ = {};
+ bool needs_validate_ = true;
// Composition requested by client(SF)
HWC2::Composition client_requested_ = HWC2::Composition::Device;
diff --git a/sdm845/sdm/libs/hwc2/hwc_session.cpp b/msm8909/sdm/libs/hwc2/hwc_session.cpp
similarity index 67%
copy from sdm845/sdm/libs/hwc2/hwc_session.cpp
copy to msm8909/sdm/libs/hwc2/hwc_session.cpp
index 2bf7d4d..b78b1a2 100644
--- a/sdm845/sdm/libs/hwc2/hwc_session.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_session.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -17,7 +17,6 @@
* limitations under the License.
*/
-#include <core/dump_interface.h>
#include <core/buffer_allocator.h>
#include <private/color_params.h>
#include <utils/constants.h>
@@ -35,6 +34,8 @@
#include <algorithm>
#include <string>
#include <bitset>
+#include <thread>
+#include <memory>
#include "hwc_buffer_allocator.h"
#include "hwc_buffer_sync_handler.h"
@@ -42,6 +43,8 @@
#include "hwc_debugger.h"
#include "hwc_display_primary.h"
#include "hwc_display_virtual.h"
+#include "hwc_display_external_test.h"
+#include "qd_utils.h"
#define __CLASS__ "HWCSession"
@@ -65,7 +68,63 @@
};
namespace sdm {
-Locker HWCSession::locker_;
+
+static HWCUEvent g_hwc_uevent_;
+Locker HWCSession::locker_[HWC_NUM_DISPLAY_TYPES];
+bool HWCSession::disable_skip_validate_ = false;
+
+void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
+ const char *uevent_thread_name = "HWC_UeventThread";
+
+ prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+ int status = uevent_init();
+ if (!status) {
+ std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
+ hwc_uevent->caller_cv_.notify_one();
+ DLOGE("Failed to init uevent with err %d", status);
+ return;
+ }
+
+ {
+ // Signal caller thread that worker thread is ready to listen to events.
+ std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
+ hwc_uevent->init_done_ = true;
+ hwc_uevent->caller_cv_.notify_one();
+ }
+
+ while (1) {
+ char uevent_data[PAGE_SIZE] = {};
+
+ // keep last 2 zeroes to ensure double 0 termination
+ int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
+
+ // scope of lock to this block only, so that caller is free to set event handler to nullptr;
+ {
+ std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
+ if (hwc_uevent->uevent_listener_) {
+ hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
+ } else {
+ DLOGW("UEvent dropped. No uevent listener.");
+ }
+ }
+ }
+}
+
+HWCUEvent::HWCUEvent() {
+ std::unique_lock<std::mutex> caller_lock(mutex_);
+ std::thread thread(HWCUEvent::UEventThread, this);
+ thread.detach();
+ caller_cv_.wait(caller_lock);
+}
+
+void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
+ DLOGI("Set uevent listener = %p", uevent_listener);
+
+ std::lock_guard<std::mutex> obj(mutex_);
+ uevent_listener_ = uevent_listener;
+}
HWCSession::HWCSession(const hw_module_t *module) {
hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
@@ -77,9 +136,15 @@
}
int HWCSession::Init() {
+ SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+
int status = -EINVAL;
const char *qservice_name = "display.qservice";
+ if (!g_hwc_uevent_.InitDone()) {
+ return status;
+ }
+
// Start QService and connect to it.
qService::QService::init();
android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
@@ -89,54 +154,64 @@
iqservice->connect(android::sp<qClient::IQClient>(this));
qservice_ = reinterpret_cast<qService::QService *>(iqservice.get());
} else {
- DLOGE("Failed to acquire %s", qservice_name);
+ ALOGE("%s::%s: Failed to acquire %s", __CLASS__, __FUNCTION__, qservice_name);
return -EINVAL;
}
- buffer_allocator_ = new HWCBufferAllocator();
+ StartServices();
- DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), buffer_allocator_,
- &buffer_sync_handler_, &socket_handler_,
- &core_intf_);
+ DisplayError error = buffer_allocator_.Init();
if (error != kErrorNone) {
- DLOGE("Display core initialization failed. Error = %d", error);
+ ALOGE("%s::%s: Buffer allocaor initialization failed. Error = %d",
+ __CLASS__, __FUNCTION__, error);
return -EINVAL;
}
- // Read which display is first, and create it and store it in primary slot
- // TODO(user): This will need to be redone for HWC2 - right now we validate only
- // the primary physical path
- HWDisplayInterfaceInfo hw_disp_info;
+ error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
+ &buffer_sync_handler_, &socket_handler_, &core_intf_);
+ if (error != kErrorNone) {
+ buffer_allocator_.Deinit();
+ ALOGE("%s::%s: Display core initialization failed. Error = %d", __CLASS__, __FUNCTION__, error);
+ return -EINVAL;
+ }
+
+ g_hwc_uevent_.Register(this);
+
+ // If HDMI display is primary display, defer display creation until hotplug event is received.
+ HWDisplayInterfaceInfo hw_disp_info = {};
error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
- if (error == kErrorNone && hw_disp_info.type == kHDMI && hw_disp_info.is_connected) {
- // HDMI is primary display. If already connected, then create it and store in
- // primary display slot. If not connected, create a NULL display for now.
- status = HWCDisplayExternal::Create(core_intf_, buffer_allocator_, &callbacks_, qservice_,
- &hwc_display_[HWC_DISPLAY_PRIMARY]);
+ if (error != kErrorNone) {
+ g_hwc_uevent_.Register(nullptr);
+ CoreInterface::DestroyCore();
+ buffer_allocator_.Deinit();
+ DLOGE("Primary display type not recognized. Error = %d", error);
+ return -EINVAL;
+ }
+
+ if (hw_disp_info.type == kHDMI) {
+ status = 0;
+ hdmi_is_primary_ = true;
+ // Create display if it is connected, else wait for hotplug connect event.
+ if (hw_disp_info.is_connected) {
+ status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY);
+ }
} else {
// Create and power on primary display
- status = HWCDisplayPrimary::Create(core_intf_, buffer_allocator_, &callbacks_, qservice_,
+ status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
&hwc_display_[HWC_DISPLAY_PRIMARY]);
+ color_mgr_ = HWCColorManager::CreateColorManager(&buffer_allocator_);
+ if (!color_mgr_) {
+ DLOGW("Failed to load HWCColorManager.");
+ }
}
if (status) {
+ g_hwc_uevent_.Register(nullptr);
CoreInterface::DestroyCore();
+ buffer_allocator_.Deinit();
return status;
}
- color_mgr_ = HWCColorManager::CreateColorManager(buffer_allocator_);
- if (!color_mgr_) {
- DLOGW("Failed to load HWCColorManager.");
- }
-
- if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
- DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno));
- HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
- hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
- CoreInterface::DestroyCore();
- return -errno;
- }
-
struct rlimit fd_limit = {};
getrlimit(RLIMIT_NOFILE, &fd_limit);
fd_limit.rlim_cur = fd_limit.rlim_cur * 2;
@@ -146,39 +221,42 @@
DLOGW("Unable to increase fd limit - err:%d, %s", errno, strerror(errno));
}
}
+
return 0;
}
int HWCSession::Deinit() {
- HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
- hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
+ Locker::SequenceCancelScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
+ Locker::SequenceCancelScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
+ Locker::SequenceCancelScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
+
+ HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+ if (primary_display) {
+ if (hdmi_is_primary_) {
+ HWCDisplayExternal::Destroy(primary_display);
+ } else {
+ HWCDisplayPrimary::Destroy(primary_display);
+ }
+ }
+ hwc_display_[HWC_DISPLAY_PRIMARY] = nullptr;
+
if (color_mgr_) {
color_mgr_->DestroyColorManager();
}
- uevent_thread_exit_ = true;
- DLOGD("Terminating uevent thread");
- // TODO(user): on restarting HWC in the same process, the uevent thread does not restart
- // cleanly.
- Sys::pthread_cancel_(uevent_thread_);
+
+ g_hwc_uevent_.Register(nullptr);
DisplayError error = CoreInterface::DestroyCore();
if (error != kErrorNone) {
- DLOGE("Display core de-initialization failed. Error = %d", error);
+ ALOGE("Display core de-initialization failed. Error = %d", error);
}
- if (buffer_allocator_ != nullptr) {
- delete buffer_allocator_;
- }
- buffer_allocator_ = nullptr;
-
return 0;
}
int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
if (!module || !name || !device) {
- DLOGE("Invalid parameters.");
+ ALOGE("%s::%s: Invalid parameters.", __CLASS__, __FUNCTION__);
return -EINVAL;
}
@@ -201,8 +279,6 @@
}
int HWCSession::Close(hw_device_t *device) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
if (!device) {
return -EINVAL;
}
@@ -217,10 +293,32 @@
void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
int32_t *outCapabilities) {
- if (outCapabilities != nullptr && *outCount >= 1) {
- outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
+ if (!outCount) {
+ return;
}
- *outCount = 1;
+
+ int value = 0;
+ uint32_t count = 0;
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ bool color_transform_supported = hwc_session->core_intf_->IsColorTransformSupported();
+
+ if (Debug::Get()->GetProperty(DISABLE_SKIP_VALIDATE_PROP, &value) == kErrorNone) {
+ disable_skip_validate_ = (value == 1);
+ }
+
+ count += (color_transform_supported) ? 1 : 0;
+ count += (!disable_skip_validate_) ? 1 : 0;
+
+ if (outCapabilities != nullptr && (*outCount >= count)) {
+ int i = 0;
+ if (color_transform_supported) {
+ outCapabilities[i++] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
+ }
+ if (!disable_skip_validate_) {
+ outCapabilities[i++] = HWC2_CAPABILITY_SKIP_VALIDATE;
+ }
+ }
+ *outCount = count;
}
template <typename PFN, typename T>
@@ -233,24 +331,30 @@
// Defined in the same order as in the HWC2 header
int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
- SCOPE_LOCK(locker_);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
}
int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t *out_layer_id) {
- SCOPE_LOCK(locker_);
+ if (!out_layer_id) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
}
int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
int32_t *format, hwc2_display_t *out_display_id) {
// TODO(user): Handle concurrency with HDMI
- SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
}
+ if (!out_display_id || !width || !height || !format) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
HWCSession *hwc_session = static_cast<HWCSession *>(device);
auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
if (status == HWC2::Error::None) {
@@ -265,16 +369,15 @@
int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t layer) {
- SCOPE_LOCK(locker_);
return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
}
int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
- SCOPE_LOCK(locker_);
- if (!device) {
+ if (!device || display != HWC_DISPLAY_VIRTUAL) {
return HWC2_ERROR_BAD_DISPLAY;
}
+ SCOPE_LOCK(locker_[display]);
DLOGI("Destroying virtual display id:%" PRIu64, display);
auto *hwc_session = static_cast<HWCSession *>(device);
@@ -288,26 +391,23 @@
}
void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
- if (!device) {
+ if (!device || !out_size) {
return;
}
+
auto *hwc_session = static_cast<HWCSession *>(device);
const size_t max_dump_size = 8192;
if (out_buffer == nullptr) {
*out_size = max_dump_size;
} else {
- char sdm_dump[4096];
- DumpInterface::GetDump(sdm_dump, 4096); // TODO(user): Fix this workaround
- std::string s("");
+ std::string s {};
for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) {
+ SCOPE_LOCK(locker_[id]);
if (hwc_session->hwc_display_[id]) {
s += hwc_session->hwc_display_[id]->Dump();
}
}
- s += sdm_dump;
auto copied = s.copy(out_buffer, std::min(s.size(), max_dump_size), 0);
*out_size = UINT32(copied);
}
@@ -321,6 +421,10 @@
static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
uint32_t *out_num_elements, hwc2_layer_t *out_layers,
int32_t *out_types) {
+ // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
+ if (!out_num_elements) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
out_num_elements, out_layers, out_types);
}
@@ -392,7 +496,9 @@
}
static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {
- return 1;
+ char property[PROPERTY_VALUE_MAX];
+ property_get(WRITEBACK_SUPPORTED, property, "1");
+ return (uint32_t) atoi(property);
}
static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
@@ -405,19 +511,48 @@
int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
int32_t *out_retire_fence) {
HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ bool notify_hotplug = false;
+ auto status = HWC2::Error::BadDisplay;
DTRACE_SCOPED();
- SEQUENCE_EXIT_SCOPE_LOCK(locker_);
- if (!device) {
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
return HWC2_ERROR_BAD_DISPLAY;
}
- auto status = HWC2::Error::BadDisplay;
- // TODO(user): Handle virtual display/HDMI concurrency
- if (hwc_session->hwc_display_[display]) {
- status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
- // This is only indicative of how many times SurfaceFlinger posts
- // frames to the display.
- CALC_FPS();
+ {
+ SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
+ if (!device) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
+ // TODO(user): Handle virtual display/HDMI concurrency
+ if (hwc_session->hwc_display_[display]) {
+ status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
+ // This is only indicative of how many times SurfaceFlinger posts
+ // frames to the display.
+ CALC_FPS();
+ }
+ }
+
+ if (status != HWC2::Error::None && status != HWC2::Error::NotValidated) {
+ SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
+ }
+
+ // Handle Pending external display connection
+ if (hwc_session->external_pending_connect_ && (display == HWC_DISPLAY_PRIMARY)) {
+ Locker::ScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
+ Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
+
+ if (!hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+ DLOGD("Process pending external display connection");
+ hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL);
+ hwc_session->external_pending_connect_ = false;
+ notify_hotplug = true;
+ }
+ }
+
+ if (notify_hotplug) {
+ hwc_session->HotPlug(HWC_DISPLAY_EXTERNAL, HWC2::Connection::Connected);
}
return INT32(status);
@@ -426,15 +561,21 @@
int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
hwc2_callback_data_t callback_data,
hwc2_function_pointer_t pointer) {
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- if (!device) {
- return HWC2_ERROR_BAD_DISPLAY;
+ if (!device || pointer == nullptr) {
+ return HWC2_ERROR_BAD_PARAMETER;
}
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ SCOPE_LOCK(hwc_session->callbacks_lock_);
auto desc = static_cast<HWC2::Callback>(descriptor);
auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
DLOGD("Registering callback: %s", to_string(desc).c_str());
- if (descriptor == HWC2_CALLBACK_HOTPLUG)
- hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
+ if (descriptor == HWC2_CALLBACK_HOTPLUG) {
+ if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
+ }
+ }
+ hwc_session->need_invalidate_ = false;
+ hwc_session->callbacks_lock_.Broadcast();
return INT32(error);
}
@@ -452,15 +593,20 @@
int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
int32_t /*android_color_mode_t*/ int_mode) {
+ if (int_mode < HAL_COLOR_MODE_NATIVE || int_mode > HAL_COLOR_MODE_DISPLAY_P3) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
auto mode = static_cast<android_color_mode_t>(int_mode);
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
}
int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
const float *matrix,
int32_t /*android_color_transform_t*/ hint) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ if (!matrix || hint < HAL_COLOR_TRANSFORM_IDENTITY ||
+ hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
transform_hint);
@@ -468,12 +614,21 @@
static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
int32_t x, int32_t y) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition, layer, x,
- y);
+ auto status = INT32(HWC2::Error::None);
+ status = HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition,
+ layer, x, y);
+ if (status == INT32(HWC2::Error::None)) {
+ // Update cursor position
+ HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetCursorPosition, x, y);
+ }
+ return status;
}
static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
int32_t int_mode) {
+ if (int_mode < HWC2_BLEND_MODE_INVALID || int_mode > HWC2_BLEND_MODE_COVERAGE) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
auto mode = static_cast<HWC2::BlendMode>(int_mode);
return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode);
}
@@ -538,10 +693,9 @@
visible);
}
-int32_t HWCSession::SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer, uint32_t z) {
- SCOPE_LOCK(locker_);
- return CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
+static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+ uint32_t z) {
+ return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
}
int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
@@ -550,8 +704,13 @@
return HWC2_ERROR_BAD_DISPLAY;
}
+ if (display != HWC_DISPLAY_VIRTUAL) {
+ return HWC2_ERROR_UNSUPPORTED;
+ }
+
+ SCOPE_LOCK(locker_[display]);
auto *hwc_session = static_cast<HWCSession *>(device);
- if (display == HWC_DISPLAY_VIRTUAL && hwc_session->hwc_display_[display]) {
+ if (hwc_session->hwc_display_[display]) {
auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
auto status = vds->SetOutputBuffer(buffer, releaseFence);
return INT32(status);
@@ -562,7 +721,6 @@
int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
auto mode = static_cast<HWC2::PowerMode>(int_mode);
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
}
@@ -582,31 +740,35 @@
// TODO(user): Handle secure session, handle QDCM solid fill
// Handle external_pending_connect_ in CreateVirtualDisplay
auto status = HWC2::Error::BadDisplay;
- if (hwc_session->hwc_display_[display]) {
- SEQUENCE_ENTRY_SCOPE_LOCK(locker_);
- if (display == HWC_DISPLAY_PRIMARY) {
- // TODO(user): This can be moved to HWCDisplayPrimary
- if (hwc_session->reset_panel_) {
- DLOGW("panel is in bad state, resetting the panel");
- hwc_session->ResetPanel();
+ {
+ SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
+ if (hwc_session->hwc_display_[display]) {
+ if (display == HWC_DISPLAY_PRIMARY) {
+ // TODO(user): This can be moved to HWCDisplayPrimary
+ if (hwc_session->reset_panel_) {
+ DLOGW("panel is in bad state, resetting the panel");
+ hwc_session->ResetPanel();
+ }
+
+ if (hwc_session->need_invalidate_) {
+ hwc_session->Refresh(display);
+ hwc_session->need_invalidate_ = false;
+ }
+
+ if (hwc_session->color_mgr_) {
+ hwc_session->color_mgr_->SetColorModeDetailEnhancer(hwc_session->hwc_display_[display]);
+ }
}
- if (hwc_session->need_invalidate_) {
- hwc_session->callbacks_.Refresh(display);
- }
-
- if (hwc_session->color_mgr_) {
- hwc_session->color_mgr_->SetColorModeDetailEnhancer(hwc_session->hwc_display_[display]);
- }
+ status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
}
+ }
- status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
+ // Sequence locking currently begins on Validate, so cancel the sequence lock on failures
+ if (status != HWC2::Error::None && status != HWC2::Error::HasChanges) {
+ SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
}
- // If validate fails, cancel the sequence lock so that other operations
- // (such as Dump or SetPowerMode) may succeed without blocking on the condition
- if (status == HWC2::Error::BadDisplay) {
- SEQUENCE_CANCEL_SCOPE_LOCK(locker_);
- }
+
return INT32(status);
}
@@ -716,7 +878,7 @@
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
return HWC2::Error::NoResources;
}
- auto status = HWCDisplayVirtual::Create(core_intf_, buffer_allocator_, &callbacks_, width,
+ auto status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, width,
height, format, &hwc_display_[HWC_DISPLAY_VIRTUAL]);
// TODO(user): validate width and height support
if (status)
@@ -735,8 +897,7 @@
hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
if (disp == HWC_DISPLAY_EXTERNAL) {
- status = HWCDisplayExternal::Create(core_intf_, buffer_allocator_, &callbacks_, primary_width,
- primary_height, qservice_, false, &hwc_display_[disp]);
+ status = CreateExternalDisplay(disp, primary_width, primary_height);
} else {
DLOGE("Invalid display type");
return -1;
@@ -769,8 +930,6 @@
// Qclient methods
android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
android::status_t status = 0;
switch (command) {
@@ -779,14 +938,11 @@
break;
case qService::IQService::SCREEN_REFRESH:
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ refreshScreen();
break;
case qService::IQService::SET_IDLE_TIMEOUT:
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- uint32_t timeout = UINT32(input_parcel->readInt32());
- hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(timeout);
- }
+ setIdleTimeout(UINT32(input_parcel->readInt32()));
break;
case qService::IQService::SET_FRAME_DUMP_CONFIG:
@@ -801,8 +957,13 @@
status = SetDisplayMode(input_parcel);
break;
- case qService::IQService::SET_SECONDARY_DISPLAY_STATUS:
- status = SetSecondaryDisplayStatus(input_parcel, output_parcel);
+ case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
+ int disp_id = INT(input_parcel->readInt32());
+ HWCDisplay::DisplayStatus disp_status =
+ static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
+ status = SetSecondaryDisplayStatus(disp_id, disp_status);
+ output_parcel->writeInt32(status);
+ }
break;
case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
@@ -812,56 +973,89 @@
case qService::IQService::SET_VIEW_FRAME:
break;
- case qService::IQService::TOGGLE_SCREEN_UPDATES:
- status = ToggleScreenUpdates(input_parcel, output_parcel);
+ case qService::IQService::TOGGLE_SCREEN_UPDATES: {
+ int32_t input = input_parcel->readInt32();
+ status = toggleScreenUpdate(input == 1);
+ output_parcel->writeInt32(status);
+ }
break;
case qService::IQService::QDCM_SVC_CMDS:
status = QdcmCMDHandler(input_parcel, output_parcel);
break;
- case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED:
- status = OnMinHdcpEncryptionLevelChange(input_parcel, output_parcel);
+ case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
+ int disp_id = input_parcel->readInt32();
+ uint32_t min_enc_level = UINT32(input_parcel->readInt32());
+ status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
+ output_parcel->writeInt32(status);
+ }
break;
- case qService::IQService::CONTROL_PARTIAL_UPDATE:
- status = ControlPartialUpdate(input_parcel, output_parcel);
+ case qService::IQService::CONTROL_PARTIAL_UPDATE: {
+ int disp_id = input_parcel->readInt32();
+ uint32_t enable = UINT32(input_parcel->readInt32());
+ status = ControlPartialUpdate(disp_id, enable == 1);
+ output_parcel->writeInt32(status);
+ }
break;
- case qService::IQService::SET_ACTIVE_CONFIG:
- status = HandleSetActiveDisplayConfig(input_parcel, output_parcel);
+ case qService::IQService::SET_ACTIVE_CONFIG: {
+ uint32_t config = UINT32(input_parcel->readInt32());
+ int disp_id = input_parcel->readInt32();
+ status = SetActiveConfigIndex(disp_id, config);
+ }
break;
- case qService::IQService::GET_ACTIVE_CONFIG:
- status = HandleGetActiveDisplayConfig(input_parcel, output_parcel);
+ case qService::IQService::GET_ACTIVE_CONFIG: {
+ int disp_id = input_parcel->readInt32();
+ uint32_t config = 0;
+ status = GetActiveConfigIndex(disp_id, &config);
+ output_parcel->writeInt32(INT(config));
+ }
break;
- case qService::IQService::GET_CONFIG_COUNT:
- status = HandleGetDisplayConfigCount(input_parcel, output_parcel);
+ case qService::IQService::GET_CONFIG_COUNT: {
+ int disp_id = input_parcel->readInt32();
+ uint32_t count = 0;
+ status = GetConfigCount(disp_id, &count);
+ output_parcel->writeInt32(INT(count));
+ }
break;
case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
break;
- case qService::IQService::GET_PANEL_BRIGHTNESS:
- status = GetPanelBrightness(input_parcel, output_parcel);
+ case qService::IQService::GET_PANEL_BRIGHTNESS: {
+ int level = 0;
+ status = GetPanelBrightness(&level);
+ output_parcel->writeInt32(level);
+ }
break;
- case qService::IQService::SET_PANEL_BRIGHTNESS:
- status = SetPanelBrightness(input_parcel, output_parcel);
+ case qService::IQService::SET_PANEL_BRIGHTNESS: {
+ uint32_t level = UINT32(input_parcel->readInt32());
+ status = setPanelBrightness(level);
+ output_parcel->writeInt32(status);
+ }
break;
case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
status = GetVisibleDisplayRect(input_parcel, output_parcel);
break;
- case qService::IQService::SET_CAMERA_STATUS:
- status = SetDynamicBWForCamera(input_parcel, output_parcel);
+ case qService::IQService::SET_CAMERA_STATUS: {
+ uint32_t camera_status = UINT32(input_parcel->readInt32());
+ status = setCameraLaunchStatus(camera_status);
+ }
break;
- case qService::IQService::GET_BW_TRANSACTION_STATUS:
- status = GetBWTransactionStatus(input_parcel, output_parcel);
+ case qService::IQService::GET_BW_TRANSACTION_STATUS: {
+ bool state = true;
+ status = DisplayBWTransactionPending(&state);
+ output_parcel->writeInt32(state);
+ }
break;
case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
@@ -872,10 +1066,6 @@
status = SetColorModeOverride(input_parcel);
break;
- case qService::IQService::SET_COLOR_MODE_BY_ID:
- status = SetColorModeById(input_parcel);
- break;
-
default:
DLOGW("QService command = %d is not supported", command);
return -EINVAL;
@@ -884,164 +1074,6 @@
return status;
}
-android::status_t HWCSession::ToggleScreenUpdates(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int input = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (hwc_display_[HWC_DISPLAY_PRIMARY] && (input <= 1) && (input >= 0)) {
- error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(input == 1);
- if (error != 0) {
- DLOGE("Failed to toggle screen updates = %d. Error = %d", input, error);
- }
- }
- output_parcel->writeInt32(error);
-
- return error;
-}
-
-android::status_t HWCSession::SetPanelBrightness(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int level = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(level);
- if (error != 0) {
- DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error);
- }
- }
- output_parcel->writeInt32(error);
-
- return error;
-}
-
-android::status_t HWCSession::GetPanelBrightness(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int error = android::BAD_VALUE;
- int ret = error;
-
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(&ret);
- if (error != 0) {
- ret = error;
- DLOGE("Failed to get the panel brightness. Error = %d", error);
- }
- }
- output_parcel->writeInt32(ret);
-
- return error;
-}
-
-android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
- android::Parcel *out) {
- DisplayError error = kErrorNone;
- int ret = 0;
- uint32_t disp_id = UINT32(input_parcel->readInt32());
- uint32_t enable = UINT32(input_parcel->readInt32());
-
- if (disp_id != HWC_DISPLAY_PRIMARY) {
- DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
- ret = -EINVAL;
- out->writeInt32(ret);
- return ret;
- }
-
- if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
- DLOGE("primary display object is not instantiated");
- ret = -EINVAL;
- out->writeInt32(ret);
- return ret;
- }
-
- uint32_t pending = 0;
- error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlPartialUpdate(enable, &pending);
-
- if (error == kErrorNone) {
- if (!pending) {
- out->writeInt32(ret);
- return ret;
- }
- } else if (error == kErrorNotSupported) {
- out->writeInt32(ret);
- return ret;
- } else {
- ret = -EINVAL;
- out->writeInt32(ret);
- return ret;
- }
-
- // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
-
- // Wait until partial update control is complete
- ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
-
- out->writeInt32(ret);
-
- return ret;
-}
-
-android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int config = input_parcel->readInt32();
- int dpy = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (dpy > HWC_DISPLAY_VIRTUAL) {
- return android::BAD_VALUE;
- }
-
- if (hwc_display_[dpy]) {
- error = hwc_display_[dpy]->SetActiveDisplayConfig(config);
- if (error == 0) {
- callbacks_.Refresh(0);
- }
- }
-
- return error;
-}
-
-android::status_t HWCSession::HandleGetActiveDisplayConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int dpy = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (dpy > HWC_DISPLAY_VIRTUAL) {
- return android::BAD_VALUE;
- }
-
- if (hwc_display_[dpy]) {
- uint32_t config = 0;
- error = hwc_display_[dpy]->GetActiveDisplayConfig(&config);
- if (error == 0) {
- output_parcel->writeInt32(INT(config));
- }
- }
-
- return error;
-}
-
-android::status_t HWCSession::HandleGetDisplayConfigCount(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int dpy = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (dpy > HWC_DISPLAY_VIRTUAL) {
- return android::BAD_VALUE;
- }
-
- uint32_t count = 0;
- if (hwc_display_[dpy]) {
- error = hwc_display_[dpy]->GetDisplayConfigCount(&count);
- if (error == 0) {
- output_parcel->writeInt32(INT(count));
- }
- }
-
- return error;
-}
-
android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
*input_parcel,
android::Parcel *output_parcel) {
@@ -1050,10 +1082,11 @@
int error = android::BAD_VALUE;
DisplayConfigVariableInfo display_attributes;
- if (dpy > HWC_DISPLAY_VIRTUAL) {
+ if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
return android::BAD_VALUE;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
if (hwc_display_[dpy]) {
error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
if (error == 0) {
@@ -1069,44 +1102,24 @@
return error;
}
-android::status_t HWCSession::SetSecondaryDisplayStatus(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int ret = -EINVAL;
-
- uint32_t display_id = UINT32(input_parcel->readInt32());
- uint32_t display_status = UINT32(input_parcel->readInt32());
-
- DLOGI("Display = %d, Status = %d", display_id, display_status);
-
- if (display_id >= HWC_NUM_DISPLAY_TYPES) {
- DLOGE("Invalid display_id");
- } else if (display_id == HWC_DISPLAY_PRIMARY) {
- DLOGE("Not supported for this display");
- } else if (!hwc_display_[display_id]) {
- DLOGW("Display is not connected");
- } else {
- ret = hwc_display_[display_id]->SetDisplayStatus(display_status);
- }
-
- output_parcel->writeInt32(ret);
-
- return ret;
-}
-
android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+
uint32_t operation = UINT32(input_parcel->readInt32());
+ HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+
switch (operation) {
case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
- return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
- HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
+ return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
+
case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
- return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
- HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
+ return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
+
case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
uint32_t refresh_rate = UINT32(input_parcel->readInt32());
- return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
- HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
+ return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
}
+
default:
DLOGW("Invalid operation %d", operation);
return -EINVAL;
@@ -1116,6 +1129,8 @@
}
android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+
uint32_t mode = UINT32(input_parcel->readInt32());
return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
}
@@ -1126,6 +1141,7 @@
uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages);
if (error != kErrorNone) {
@@ -1135,6 +1151,7 @@
}
if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages);
if (error != kErrorNone) {
@@ -1144,6 +1161,7 @@
}
if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages);
if (error != kErrorNone) {
@@ -1155,59 +1173,27 @@
return 0;
}
-android::status_t HWCSession::SetDynamicBWForCamera(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- DisplayError error = kErrorNone;
- uint32_t camera_status = UINT32(input_parcel->readInt32());
- HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault;
-
- // trigger invalidate to apply new bw caps.
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
-
- error = core_intf_->SetMaxBandwidthMode(mode);
- if (error != kErrorNone) {
- return -EINVAL;
- }
-
- new_bw_mode_ = true;
- need_invalidate_ = true;
-
- return 0;
-}
-
-android::status_t HWCSession::GetBWTransactionStatus(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- bool state = true;
-
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- if (sync_wait(bw_mode_release_fd_, 0) < 0) {
- DLOGI("bw_transaction_release_fd is not yet signalled: err= %s", strerror(errno));
- state = false;
- }
- output_parcel->writeInt32(state);
- }
-
- return 0;
-}
-
void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
}
if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
}
if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
@@ -1223,6 +1209,7 @@
return -EINVAL;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
DLOGI("Primary display is not initialized");
return -EINVAL;
@@ -1243,23 +1230,20 @@
auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
auto device = static_cast<hwc2_device_t *>(this);
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return -EINVAL;
+ }
auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
- return 0;
-}
-android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
- auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
- auto mode = input_parcel->readInt32();
- auto device = static_cast<hwc2_device_t *>(this);
- auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorModeById, mode);
- if (err != HWC2_ERROR_NONE)
- return -EINVAL;
return 0;
}
void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
+ // TODO(user): Do we really need a lock here?
+
int type = input_parcel->readInt32();
bool enable = (input_parcel->readInt32() > 0);
DLOGI("type = %d enable = %d", type, enable);
@@ -1293,6 +1277,18 @@
HWCDebugHandler::DebugQdcm(enable, verbose_level);
break;
+ case qService::IQService::DEBUG_SCALAR:
+ HWCDebugHandler::DebugScalar(enable, verbose_level);
+ break;
+
+ case qService::IQService::DEBUG_CLIENT:
+ HWCDebugHandler::DebugClient(enable, verbose_level);
+ break;
+
+ case qService::IQService::DEBUG_DISPLAY:
+ HWCDebugHandler::DebugDisplay(enable, verbose_level);
+ break;
+
default:
DLOGW("type = %d is not supported", type);
}
@@ -1332,132 +1328,105 @@
return ret;
}
- switch (pending_action.action) {
- case kInvalidating:
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
- break;
- case kEnterQDCMMode:
- ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- break;
- case kExitQDCMMode:
- ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
- break;
- case kApplySolidFill:
- ret =
- color_mgr_->SetSolidFill(pending_action.params, true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
- break;
- case kDisableSolidFill:
- ret =
- color_mgr_->SetSolidFill(pending_action.params, false, hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
- break;
- case kSetPanelBrightness:
- brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
- if (brightness_value == NULL) {
- DLOGE("Brightness value is Null");
- return -EINVAL;
- }
- if (HWC_DISPLAY_PRIMARY == display_id)
- ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
- break;
- case kEnableFrameCapture:
- ret = color_mgr_->SetFrameCapture(pending_action.params, true,
- hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
- break;
- case kDisableFrameCapture:
- ret = color_mgr_->SetFrameCapture(pending_action.params, false,
- hwc_display_[HWC_DISPLAY_PRIMARY]);
- break;
- case kConfigureDetailedEnhancer:
- ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
- hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
- break;
- case kNoAction:
- break;
- default:
- DLOGW("Invalid pending action = %d!", pending_action.action);
- break;
- }
+ int32_t action = pending_action.action;
+ int count = -1;
+ bool reset_validate = true;
+ while (action > 0) {
+ count++;
+ int32_t bit = (action & 1);
+ action = action >> 1;
+
+ if (!bit)
+ continue;
+
+ DLOGV_IF(kTagQDCM, "pending action = %d", BITMAP(count));
+ switch (BITMAP(count)) {
+ case kInvalidating:
+ Refresh(HWC_DISPLAY_PRIMARY);
+ reset_validate = !disable_skip_validate_;
+ break;
+ case kEnterQDCMMode:
+ ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
+ break;
+ case kExitQDCMMode:
+ ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
+ break;
+ case kApplySolidFill:
+ ret = color_mgr_->SetSolidFill(pending_action.params,
+ true, hwc_display_[HWC_DISPLAY_PRIMARY]);
+ Refresh(HWC_DISPLAY_PRIMARY);
+ break;
+ case kDisableSolidFill:
+ ret = color_mgr_->SetSolidFill(pending_action.params,
+ false, hwc_display_[HWC_DISPLAY_PRIMARY]);
+ Refresh(HWC_DISPLAY_PRIMARY);
+ break;
+ case kSetPanelBrightness:
+ brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
+ if (brightness_value == NULL) {
+ DLOGE("Brightness value is Null");
+ return -EINVAL;
+ }
+ if (HWC_DISPLAY_PRIMARY == display_id)
+ ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
+ break;
+ case kEnableFrameCapture:
+ ret = color_mgr_->SetFrameCapture(pending_action.params, true,
+ hwc_display_[HWC_DISPLAY_PRIMARY]);
+ Refresh(HWC_DISPLAY_PRIMARY);
+ break;
+ case kDisableFrameCapture:
+ ret = color_mgr_->SetFrameCapture(pending_action.params, false,
+ hwc_display_[HWC_DISPLAY_PRIMARY]);
+ break;
+ case kConfigureDetailedEnhancer:
+ ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
+ hwc_display_[HWC_DISPLAY_PRIMARY]);
+ Refresh(HWC_DISPLAY_PRIMARY);
+ break;
+ case kModeSet:
+ ret = static_cast<int>
+ (hwc_display_[HWC_DISPLAY_PRIMARY]->RestoreColorTransform());
+ Refresh(HWC_DISPLAY_PRIMARY);
+ break;
+ case kNoAction:
+ break;
+ default:
+ DLOGW("Invalid pending action = %d!", pending_action.action);
+ break;
+ }
+ }
// for display API getter case, marshall returned params into out_parcel.
output_parcel->writeInt32(ret);
HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
req_payload.DestroyPayload();
resp_payload.DestroyPayload();
+ if (reset_validate) {
+ hwc_display_[display_id]->ResetValidation();
+ }
return (ret ? -EINVAL : 0);
}
-android::status_t HWCSession::OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int ret = -EINVAL;
- uint32_t display_id = UINT32(input_parcel->readInt32());
- uint32_t min_enc_level = UINT32(input_parcel->readInt32());
-
- DLOGI("Display %d", display_id);
-
- if (display_id >= HWC_NUM_DISPLAY_TYPES) {
- DLOGE("Invalid display_id");
- } else if (display_id != HWC_DISPLAY_EXTERNAL) {
- DLOGE("Not supported for display");
- } else if (!hwc_display_[display_id]) {
- DLOGW("Display is not connected");
- } else {
- ret = hwc_display_[display_id]->OnMinHdcpEncryptionLevelChange(min_enc_level);
- }
-
- output_parcel->writeInt32(ret);
-
- return ret;
-}
-
-void *HWCSession::HWCUeventThread(void *context) {
- if (context) {
- return reinterpret_cast<HWCSession *>(context)->HWCUeventThreadHandler();
- }
-
- return NULL;
-}
-
-void *HWCSession::HWCUeventThreadHandler() {
- static char uevent_data[PAGE_SIZE];
- int length = 0;
- prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0);
- setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
- if (!uevent_init()) {
- DLOGE("Failed to init uevent");
- pthread_exit(0);
- return NULL;
- }
-
- while (!uevent_thread_exit_) {
- // keep last 2 zeroes to ensure double 0 termination
- length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
-
- if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) {
- DLOGI("Uevent HDMI = %s", uevent_data);
- int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
- if (connected >= 0) {
- DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
- if (HotPlugHandler(connected) == -1) {
- DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
- }
- }
- } else if (strcasestr(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) {
- DLOGI("Uevent FB0 = %s", uevent_data);
- int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
- if (panel_reset == 0) {
- callbacks_.Refresh(0);
- reset_panel_ = true;
+void HWCSession::UEventHandler(const char *uevent_data, int length) {
+ if (!strcasecmp(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
+ DLOGI("Uevent HDMI = %s", uevent_data);
+ int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
+ if (connected >= 0) {
+ DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
+ if (HotPlugHandler(connected) == -1) {
+ DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
}
}
+ } else if (!strcasecmp(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
+ DLOGI("Uevent FB0 = %s", uevent_data);
+ int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
+ if (panel_reset == 0) {
+ Refresh(0);
+ reset_panel_ = true;
+ }
}
- pthread_exit(0);
-
- return NULL;
}
int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
@@ -1500,34 +1469,38 @@
int HWCSession::HotPlugHandler(bool connected) {
int status = 0;
bool notify_hotplug = false;
- bool hdmi_primary = false;
// To prevent sending events to client while a lock is held, acquire scope locks only within
// below scope so that those get automatically unlocked after the scope ends.
- {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
- if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
- DLOGE("Primary display is not connected.");
- return -1;
- }
-
- HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
- HWCDisplay *external_display = NULL;
-
- if (primary_display->GetDisplayClass() == DISPLAY_CLASS_EXTERNAL) {
- external_display = static_cast<HWCDisplayExternal *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
- hdmi_primary = true;
- }
-
- // If primary display connected is a NULL display, then replace it with the external display
- if (connected) {
- // If we are in HDMI as primary and the primary display just got plugged in
- if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
- DLOGE("HDMI is already connected");
- return -1;
+ do {
+ // If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
+ // if it is already created, but got disconnected/connected again,
+ // just toggle display status and do not notify surfaceflinger.
+ // If HDMI is not primary, create/destroy external display normally.
+ if (hdmi_is_primary_) {
+ SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
+ } else {
+ status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY);
+ notify_hotplug = true;
}
+ break;
+ }
+
+ {
+ SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ // Primary display must be connected for HDMI as secondary cases.
+ if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ DLOGE("Primary display is not connected.");
+ return -1;
+ }
+ }
+
+ if (connected) {
+ SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
+ Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
// Connect external display if virtual display is not connected.
// Else, defer external display connection and process it when virtual display
// tears down; Do not notify SurfaceFlinger since connection is deferred now.
@@ -1542,43 +1515,33 @@
external_pending_connect_ = true;
}
} else {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
// Do not return error if external display is not in connected status.
// Due to virtual display concurrency, external display connection might be still pending
// but hdmi got disconnected before pending connection could be processed.
-
- if (hdmi_primary) {
- assert(external_display != NULL);
- uint32_t x_res, y_res;
- external_display->GetFrameBufferResolution(&x_res, &y_res);
- // Need to manually disable VSYNC as SF is not aware of connect/disconnect cases
- // for HDMI as primary
- external_display->SetVsyncEnabled(HWC2::Vsync::Disable);
- HWCDisplayExternal::Destroy(external_display);
-
- // In HWC2, primary displays can be hotplugged out
+ if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+ status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
notify_hotplug = true;
- } else {
- if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
- status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
- notify_hotplug = true;
- }
- external_pending_connect_ = false;
}
+ external_pending_connect_ = false;
+ }
+ } while (0);
+
+ if (connected) {
+ Refresh(0);
+
+ if (!hdmi_is_primary_) {
+ // wait for sufficient time to ensure sufficient resources are available to process new
+ // new display connection.
+ uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
+ usleep(vsync_period * 2 / 1000);
}
}
- if (connected && notify_hotplug) {
- // trigger screen refresh to ensure sufficient resources are available to process new
- // new display connection.
- callbacks_.Refresh(0);
- uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
- usleep(vsync_period * 2 / 1000);
- }
// notify client
- // Handle HDMI as primary here
if (notify_hotplug) {
- callbacks_.Hotplug(HWC_DISPLAY_EXTERNAL,
- connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
+ HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
+ connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
}
qservice_->onHdmiHotplug(INT(connected));
@@ -1587,7 +1550,7 @@
}
int HWCSession::GetVsyncPeriod(int disp) {
- SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_[disp]);
// default value
int32_t vsync_period = 1000000000l / 60;
auto attribute = HWC2::Attribute::VsyncPeriod;
@@ -1602,11 +1565,11 @@
android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
int dpy = input_parcel->readInt32();
-
- if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) {
+ if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
return android::BAD_VALUE;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
if (!hwc_display_[dpy]) {
return android::NO_INIT;
}
@@ -1625,4 +1588,44 @@
return android::NO_ERROR;
}
+void HWCSession::Refresh(hwc2_display_t display) {
+ SCOPE_LOCK(callbacks_lock_);
+ HWC2::Error err = callbacks_.Refresh(display);
+ while (err != HWC2::Error::None) {
+ callbacks_lock_.Wait();
+ err = callbacks_.Refresh(display);
+ }
+}
+
+void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
+ SCOPE_LOCK(callbacks_lock_);
+ HWC2::Error err = callbacks_.Hotplug(display, state);
+ while (err != HWC2::Error::None) {
+ callbacks_lock_.Wait();
+ err = callbacks_.Hotplug(display, state);
+ }
+}
+
+int HWCSession::CreateExternalDisplay(int disp, uint32_t primary_width,
+ uint32_t primary_height, bool use_primary_res) {
+ uint32_t panel_bpp = 0;
+ uint32_t pattern_type = 0;
+ if (qdutils::isDPConnected()) {
+ qdutils::getDPTestConfig(&panel_bpp, &pattern_type);
+ }
+ if (panel_bpp && pattern_type) {
+ return HWCDisplayExternalTest::Create(core_intf_, &buffer_allocator_, &callbacks_,
+ qservice_, panel_bpp,
+ pattern_type, &hwc_display_[disp]);
+ }
+ if (use_primary_res) {
+ return HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
+ primary_width, primary_height, qservice_,
+ use_primary_res, &hwc_display_[disp]);
+ } else {
+ return HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
+ qservice_, &hwc_display_[disp]);
+ }
+}
+
} // namespace sdm
diff --git a/msm8909/sdm/libs/hwc2/hwc_session.h b/msm8909/sdm/libs/hwc2/hwc_session.h
new file mode 100644
index 0000000..c794176
--- /dev/null
+++ b/msm8909/sdm/libs/hwc2/hwc_session.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright 2015 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.
+ */
+
+#ifndef __HWC_SESSION_H__
+#define __HWC_SESSION_H__
+
+#ifdef DISPLAY_CONFIG_1_1
+#include <vendor/display/config/1.1/IDisplayConfig.h>
+#else
+#include <vendor/display/config/1.0/IDisplayConfig.h>
+#endif
+
+#include <core/core_interface.h>
+#include <utils/locker.h>
+
+#include "hwc_callbacks.h"
+#include "hwc_layers.h"
+#include "hwc_display.h"
+#include "hwc_display_primary.h"
+#include "hwc_display_external.h"
+#include "hwc_display_virtual.h"
+#include "hwc_color_manager.h"
+#include "hwc_socket_handler.h"
+
+namespace sdm {
+
+#ifdef DISPLAY_CONFIG_1_1
+using vendor::display::config::V1_1::IDisplayConfig;
+#else
+using ::vendor::display::config::V1_0::IDisplayConfig;
+#endif
+using ::android::hardware::Return;
+
+// Create a singleton uevent listener thread valid for life of hardware composer process.
+// This thread blocks on uevents poll inside uevent library implementation. This poll exits
+// only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle
+// of this thread with HWC session cause HWC deinitialization to wait infinitely for the
+// thread to exit.
+class HWCUEventListener {
+ public:
+ virtual ~HWCUEventListener() {}
+ virtual void UEventHandler(const char *uevent_data, int length) = 0;
+};
+
+class HWCUEvent {
+ public:
+ HWCUEvent();
+ static void UEventThread(HWCUEvent *hwc_event);
+ void Register(HWCUEventListener *uevent_listener);
+ inline bool InitDone() { return init_done_; }
+
+ private:
+ std::mutex mutex_;
+ std::condition_variable caller_cv_;
+ HWCUEventListener *uevent_listener_ = nullptr;
+ bool init_done_ = false;
+};
+
+class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qClient::BnQClient {
+ public:
+ struct HWCModuleMethods : public hw_module_methods_t {
+ HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; }
+ };
+
+ explicit HWCSession(const hw_module_t *module);
+ int Init();
+ int Deinit();
+ HWC2::Error CreateVirtualDisplayObject(uint32_t width, uint32_t height, int32_t *format);
+
+ template <typename... Args>
+ static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display,
+ HWC2::Error (HWCDisplay::*member)(Args...), Args... args) {
+ if (!device) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
+ SCOPE_LOCK(locker_[display]);
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ auto status = HWC2::Error::BadDisplay;
+ if (hwc_session->hwc_display_[display]) {
+ auto hwc_display = hwc_session->hwc_display_[display];
+ status = (hwc_display->*member)(std::forward<Args>(args)...);
+ }
+ return INT32(status);
+ }
+
+ template <typename... Args>
+ static int32_t CallLayerFunction(hwc2_device_t *device, hwc2_display_t display,
+ hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args...),
+ Args... args) {
+ if (!device) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
+ SCOPE_LOCK(locker_[display]);
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ auto status = HWC2::Error::BadDisplay;
+ if (hwc_session->hwc_display_[display]) {
+ status = HWC2::Error::BadLayer;
+ auto hwc_layer = hwc_session->hwc_display_[display]->GetHWCLayer(layer);
+ if (hwc_layer != nullptr) {
+ status = (hwc_layer->*member)(std::forward<Args>(args)...);
+ if (hwc_session->hwc_display_[display]->GetGeometryChanges()) {
+ hwc_session->hwc_display_[display]->ResetValidation();
+ }
+ }
+ }
+ return INT32(status);
+ }
+
+ // HWC2 Functions that require a concrete implementation in hwc session
+ // and hence need to be member functions
+ static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display);
+ static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
+ hwc2_layer_t *out_layer_id);
+ static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
+ int32_t *format, hwc2_display_t *out_display_id);
+ static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer);
+ static int32_t DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display);
+ static void Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer);
+ static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
+ int32_t *out_retire_fence);
+ static int32_t RegisterCallback(hwc2_device_t *device, int32_t descriptor,
+ hwc2_callback_data_t callback_data,
+ hwc2_function_pointer_t pointer);
+ static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
+ buffer_handle_t buffer, int32_t releaseFence);
+ static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode);
+ static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
+ uint32_t *out_num_types, uint32_t *out_num_requests);
+ static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display,
+ int32_t /*android_color_mode_t*/ int_mode);
+ static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
+ const float *matrix, int32_t /*android_color_transform_t*/ hint);
+
+ private:
+ static const int kExternalConnectionTimeoutMs = 500;
+ static const int kPartialUpdateControlTimeoutMs = 100;
+ static bool disable_skip_validate_;
+
+ // hwc methods
+ static int Open(const hw_module_t *module, const char *name, hw_device_t **device);
+ static int Close(hw_device_t *device);
+ static void GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
+ int32_t *outCapabilities);
+ static hwc2_function_pointer_t GetFunction(struct hwc2_device *device, int32_t descriptor);
+
+ // Uevent handler
+ virtual void UEventHandler(const char *uevent_data, int length);
+ int GetEventValue(const char *uevent_data, int length, const char *event_info);
+ int HotPlugHandler(bool connected);
+ void ResetPanel();
+ int32_t ConnectDisplay(int disp);
+ int DisconnectDisplay(int disp);
+ int GetVsyncPeriod(int disp);
+ int32_t GetConfigCount(int disp_id, uint32_t *count);
+ int32_t GetActiveConfigIndex(int disp_id, uint32_t *config);
+ int32_t SetActiveConfigIndex(int disp_id, uint32_t config);
+ int32_t ControlPartialUpdate(int dpy, bool enable);
+ int32_t DisplayBWTransactionPending(bool *status);
+ int32_t SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status);
+ int32_t GetPanelBrightness(int *level);
+ int32_t MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level);
+ int32_t CreateExternalDisplay(int disp, uint32_t primary_width = 0,
+ uint32_t primary_height = 0,
+ bool use_primary_res = false);
+
+ // service methods
+ void StartServices();
+
+ // Methods from ::android::hardware::display::config::V1_0::IDisplayConfig follow.
+ Return<void> isDisplayConnected(IDisplayConfig::DisplayType dpy,
+ isDisplayConnected_cb _hidl_cb) override;
+ Return<int32_t> setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy,
+ IDisplayConfig::DisplayExternalStatus status) override;
+ Return<int32_t> configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op,
+ uint32_t refreshRate) override;
+ Return<void> getConfigCount(IDisplayConfig::DisplayType dpy,
+ getConfigCount_cb _hidl_cb) override;
+ Return<void> getActiveConfig(IDisplayConfig::DisplayType dpy,
+ getActiveConfig_cb _hidl_cb) override;
+ Return<int32_t> setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) override;
+ Return<void> getDisplayAttributes(uint32_t configIndex, IDisplayConfig::DisplayType dpy,
+ getDisplayAttributes_cb _hidl_cb) override;
+ Return<int32_t> setPanelBrightness(uint32_t level) override;
+ Return<void> getPanelBrightness(getPanelBrightness_cb _hidl_cb) override;
+ Return<int32_t> minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy,
+ uint32_t min_enc_level) override;
+ Return<int32_t> refreshScreen() override;
+ Return<int32_t> controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) override;
+ Return<int32_t> toggleScreenUpdate(bool on) override;
+ Return<int32_t> setIdleTimeout(uint32_t value) override;
+ Return<void> getHDRCapabilities(IDisplayConfig::DisplayType dpy,
+ getHDRCapabilities_cb _hidl_cb) override;
+ Return<int32_t> setCameraLaunchStatus(uint32_t on) override;
+ Return<void> displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::display::config::V1_1::IDisplayConfig follow.
+#ifdef DISPLAY_CONFIG_1_1
+ Return<int32_t> setDisplayAnimating(uint64_t display_id, bool animating) override;
+#endif
+
+ // QClient methods
+ virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
+ android::Parcel *output_parcel);
+ void DynamicDebug(const android::Parcel *input_parcel);
+ void SetFrameDumpConfig(const android::Parcel *input_parcel);
+ android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
+ android::status_t SetDisplayMode(const android::Parcel *input_parcel);
+ android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
+ android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
+ android::Parcel *output_parcel);
+ android::status_t HandleGetDisplayAttributesForConfig(const android::Parcel *input_parcel,
+ android::Parcel *output_parcel);
+ android::status_t GetVisibleDisplayRect(const android::Parcel *input_parcel,
+ android::Parcel *output_parcel);
+ android::status_t SetMixerResolution(const android::Parcel *input_parcel);
+ android::status_t SetColorModeOverride(const android::Parcel *input_parcel);
+
+ void Refresh(hwc2_display_t display);
+ void HotPlug(hwc2_display_t display, HWC2::Connection state);
+
+ static Locker locker_[HWC_NUM_DISPLAY_TYPES];
+ CoreInterface *core_intf_ = nullptr;
+ HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr};
+ HWCCallbacks callbacks_;
+ HWCBufferAllocator buffer_allocator_;
+ HWCBufferSyncHandler buffer_sync_handler_;
+ HWCColorManager *color_mgr_ = nullptr;
+ bool reset_panel_ = false;
+ bool secure_display_active_ = false;
+ bool external_pending_connect_ = false;
+ bool new_bw_mode_ = false;
+ bool need_invalidate_ = false;
+ int bw_mode_release_fd_ = -1;
+ qService::QService *qservice_ = nullptr;
+ HWCSocketHandler socket_handler_;
+ bool hdmi_is_primary_ = false;
+ Locker callbacks_lock_;
+};
+
+} // namespace sdm
+
+#endif // __HWC_SESSION_H__
diff --git a/msm8909/sdm/libs/hwc2/hwc_session_services.cpp b/msm8909/sdm/libs/hwc2/hwc_session_services.cpp
new file mode 100644
index 0000000..e8df03e
--- /dev/null
+++ b/msm8909/sdm/libs/hwc2/hwc_session_services.cpp
@@ -0,0 +1,494 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <core/buffer_allocator.h>
+#include <utils/debug.h>
+#include <sync/sync.h>
+#include <profiler.h>
+
+#include "hwc_buffer_sync_handler.h"
+#include "hwc_session.h"
+
+#define __CLASS__ "HWCSession"
+
+namespace sdm {
+
+using ::android::hardware::Void;
+
+void HWCSession::StartServices() {
+ status_t status = IDisplayConfig::registerAsService();
+ if (status != OK) {
+ ALOGW("%s::%s: Could not register IDisplayConfig as service (%d).",
+ __CLASS__, __FUNCTION__, status);
+ } else {
+ ALOGI("%s::%s: IDisplayConfig service registration completed.", __CLASS__, __FUNCTION__);
+ }
+}
+
+int MapDisplayType(IDisplayConfig::DisplayType dpy) {
+ switch (dpy) {
+ case IDisplayConfig::DisplayType::DISPLAY_PRIMARY:
+ return HWC_DISPLAY_PRIMARY;
+
+ case IDisplayConfig::DisplayType::DISPLAY_EXTERNAL:
+ return HWC_DISPLAY_EXTERNAL;
+
+ case IDisplayConfig::DisplayType::DISPLAY_VIRTUAL:
+ return HWC_DISPLAY_VIRTUAL;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+HWCDisplay::DisplayStatus MapExternalStatus(IDisplayConfig::DisplayExternalStatus status) {
+ switch (status) {
+ case IDisplayConfig::DisplayExternalStatus::EXTERNAL_OFFLINE:
+ return HWCDisplay::kDisplayStatusOffline;
+
+ case IDisplayConfig::DisplayExternalStatus::EXTERNAL_ONLINE:
+ return HWCDisplay::kDisplayStatusOnline;
+
+ case IDisplayConfig::DisplayExternalStatus::EXTERNAL_PAUSE:
+ return HWCDisplay::kDisplayStatusPause;
+
+ case IDisplayConfig::DisplayExternalStatus::EXTERNAL_RESUME:
+ return HWCDisplay::kDisplayStatusResume;
+
+ default:
+ break;
+ }
+
+ return HWCDisplay::kDisplayStatusInvalid;
+}
+
+// Methods from ::vendor::hardware::display::config::V1_0::IDisplayConfig follow.
+Return<void> HWCSession::isDisplayConnected(IDisplayConfig::DisplayType dpy,
+ isDisplayConnected_cb _hidl_cb) {
+ int32_t error = -EINVAL;
+ bool connected = false;
+
+ int disp_id = MapDisplayType(dpy);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+
+ if (disp_id >= 0) {
+ connected = hwc_display_[disp_id];
+ error = 0;
+ }
+
+ _hidl_cb(error, connected);
+
+ return Void();
+}
+
+int32_t HWCSession::SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status) {
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+ DLOGI("Display = %d, Status = %d", disp_id, status);
+
+ if (disp_id == HWC_DISPLAY_PRIMARY) {
+ DLOGE("Not supported for this display");
+ } else if (!hwc_display_[disp_id]) {
+ DLOGW("Display is not connected");
+ } else {
+ return hwc_display_[disp_id]->SetDisplayStatus(status);
+ }
+
+ return -EINVAL;
+}
+
+Return<int32_t> HWCSession::setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy,
+ IDisplayConfig::DisplayExternalStatus status) {
+ return SetSecondaryDisplayStatus(MapDisplayType(dpy), MapExternalStatus(status));
+}
+
+Return<int32_t> HWCSession::configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op,
+ uint32_t refreshRate) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+
+ switch (op) {
+ case IDisplayConfig::DisplayDynRefreshRateOp::DISABLE_METADATA_DYN_REFRESH_RATE:
+ return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
+
+ case IDisplayConfig::DisplayDynRefreshRateOp::ENABLE_METADATA_DYN_REFRESH_RATE:
+ return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
+
+ case IDisplayConfig::DisplayDynRefreshRateOp::SET_BINDER_DYN_REFRESH_RATE:
+ return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refreshRate);
+
+ default:
+ DLOGW("Invalid operation %d", op);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int32_t HWCSession::GetConfigCount(int disp_id, uint32_t *count) {
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+
+ if (hwc_display_[disp_id]) {
+ return hwc_display_[disp_id]->GetDisplayConfigCount(count);
+ }
+
+ return -EINVAL;
+}
+
+Return<void> HWCSession::getConfigCount(IDisplayConfig::DisplayType dpy,
+ getConfigCount_cb _hidl_cb) {
+ uint32_t count = 0;
+ int32_t error = GetConfigCount(MapDisplayType(dpy), &count);
+
+ _hidl_cb(error, count);
+
+ return Void();
+}
+
+int32_t HWCSession::GetActiveConfigIndex(int disp_id, uint32_t *config) {
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+
+ if (hwc_display_[disp_id]) {
+ return hwc_display_[disp_id]->GetActiveDisplayConfig(config);
+ }
+
+ return -EINVAL;
+}
+
+Return<void> HWCSession::getActiveConfig(IDisplayConfig::DisplayType dpy,
+ getActiveConfig_cb _hidl_cb) {
+ uint32_t config = 0;
+ int32_t error = GetActiveConfigIndex(MapDisplayType(dpy), &config);
+
+ _hidl_cb(error, config);
+
+ return Void();
+}
+
+int32_t HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) {
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+ int32_t error = -EINVAL;
+ if (hwc_display_[disp_id]) {
+ error = hwc_display_[disp_id]->SetActiveDisplayConfig(config);
+ if (!error) {
+ Refresh(0);
+ }
+ }
+
+ return error;
+}
+
+Return<int32_t> HWCSession::setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) {
+ return SetActiveConfigIndex(MapDisplayType(dpy), config);
+}
+
+Return<void> HWCSession::getDisplayAttributes(uint32_t configIndex,
+ IDisplayConfig::DisplayType dpy,
+ getDisplayAttributes_cb _hidl_cb) {
+ int32_t error = -EINVAL;
+ IDisplayConfig::DisplayAttributes display_attributes = {};
+ int disp_id = MapDisplayType(dpy);
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+ if (disp_id >= 0 && hwc_display_[disp_id]) {
+ DisplayConfigVariableInfo hwc_display_attributes;
+ error = hwc_display_[disp_id]->GetDisplayAttributesForConfig(static_cast<int>(configIndex),
+ &hwc_display_attributes);
+ if (!error) {
+ display_attributes.vsyncPeriod = hwc_display_attributes.vsync_period_ns;
+ display_attributes.xRes = hwc_display_attributes.x_pixels;
+ display_attributes.yRes = hwc_display_attributes.y_pixels;
+ display_attributes.xDpi = hwc_display_attributes.x_dpi;
+ display_attributes.yDpi = hwc_display_attributes.y_dpi;
+ display_attributes.panelType = IDisplayConfig::DisplayPortType::DISPLAY_PORT_DEFAULT;
+ display_attributes.isYuv = hwc_display_attributes.is_yuv;
+ }
+ }
+
+ return Void();
+}
+
+Return<int32_t> HWCSession::setPanelBrightness(uint32_t level) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ int32_t error = -EINVAL;
+
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(static_cast<int>(level));
+ if (error) {
+ DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error);
+ }
+ }
+
+ return error;
+}
+
+int32_t HWCSession::GetPanelBrightness(int *level) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ int32_t error = -EINVAL;
+
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(level);
+ if (error) {
+ DLOGE("Failed to get the panel brightness. Error = %d", error);
+ }
+ }
+
+ return error;
+}
+
+Return<void> HWCSession::getPanelBrightness(getPanelBrightness_cb _hidl_cb) {
+ int level = 0;
+ int32_t error = GetPanelBrightness(&level);
+
+ _hidl_cb(error, static_cast<uint32_t>(level));
+
+ return Void();
+}
+
+int32_t HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level) {
+ DLOGI("Display %d", disp_id);
+
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+ if (disp_id != HWC_DISPLAY_EXTERNAL) {
+ DLOGE("Not supported for display");
+ } else if (!hwc_display_[disp_id]) {
+ DLOGW("Display is not connected");
+ } else {
+ return hwc_display_[disp_id]->OnMinHdcpEncryptionLevelChange(min_enc_level);
+ }
+
+ return -EINVAL;
+}
+
+Return<int32_t> HWCSession::minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy,
+ uint32_t min_enc_level) {
+ return MinHdcpEncryptionLevelChanged(MapDisplayType(dpy), min_enc_level);
+}
+
+Return<int32_t> HWCSession::refreshScreen() {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ Refresh(HWC_DISPLAY_PRIMARY);
+
+ return 0;
+}
+
+int32_t HWCSession::ControlPartialUpdate(int disp_id, bool enable) {
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ if (disp_id != HWC_DISPLAY_PRIMARY) {
+ DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
+ return -EINVAL;
+ }
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+ HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+ if (!hwc_display) {
+ DLOGE("primary display object is not instantiated");
+ return -EINVAL;
+ }
+
+ uint32_t pending = 0;
+ DisplayError hwc_error = hwc_display->ControlPartialUpdate(enable, &pending);
+
+ if (hwc_error == kErrorNone) {
+ if (!pending) {
+ return 0;
+ }
+ } else if (hwc_error == kErrorNotSupported) {
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+
+ // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
+ Refresh(HWC_DISPLAY_PRIMARY);
+
+ // Wait until partial update control is complete
+ int32_t error = locker_[disp_id].WaitFinite(kPartialUpdateControlTimeoutMs);
+
+ return error;
+}
+
+Return<int32_t> HWCSession::controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) {
+ return ControlPartialUpdate(MapDisplayType(dpy), enable);
+}
+
+Return<int32_t> HWCSession::toggleScreenUpdate(bool on) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+
+ int32_t error = -EINVAL;
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(on);
+ if (error) {
+ DLOGE("Failed to toggle screen updates = %d. Error = %d", on, error);
+ }
+ }
+
+ return error;
+}
+
+Return<int32_t> HWCSession::setIdleTimeout(uint32_t value) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(value);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+Return<void> HWCSession::getHDRCapabilities(IDisplayConfig::DisplayType dpy,
+ getHDRCapabilities_cb _hidl_cb) {
+ int32_t error = -EINVAL;
+ IDisplayConfig::DisplayHDRCapabilities hdr_caps = {};
+
+ do {
+ int disp_id = MapDisplayType(dpy);
+ if (disp_id < 0) {
+ DLOGE("Invalid display id = %d", disp_id);
+ break;
+ }
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+ HWCDisplay *hwc_display = hwc_display_[disp_id];
+ if (!hwc_display) {
+ DLOGE("Display = %d is not connected.", disp_id);
+ break;
+ }
+
+ // query number of hdr types
+ uint32_t out_num_types = 0;
+ if (hwc_display->GetHdrCapabilities(&out_num_types, nullptr, nullptr, nullptr, nullptr)
+ != HWC2::Error::None) {
+ break;
+ }
+
+ if (!out_num_types) {
+ error = 0;
+ break;
+ }
+
+ // query hdr caps
+ hdr_caps.supportedHdrTypes.resize(out_num_types);
+
+ float out_max_luminance = 0.0f;
+ float out_max_average_luminance = 0.0f;
+ float out_min_luminance = 0.0f;
+ if (hwc_display->GetHdrCapabilities(&out_num_types, hdr_caps.supportedHdrTypes.data(),
+ &out_max_luminance, &out_max_average_luminance,
+ &out_min_luminance)
+ == HWC2::Error::None) {
+ error = 0;
+ }
+ } while (false);
+
+ _hidl_cb(error, hdr_caps);
+
+ return Void();
+}
+
+Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+
+ HWBwModes mode = on > 0 ? kBwCamera : kBwDefault;
+
+ // trigger invalidate to apply new bw caps.
+ Refresh(HWC_DISPLAY_PRIMARY);
+
+ if (core_intf_->SetMaxBandwidthMode(mode) != kErrorNone) {
+ return -EINVAL;
+ }
+
+ new_bw_mode_ = true;
+ need_invalidate_ = true;
+ hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
+
+ return 0;
+}
+
+int32_t HWCSession::DisplayBWTransactionPending(bool *status) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ if (sync_wait(bw_mode_release_fd_, 0) < 0) {
+ DLOGI("bw_transaction_release_fd is not yet signaled: err= %s", strerror(errno));
+ *status = false;
+ }
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+Return<void> HWCSession::displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) {
+ bool status = true;
+
+ int32_t error = DisplayBWTransactionPending(&status);
+
+ _hidl_cb(error, status);
+
+ return Void();
+}
+
+#ifdef DISPLAY_CONFIG_1_1
+// Methods from ::vendor::hardware::display::config::V1_1::IDisplayConfig follow.
+Return<int32_t> HWCSession::setDisplayAnimating(uint64_t display_id, bool animating ) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[display_id]);
+ return CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id,
+ &HWCDisplay::SetDisplayAnimating, animating);
+}
+#endif
+
+
+} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_tonemapper.cpp b/msm8909/sdm/libs/hwc2/hwc_tonemapper.cpp
similarity index 73%
copy from sdm845/sdm/libs/hwc2/hwc_tonemapper.cpp
copy to msm8909/sdm/libs/hwc2/hwc_tonemapper.cpp
index 7bda725..e68741e 100644
--- a/sdm845/sdm/libs/hwc2/hwc_tonemapper.cpp
+++ b/msm8909/sdm/libs/hwc2/hwc_tonemapper.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016 - 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -49,18 +49,57 @@
namespace sdm {
-ToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator) :
- buffer_allocator_(buffer_allocator) {
+ToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator)
+ : tone_map_task_(*this), buffer_allocator_(buffer_allocator) {
buffer_info_.resize(kNumIntermediateBuffers);
}
ToneMapSession::~ToneMapSession() {
- delete gpu_tone_mapper_;
- gpu_tone_mapper_ = nullptr;
+ tone_map_task_.PerformTask(ToneMapTaskCode::kCodeDestroy, nullptr);
FreeIntermediateBuffers();
buffer_info_.clear();
}
+void ToneMapSession::OnTask(const ToneMapTaskCode &task_code,
+ SyncTask<ToneMapTaskCode>::TaskContext *task_context) {
+ switch (task_code) {
+ case ToneMapTaskCode::kCodeGetInstance: {
+ ToneMapGetInstanceContext *ctx = static_cast<ToneMapGetInstanceContext *>(task_context);
+ Lut3d &lut_3d = ctx->layer->lut_3d;
+ Color10Bit *grid_entries = NULL;
+ int grid_size = 0;
+ if (lut_3d.validGridEntries) {
+ grid_entries = lut_3d.gridEntries;
+ grid_size = INT(lut_3d.gridSize);
+ }
+ gpu_tone_mapper_ = TonemapperFactory_GetInstance(tone_map_config_.type,
+ lut_3d.lutEntries, lut_3d.dim,
+ grid_entries, grid_size,
+ tone_map_config_.secure);
+ }
+ break;
+
+ case ToneMapTaskCode::kCodeBlit: {
+ ToneMapBlitContext *ctx = static_cast<ToneMapBlitContext *>(task_context);
+ uint8_t buffer_index = current_buffer_index_;
+ const void *dst_hnd = reinterpret_cast<const void *>
+ (buffer_info_[buffer_index].private_data);
+ const void *src_hnd = reinterpret_cast<const void *>
+ (ctx->layer->input_buffer.buffer_id);
+ ctx->fence_fd = gpu_tone_mapper_->blit(dst_hnd, src_hnd, ctx->merged_fd);
+ }
+ break;
+
+ case ToneMapTaskCode::kCodeDestroy: {
+ delete gpu_tone_mapper_;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
DisplayError ToneMapSession::AllocateIntermediateBuffers(const Layer *layer) {
DisplayError error = kErrorNone;
for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) {
@@ -142,6 +181,7 @@
}
if (layer->request.flags.tone_map) {
+ DLOGV_IF(kTagClient, "Tonemapping for layer at index %d", i);
switch (layer->composition) {
case kCompositionGPUTarget:
if (!gpu_count) {
@@ -149,8 +189,8 @@
// then SDM marks them for SDE Composition because the cached FB layer gets displayed.
// GPU count will be 0 in this case. Try to use the existing tone-mapped frame buffer.
// No ToneMap/Blit is required. Just update the buffer & acquire fence fd of FB layer.
- if (!tone_map_sessions_.empty()) {
- ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(fb_session_index_);
+ if (!tone_map_sessions_.empty() && (fb_session_index_ >= 0)) {
+ ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(UINT32(fb_session_index_));
fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer);
fb_tone_map_session->layer_index_ = INT(i);
fb_tone_map_session->acquired_ = true;
@@ -158,7 +198,7 @@
}
}
error = AcquireToneMapSession(layer, &session_index);
- fb_session_index_ = session_index;
+ fb_session_index_ = INT(session_index);
break;
default:
error = AcquireToneMapSession(layer, &session_index);
@@ -172,6 +212,7 @@
ToneMapSession *session = tone_map_sessions_.at(session_index);
ToneMap(layer, session);
+ DLOGI_IF(kTagClient, "Layer %d associated with session index %d", i, session_index);
session->layer_index_ = INT(i);
}
}
@@ -180,35 +221,30 @@
}
void HWCToneMapper::ToneMap(Layer* layer, ToneMapSession *session) {
- int fence_fd = -1;
- int acquire_fd = -1;
- int merged_fd = -1;
+ ToneMapBlitContext ctx = {};
+ ctx.layer = layer;
uint8_t buffer_index = session->current_buffer_index_;
- const private_handle_t *dst_hnd = static_cast<private_handle_t *>
- (session->buffer_info_[buffer_index].private_data);
- const private_handle_t *src_hnd = reinterpret_cast<const private_handle_t *>
- (layer->input_buffer.buffer_id);
+ int &release_fence_fd = session->release_fence_fd_[buffer_index];
// use and close the layer->input_buffer acquire fence fd.
- acquire_fd = layer->input_buffer.acquire_fence_fd;
- buffer_sync_handler_.SyncMerge(session->release_fence_fd_[buffer_index], acquire_fd, &merged_fd);
+ int acquire_fd = layer->input_buffer.acquire_fence_fd;
+ buffer_sync_handler_.SyncMerge(release_fence_fd, acquire_fd, &ctx.merged_fd);
if (acquire_fd >= 0) {
CloseFd(&acquire_fd);
}
- if (session->release_fence_fd_[buffer_index] >= 0) {
- CloseFd(&session->release_fence_fd_[buffer_index]);
+ if (release_fence_fd >= 0) {
+ CloseFd(&release_fence_fd);
}
DTRACE_BEGIN("GPU_TM_BLIT");
- fence_fd = session->gpu_tone_mapper_->blit(reinterpret_cast<const void *>(dst_hnd),
- reinterpret_cast<const void *>(src_hnd), merged_fd);
+ session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeBlit, &ctx);
DTRACE_END();
- DumpToneMapOutput(session, &fence_fd);
- session->UpdateBuffer(fence_fd, &layer->input_buffer);
+ DumpToneMapOutput(session, &ctx.fence_fd);
+ session->UpdateBuffer(ctx.fence_fd, &layer->input_buffer);
}
void HWCToneMapper::PostCommit(LayerStack *layer_stack) {
@@ -225,8 +261,16 @@
session->acquired_ = false;
it++;
} else {
+ DLOGI_IF(kTagClient, "Tone map session %d closed.", session_index);
delete session;
it = tone_map_sessions_.erase(it);
+ int deleted_session = INT(session_index);
+ // If FB tonemap session gets deleted, reset fb_session_index_, else update it.
+ if (deleted_session == fb_session_index_) {
+ fb_session_index_ = -1;
+ } else if (deleted_session < fb_session_index_) {
+ fb_session_index_--;
+ }
}
}
}
@@ -237,7 +281,7 @@
delete tone_map_sessions_.back();
tone_map_sessions_.pop_back();
}
- fb_session_index_ = 0;
+ fb_session_index_ = -1;
}
}
@@ -248,6 +292,7 @@
}
void HWCToneMapper::DumpToneMapOutput(ToneMapSession *session, int *acquire_fd) {
+ DisplayError error = kErrorNone;
if (!dump_frame_count_) {
return;
}
@@ -263,11 +308,17 @@
}
}
+ error = buffer_allocator_->MapBuffer(target_buffer, *acquire_fd);
+ if (error != kErrorNone) {
+ DLOGE("MapBuffer failed, base addr = %x", target_buffer->base);
+ return;
+ }
+
size_t result = 0;
char dump_file_name[PATH_MAX];
- snprintf(dump_file_name, sizeof(dump_file_name), "/data/misc/display/frame_dump_primary"
- "/tonemap_%dx%d_frame%d.raw", target_buffer->width, target_buffer->height,
- dump_frame_index_);
+ snprintf(dump_file_name, sizeof(dump_file_name), "%s/frame_dump_primary"
+ "/tonemap_%dx%d_frame%d.raw", HWCDebugHandler::DumpDir(), target_buffer->width,
+ target_buffer->height, dump_frame_index_);
FILE* fp = fopen(dump_file_name, "w+");
if (fp) {
@@ -281,15 +332,7 @@
}
DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index) {
- Color10Bit *grid_entries = NULL;
- int grid_size = 0;
-
- if (layer->lut_3d.validGridEntries) {
- grid_entries = layer->lut_3d.gridEntries;
- grid_size = INT(layer->lut_3d.gridSize);
- }
-
- // When the property sdm.disable_hdr_lut_gen is set, the lutEntries and gridEntries in
+ // When the property vendor.display.disable_hdr_lut_gen is set, the lutEntries and gridEntries in
// the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut
// for Tonemapping.
if (!layer->lut_3d.lutEntries || !layer->lut_3d.dim) {
@@ -311,13 +354,15 @@
}
ToneMapSession *session = new ToneMapSession(buffer_allocator_);
+ if (!session) {
+ return kErrorMemory;
+ }
session->SetToneMapConfig(layer);
- session->gpu_tone_mapper_ = TonemapperFactory_GetInstance(session->tone_map_config_.type,
- layer->lut_3d.lutEntries,
- layer->lut_3d.dim,
- grid_entries, grid_size,
- session->tone_map_config_.secure);
+
+ ToneMapGetInstanceContext ctx;
+ ctx.layer = layer;
+ session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeGetInstance, &ctx);
if (session->gpu_tone_mapper_ == NULL) {
DLOGE("Get Tonemapper failed!");
diff --git a/sdm845/sdm/libs/hwc2/hwc_tonemapper.h b/msm8909/sdm/libs/hwc2/hwc_tonemapper.h
similarity index 83%
rename from sdm845/sdm/libs/hwc2/hwc_tonemapper.h
rename to msm8909/sdm/libs/hwc2/hwc_tonemapper.h
index 8367c3e..8bef3b1 100644
--- a/sdm845/sdm/libs/hwc2/hwc_tonemapper.h
+++ b/msm8909/sdm/libs/hwc2/hwc_tonemapper.h
@@ -37,6 +37,7 @@
#include <core/layer_stack.h>
#include <utils/sys.h>
+#include <utils/sync_task.h>
#include <vector>
#include "hwc_buffer_sync_handler.h"
#include "hwc_buffer_allocator.h"
@@ -45,6 +46,22 @@
namespace sdm {
+enum class ToneMapTaskCode : int32_t {
+ kCodeGetInstance,
+ kCodeBlit,
+ kCodeDestroy,
+};
+
+struct ToneMapGetInstanceContext : public SyncTask<ToneMapTaskCode>::TaskContext {
+ Layer *layer = nullptr;
+};
+
+struct ToneMapBlitContext : public SyncTask<ToneMapTaskCode>::TaskContext {
+ Layer *layer = nullptr;
+ int merged_fd = -1;
+ int fence_fd = -1;
+};
+
struct ToneMapConfig {
int type = 0;
ColorPrimaries colorPrimaries = ColorPrimaries_Max;
@@ -53,7 +70,7 @@
bool secure = false;
};
-class ToneMapSession {
+class ToneMapSession : public SyncTask<ToneMapTaskCode>::TaskHandler {
public:
explicit ToneMapSession(HWCBufferAllocator *buffer_allocator);
~ToneMapSession();
@@ -64,7 +81,12 @@
void SetToneMapConfig(Layer *layer);
bool IsSameToneMapConfig(Layer *layer);
+ // TaskHandler methods implementation.
+ virtual void OnTask(const ToneMapTaskCode &task_code,
+ SyncTask<ToneMapTaskCode>::TaskContext *task_context);
+
static const uint8_t kNumIntermediateBuffers = 2;
+ SyncTask<ToneMapTaskCode> tone_map_task_;
Tonemapper *gpu_tone_mapper_ = nullptr;
HWCBufferAllocator *buffer_allocator_ = nullptr;
ToneMapConfig tone_map_config_ = {};
@@ -96,7 +118,7 @@
HWCBufferAllocator *buffer_allocator_ = nullptr;
uint32_t dump_frame_count_ = 0;
uint32_t dump_frame_index_ = 0;
- uint32_t fb_session_index_ = 0;
+ int fb_session_index_ = -1;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/utils/Android.mk b/msm8909/sdm/libs/utils/Android.mk
similarity index 94%
rename from sdm845/sdm/libs/utils/Android.mk
rename to msm8909/sdm/libs/utils/Android.mk
index fe89104..09e1414 100644
--- a/sdm845/sdm/libs/utils/Android.mk
+++ b/msm8909/sdm/libs/utils/Android.mk
@@ -25,6 +25,7 @@
$(SDM_HEADER_PATH)/utils/locker.h \
$(SDM_HEADER_PATH)/utils/rect.h \
$(SDM_HEADER_PATH)/utils/sys.h \
+ $(SDM_HEADER_PATH)/utils/sync_task.h \
$(SDM_HEADER_PATH)/utils/utils.h \
$(SDM_HEADER_PATH)/utils/factory.h
diff --git a/sdm845/sdm/libs/utils/Makefile.am b/msm8909/sdm/libs/utils/Makefile.am
similarity index 100%
rename from sdm845/sdm/libs/utils/Makefile.am
rename to msm8909/sdm/libs/utils/Makefile.am
diff --git a/msm8909/sdm/libs/utils/debug.cpp b/msm8909/sdm/libs/utils/debug.cpp
new file mode 100644
index 0000000..a012ab4
--- /dev/null
+++ b/msm8909/sdm/libs/utils/debug.cpp
@@ -0,0 +1,216 @@
+/*
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <utils/debug.h>
+#include <utils/constants.h>
+#include <string>
+#include <algorithm>
+
+namespace sdm {
+
+Debug Debug::debug_;
+
+Debug::Debug() : debug_handler_(&default_debug_handler_) {
+}
+
+int Debug::GetSimulationFlag() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(COMPOSITION_MASK_PROP, &value);
+
+ return value;
+}
+
+int Debug::GetHDMIResolution() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(HDMI_CONFIG_INDEX_PROP, &value);
+ return value;
+}
+
+void Debug::GetIdleTimeoutMs(uint32_t *active_ms, uint32_t *inactive_ms) {
+ int active_val = IDLE_TIMEOUT_ACTIVE_MS;
+ int inactive_val = IDLE_TIMEOUT_INACTIVE_MS;
+
+ debug_.debug_handler_->GetProperty(IDLE_TIME_PROP, &active_val);
+ debug_.debug_handler_->GetProperty(IDLE_TIME_INACTIVE_PROP, &inactive_val);
+
+ *active_ms = UINT32(active_val);
+ *inactive_ms = UINT32(inactive_val);
+}
+
+int Debug::GetBootAnimLayerCount() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(BOOT_ANIMATION_LAYER_COUNT_PROP, &value);
+
+ return value;
+}
+
+bool Debug::IsRotatorDownScaleDisabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(DISABLE_ROTATOR_DOWNSCALE_PROP, &value);
+
+ return (value == 1);
+}
+
+bool Debug::IsDecimationDisabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(DISABLE_DECIMATION_PROP, &value);
+
+ return (value == 1);
+}
+
+int Debug::GetMaxPipesPerMixer(DisplayType display_type) {
+ int value = -1;
+ switch (display_type) {
+ case kPrimary:
+ debug_.debug_handler_->GetProperty(PRIMARY_MIXER_STAGES_PROP, &value);
+ break;
+ case kHDMI:
+ debug_.debug_handler_->GetProperty(EXTERNAL_MIXER_STAGES_PROP, &value);
+ break;
+ case kVirtual:
+ debug_.debug_handler_->GetProperty(VIRTUAL_MIXER_STAGES_PROP, &value);
+ break;
+ default:
+ break;
+ }
+
+ return value;
+}
+
+int Debug::GetMaxUpscale() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(MAX_UPSCALE_PROP, &value);
+
+ return value;
+}
+
+bool Debug::IsVideoModeEnabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(VIDEO_MODE_PANEL_PROP, &value);
+
+ return (value == 1);
+}
+
+bool Debug::IsRotatorUbwcDisabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(DISABLE_ROTATOR_UBWC_PROP, &value);
+
+ return (value == 1);
+}
+
+bool Debug::IsRotatorSplitDisabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(DISABLE_ROTATOR_SPLIT_PROP, &value);
+
+ return (value == 1);
+}
+
+bool Debug::IsScalarDisabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(DISABLE_SCALER_PROP, &value);
+
+ return (value == 1);
+}
+
+bool Debug::IsUbwcTiledFrameBuffer() {
+ int ubwc_disabled = 0;
+ int ubwc_framebuffer = 0;
+
+ debug_.debug_handler_->GetProperty(DISABLE_UBWC_PROP, &ubwc_disabled);
+
+ if (!ubwc_disabled) {
+ debug_.debug_handler_->GetProperty(ENABLE_FB_UBWC_PROP, &ubwc_framebuffer);
+ }
+
+ return (ubwc_framebuffer == 1);
+}
+
+bool Debug::IsAVRDisabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(DISABLE_AVR_PROP, &value);
+
+ return (value == 1);
+}
+
+bool Debug::IsExtAnimDisabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(DISABLE_EXTERNAL_ANIMATION_PROP, &value);
+
+ return (value == 1);
+}
+
+bool Debug::IsPartialSplitDisabled() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty(DISABLE_PARTIAL_SPLIT_PROP, &value);
+
+ return (value == 1);
+}
+
+DisplayError Debug::GetMixerResolution(uint32_t *width, uint32_t *height) {
+ char value[64] = {};
+
+ DisplayError error = debug_.debug_handler_->GetProperty(MIXER_RESOLUTION_PROP, value);
+ if (error !=kErrorNone) {
+ return error;
+ }
+
+ std::string str(value);
+
+ *width = UINT32(stoi(str));
+ *height = UINT32(stoi(str.substr(str.find('x') + 1)));
+
+ return kErrorNone;
+}
+
+int Debug::GetExtMaxlayers() {
+ int max_external_layers = 0;
+ debug_.debug_handler_->GetProperty(MAX_EXTERNAL_LAYERS_PROP, &max_external_layers);
+
+ return std::max(max_external_layers, 2);
+}
+
+bool Debug::GetProperty(const char* property_name, char* value) {
+ if (debug_.debug_handler_->GetProperty(property_name, value) != kErrorNone) {
+ return false;
+ }
+
+ return true;
+}
+
+bool Debug::SetProperty(const char* property_name, const char* value) {
+ if (debug_.debug_handler_->SetProperty(property_name, value) != kErrorNone) {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace sdm
+
diff --git a/sdm845/sdm/libs/utils/formats.cpp b/msm8909/sdm/libs/utils/formats.cpp
similarity index 100%
rename from sdm845/sdm/libs/utils/formats.cpp
rename to msm8909/sdm/libs/utils/formats.cpp
diff --git a/msm8909/sdm/libs/utils/rect.cpp b/msm8909/sdm/libs/utils/rect.cpp
new file mode 100644
index 0000000..8413257
--- /dev/null
+++ b/msm8909/sdm/libs/utils/rect.cpp
@@ -0,0 +1,270 @@
+/*
+* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <math.h>
+#include <utils/rect.h>
+#include <utils/constants.h>
+#include <algorithm>
+
+#define __CLASS__ "RectUtils"
+
+namespace sdm {
+
+bool IsValid(const LayerRect &rect) {
+ return ((rect.bottom > rect.top) && (rect.right > rect.left));
+}
+
+bool IsCongruent(const LayerRect &rect1, const LayerRect &rect2) {
+ return ((rect1.left == rect2.left) &&
+ (rect1.top == rect2.top) &&
+ (rect1.right == rect2.right) &&
+ (rect1.bottom == rect2.bottom));
+}
+
+void LogI(DebugTag debug_tag, const char *prefix, const LayerRect &roi) {
+ DLOGI_IF(debug_tag, "%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
+ prefix, roi.left, roi.top, roi.right, roi.bottom);
+}
+
+void Log(DebugTag debug_tag, const char *prefix, const LayerRect &roi) {
+ DLOGV_IF(debug_tag, "%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
+ prefix, roi.left, roi.top, roi.right, roi.bottom);
+}
+
+void Normalize(const uint32_t &align_x, const uint32_t &align_y, LayerRect *rect) {
+ rect->left = ROUND_UP_ALIGN_UP(rect->left, align_x);
+ rect->right = ROUND_UP_ALIGN_DOWN(rect->right, align_x);
+ rect->top = ROUND_UP_ALIGN_UP(rect->top, align_y);
+ rect->bottom = ROUND_UP_ALIGN_DOWN(rect->bottom, align_y);
+}
+
+LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2) {
+ LayerRect res;
+
+ if (!IsValid(rect1) || !IsValid(rect2)) {
+ return LayerRect();
+ }
+
+ res.left = std::max(rect1.left, rect2.left);
+ res.top = std::max(rect1.top, rect2.top);
+ res.right = std::min(rect1.right, rect2.right);
+ res.bottom = std::min(rect1.bottom, rect2.bottom);
+
+ if (!IsValid(res)) {
+ return LayerRect();
+ }
+
+ return res;
+}
+
+LayerRect Reposition(const LayerRect &rect, const int &x_offset, const int &y_offset) {
+ LayerRect res;
+
+ if (!IsValid(rect)) {
+ return LayerRect();
+ }
+
+ res.left = rect.left + FLOAT(x_offset);
+ res.top = rect.top + FLOAT(y_offset);
+ res.right = rect.right + FLOAT(x_offset);
+ res.bottom = rect.bottom + FLOAT(y_offset);
+
+ return res;
+}
+
+// Not a geometrical rect deduction. Deducts rect2 from rect1 only if it results a single rect
+LayerRect Subtract(const LayerRect &rect1, const LayerRect &rect2) {
+ LayerRect res;
+
+ res = rect1;
+
+ if ((rect1.left == rect2.left) && (rect1.right == rect2.right)) {
+ if ((rect1.top == rect2.top) && (rect2.bottom <= rect1.bottom)) {
+ res.top = rect2.bottom;
+ } else if ((rect1.bottom == rect2.bottom) && (rect2.top >= rect1.top)) {
+ res.bottom = rect2.top;
+ }
+ } else if ((rect1.top == rect2.top) && (rect1.bottom == rect2.bottom)) {
+ if ((rect1.left == rect2.left) && (rect2.right <= rect1.right)) {
+ res.left = rect2.right;
+ } else if ((rect1.right == rect2.right) && (rect2.left >= rect1.left)) {
+ res.right = rect2.left;
+ }
+ }
+
+ return res;
+}
+
+LayerRect Union(const LayerRect &rect1, const LayerRect &rect2) {
+ LayerRect res;
+
+ if (!IsValid(rect1) && !IsValid(rect2)) {
+ return LayerRect();
+ }
+
+ if (!IsValid(rect1)) {
+ return rect2;
+ }
+
+ if (!IsValid(rect2)) {
+ return rect1;
+ }
+
+ res.left = std::min(rect1.left, rect2.left);
+ res.top = std::min(rect1.top, rect2.top);
+ res.right = std::max(rect1.right, rect2.right);
+ res.bottom = std::max(rect1.bottom, rect2.bottom);
+
+ return res;
+}
+
+void SplitLeftRight(const LayerRect &in_rect, uint32_t split_count, uint32_t align_x,
+ bool flip_horizontal, LayerRect *out_rects) {
+ LayerRect rect_temp = in_rect;
+
+ uint32_t split_width = UINT32(rect_temp.right - rect_temp.left) / split_count;
+ float aligned_width = FLOAT(CeilToMultipleOf(split_width, align_x));
+
+ for (uint32_t count = 0; count < split_count; count++) {
+ float aligned_right = rect_temp.left + aligned_width;
+ out_rects[count].left = rect_temp.left;
+ out_rects[count].right = std::min(rect_temp.right, aligned_right);
+ out_rects[count].top = rect_temp.top;
+ out_rects[count].bottom = rect_temp.bottom;
+
+ rect_temp.left = out_rects[count].right;
+
+ Log(kTagRotator, "SplitLeftRight", out_rects[count]);
+ }
+
+ // If we have a horizontal flip, then we should be splitting the source from right to left
+ // to ensure that the right split will have an aligned width that matches the alignment on the
+ // destination.
+ if (flip_horizontal && split_count > 1) {
+ out_rects[0].right = out_rects[0].left + (out_rects[1].right - out_rects[1].left);
+ out_rects[1].left = out_rects[0].right;
+ Log(kTagRotator, "Adjusted Left", out_rects[0]);
+ Log(kTagRotator, "Adjusted Right", out_rects[1]);
+ }
+}
+
+void SplitTopBottom(const LayerRect &in_rect, uint32_t split_count, uint32_t align_y,
+ bool flip_horizontal, LayerRect *out_rects) {
+ LayerRect rect_temp = in_rect;
+
+ uint32_t split_height = UINT32(rect_temp.bottom - rect_temp.top) / split_count;
+ float aligned_height = FLOAT(CeilToMultipleOf(split_height, align_y));
+
+ for (uint32_t count = 0; count < split_count; count++) {
+ float aligned_bottom = rect_temp.top + aligned_height;
+ out_rects[count].top = rect_temp.top;
+ out_rects[count].bottom = std::min(rect_temp.bottom, aligned_bottom);
+ out_rects[count].left = rect_temp.left;
+ out_rects[count].right = rect_temp.right;
+
+ rect_temp.top = out_rects[count].bottom;
+
+ Log(kTagRotator, "SplitTopBottom", out_rects[count]);
+ }
+
+ // If we have a horizontal flip, then we should be splitting the destination from bottom to top
+ // to ensure that the bottom split's y-offset is aligned correctly after we swap the destinations
+ // while accounting for the flip.
+ if (flip_horizontal && split_count > 1) {
+ out_rects[0].bottom = out_rects[0].top + (out_rects[1].bottom - out_rects[1].top);
+ out_rects[1].top = out_rects[0].bottom;
+ Log(kTagRotator, "Adjusted Top", out_rects[0]);
+ Log(kTagRotator, "Adjusted Bottom", out_rects[1]);
+ }
+}
+
+void MapRect(const LayerRect &src_domain, const LayerRect &dst_domain, const LayerRect &in_rect,
+ LayerRect *out_rect) {
+ if (!IsValid(src_domain) || !IsValid(dst_domain) || !IsValid(in_rect)) {
+ return;
+ }
+
+ int x_offset = INT(src_domain.left);
+ int y_offset = INT(src_domain.top);
+
+ LayerRect modified_in_rect = Reposition(in_rect, -x_offset, -y_offset);
+ float src_domain_width = src_domain.right - src_domain.left;
+ float src_domain_height = src_domain.bottom - src_domain.top;
+ float dst_domain_width = dst_domain.right - dst_domain.left;
+ float dst_domain_height = dst_domain.bottom - dst_domain.top;
+
+ float width_ratio = dst_domain_width / src_domain_width;
+ float height_ratio = dst_domain_height / src_domain_height;
+
+ out_rect->left = dst_domain.left + (width_ratio * modified_in_rect.left);
+ out_rect->top = dst_domain.top + (height_ratio * modified_in_rect.top);
+ out_rect->right = dst_domain.left + (width_ratio * modified_in_rect.right);
+ out_rect->bottom = dst_domain.top + (height_ratio * modified_in_rect.bottom);
+}
+
+void TransformHV(const LayerRect &src_domain, const LayerRect &in_rect,
+ const LayerTransform &transform, LayerRect *out_rect) {
+ if (!IsValid(src_domain) || !IsValid(in_rect)) {
+ return;
+ }
+
+ float in_width = in_rect.right - in_rect.left;
+ float in_height = in_rect.bottom - in_rect.top;
+ float x_offset = in_rect.left - src_domain.left;
+ float y_offset = in_rect.top - src_domain.top;
+ *out_rect = in_rect;
+
+ if (transform.flip_horizontal) {
+ out_rect->right = src_domain.right - x_offset;
+ out_rect->left = out_rect->right - in_width;
+ }
+
+ if (transform.flip_vertical) {
+ out_rect->bottom = src_domain.bottom - y_offset;
+ out_rect->top = out_rect->bottom - in_height;
+ }
+}
+
+RectOrientation GetOrientation(const LayerRect &in_rect) {
+ if (!IsValid(in_rect)) {
+ return kOrientationUnknown;
+ }
+
+ float input_width = in_rect.right - in_rect.left;
+ float input_height = in_rect.bottom - in_rect.top;
+
+ if (input_width < input_height) {
+ return kOrientationPortrait;
+ }
+
+ return kOrientationLandscape;
+}
+
+} // namespace sdm
+
diff --git a/sdm845/sdm/libs/utils/sys.cpp b/msm8909/sdm/libs/utils/sys.cpp
similarity index 100%
rename from sdm845/sdm/libs/utils/sys.cpp
rename to msm8909/sdm/libs/utils/sys.cpp
diff --git a/sdm845/sdm/libs/utils/utils.cpp b/msm8909/sdm/libs/utils/utils.cpp
similarity index 100%
rename from sdm845/sdm/libs/utils/utils.cpp
rename to msm8909/sdm/libs/utils/utils.cpp
diff --git a/msm8909w_3100/.clang-format b/msm8909w_3100/.clang-format
new file mode 100644
index 0000000..9082c40
--- /dev/null
+++ b/msm8909w_3100/.clang-format
@@ -0,0 +1,13 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortBlocksOnASingleLine: false
+ColumnLimit: 100
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+DerivePointerAlignment: false
+PointerAlignment: Right
+#ReflowComments: false
diff --git a/sdm845/Android.mk b/msm8909w_3100/Android.mk
similarity index 94%
rename from sdm845/Android.mk
rename to msm8909w_3100/Android.mk
index 226e8a0..1a285bf 100644
--- a/sdm845/Android.mk
+++ b/msm8909w_3100/Android.mk
@@ -3,7 +3,7 @@
ifneq ($(TARGET_IS_HEADLESS), true)
display-hals += libcopybit liblight libmemtrack hdmi_cec \
- $(sdm-libs)/hwc $(sdm-libs)/hwc2 gpu_tonemapper libdrmutils
+ $(sdm-libs)/hwc $(sdm-libs)/hwc2 gpu_tonemapper libdrmutils libdisplayconfig
endif
ifneq ($(TARGET_USES_GRALLOC1), true)
diff --git a/sdm845/common.mk b/msm8909w_3100/common.mk
similarity index 97%
rename from sdm845/common.mk
rename to msm8909w_3100/common.mk
index 88d1aee..b253c80 100644
--- a/sdm845/common.mk
+++ b/msm8909w_3100/common.mk
@@ -3,7 +3,7 @@
#Common C flags
common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
-common_flags += -Wconversion -Wall -Werror -std=c++11
+common_flags += -Wconversion -Wall -Werror -std=c++14
ifeq ($(TARGET_IS_HEADLESS), true)
common_flags += -DTARGET_HEADLESS
LOCAL_CLANG := false
diff --git a/sdm845/gpu_tonemapper/Android.mk b/msm8909w_3100/gpu_tonemapper/Android.mk
similarity index 92%
rename from sdm845/gpu_tonemapper/Android.mk
rename to msm8909w_3100/gpu_tonemapper/Android.mk
index 769d0ab..a2471e5 100644
--- a/sdm845/gpu_tonemapper/Android.mk
+++ b/msm8909w_3100/gpu_tonemapper/Android.mk
@@ -11,7 +11,6 @@
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(TARGET_OUT_HEADERS)/qcom/display/
-LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_SHARED_LIBRARIES := libEGL libGLESv2 libui libutils liblog
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
diff --git a/sdm845/gpu_tonemapper/EGLImageBuffer.cpp b/msm8909w_3100/gpu_tonemapper/EGLImageBuffer.cpp
similarity index 100%
copy from sdm845/gpu_tonemapper/EGLImageBuffer.cpp
copy to msm8909w_3100/gpu_tonemapper/EGLImageBuffer.cpp
diff --git a/sdm845/gpu_tonemapper/EGLImageBuffer.h b/msm8909w_3100/gpu_tonemapper/EGLImageBuffer.h
similarity index 100%
copy from sdm845/gpu_tonemapper/EGLImageBuffer.h
copy to msm8909w_3100/gpu_tonemapper/EGLImageBuffer.h
diff --git a/sdm845/gpu_tonemapper/EGLImageWrapper.cpp b/msm8909w_3100/gpu_tonemapper/EGLImageWrapper.cpp
similarity index 100%
copy from sdm845/gpu_tonemapper/EGLImageWrapper.cpp
copy to msm8909w_3100/gpu_tonemapper/EGLImageWrapper.cpp
diff --git a/sdm845/gpu_tonemapper/EGLImageWrapper.h b/msm8909w_3100/gpu_tonemapper/EGLImageWrapper.h
similarity index 100%
copy from sdm845/gpu_tonemapper/EGLImageWrapper.h
copy to msm8909w_3100/gpu_tonemapper/EGLImageWrapper.h
diff --git a/sdm845/gpu_tonemapper/TonemapFactory.cpp b/msm8909w_3100/gpu_tonemapper/TonemapFactory.cpp
similarity index 100%
rename from sdm845/gpu_tonemapper/TonemapFactory.cpp
rename to msm8909w_3100/gpu_tonemapper/TonemapFactory.cpp
diff --git a/sdm845/gpu_tonemapper/TonemapFactory.h b/msm8909w_3100/gpu_tonemapper/TonemapFactory.h
similarity index 100%
copy from sdm845/gpu_tonemapper/TonemapFactory.h
copy to msm8909w_3100/gpu_tonemapper/TonemapFactory.h
diff --git a/sdm845/gpu_tonemapper/Tonemapper.cpp b/msm8909w_3100/gpu_tonemapper/Tonemapper.cpp
similarity index 91%
copy from sdm845/gpu_tonemapper/Tonemapper.cpp
copy to msm8909w_3100/gpu_tonemapper/Tonemapper.cpp
index 981863d..811e091 100644
--- a/sdm845/gpu_tonemapper/Tonemapper.cpp
+++ b/msm8909w_3100/gpu_tonemapper/Tonemapper.cpp
@@ -45,7 +45,6 @@
Tonemapper::~Tonemapper()
//-----------------------------------------------------------------------------
{
- void* caller_context = engine_backup();
engine_bind(engineContext);
engine_deleteInputBuffer(tonemapTexture);
engine_deleteInputBuffer(lutXformTexture);
@@ -58,9 +57,6 @@
}
engine_shutdown(engineContext);
- // restore the caller context
- engine_bind(caller_context);
- engine_free_backup(caller_context);
}
//-----------------------------------------------------------------------------
@@ -78,7 +74,6 @@
tonemapper->engineContext = engine_initialize(isSecure);
- void* caller_context = engine_backup();
engine_bind(tonemapper->engineContext);
// load the 3d lut
@@ -117,10 +112,6 @@
tonemapper->programID =
engine_loadProgram(1, &fullscreen_vertex_shader, fragmentShaderCount, fragmentShaders);
- // restore the caller context
- engine_bind(caller_context);
- engine_free_backup(caller_context);
-
return tonemapper;
}
@@ -128,7 +119,6 @@
int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd)
//-----------------------------------------------------------------------------
{
- void* caller_context = engine_backup();
// make current
engine_bind(engineContext);
@@ -159,10 +149,5 @@
// perform
int fenceFD = engine_blit(srcFenceFd);
- // restore the caller context
- engine_bind(caller_context);
- engine_free_backup(caller_context);
-
-
return fenceFD;
}
diff --git a/sdm845/gpu_tonemapper/Tonemapper.h b/msm8909w_3100/gpu_tonemapper/Tonemapper.h
similarity index 100%
copy from sdm845/gpu_tonemapper/Tonemapper.h
copy to msm8909w_3100/gpu_tonemapper/Tonemapper.h
diff --git a/sdm845/gpu_tonemapper/engine.h b/msm8909w_3100/gpu_tonemapper/engine.h
similarity index 96%
copy from sdm845/gpu_tonemapper/engine.h
copy to msm8909w_3100/gpu_tonemapper/engine.h
index e0bf2aa..8fb9452 100644
--- a/sdm845/gpu_tonemapper/engine.h
+++ b/msm8909w_3100/gpu_tonemapper/engine.h
@@ -22,8 +22,6 @@
void* engine_initialize(bool isSecure);
void engine_bind(void*);
-void* engine_backup();
-void engine_free_backup(void*);
void engine_shutdown(void*);
unsigned int engine_loadProgram(int, const char **, int, const char **);
diff --git a/sdm845/gpu_tonemapper/forward_tonemap.inl b/msm8909w_3100/gpu_tonemapper/forward_tonemap.inl
similarity index 100%
copy from sdm845/gpu_tonemapper/forward_tonemap.inl
copy to msm8909w_3100/gpu_tonemapper/forward_tonemap.inl
diff --git a/sdm845/gpu_tonemapper/fullscreen_vertex_shader.inl b/msm8909w_3100/gpu_tonemapper/fullscreen_vertex_shader.inl
similarity index 100%
copy from sdm845/gpu_tonemapper/fullscreen_vertex_shader.inl
copy to msm8909w_3100/gpu_tonemapper/fullscreen_vertex_shader.inl
diff --git a/sdm845/gpu_tonemapper/glengine.cpp b/msm8909w_3100/gpu_tonemapper/glengine.cpp
similarity index 95%
rename from sdm845/gpu_tonemapper/glengine.cpp
rename to msm8909w_3100/gpu_tonemapper/glengine.cpp
index 6cfe15f..6c94c23 100644
--- a/sdm845/gpu_tonemapper/glengine.cpp
+++ b/msm8909w_3100/gpu_tonemapper/glengine.cpp
@@ -47,27 +47,6 @@
}
//-----------------------------------------------------------------------------
-// store the current context(caller)
-void* engine_backup()
-{
- EngineContext* callerContext = new EngineContext();
- // store the previous display/context
- callerContext->eglDisplay = eglGetCurrentDisplay();
- callerContext->eglContext = eglGetCurrentContext();
- callerContext->eglSurface = eglGetCurrentSurface(EGL_DRAW);
-
- return (void*)callerContext;
-}
-//-----------------------------------------------------------------------------
-// frees the backed up caller context
-void engine_free_backup(void* context)
-{
- EngineContext* callerContext = (EngineContext*)(context);
-
- delete callerContext;
-}
-
-//-----------------------------------------------------------------------------
// initialize GL
//
void* engine_initialize(bool isSecure)
diff --git a/sdm845/gpu_tonemapper/glengine.h b/msm8909w_3100/gpu_tonemapper/glengine.h
similarity index 100%
copy from sdm845/gpu_tonemapper/glengine.h
copy to msm8909w_3100/gpu_tonemapper/glengine.h
diff --git a/sdm845/gpu_tonemapper/rgba_inverse_tonemap.inl b/msm8909w_3100/gpu_tonemapper/rgba_inverse_tonemap.inl
similarity index 100%
copy from sdm845/gpu_tonemapper/rgba_inverse_tonemap.inl
copy to msm8909w_3100/gpu_tonemapper/rgba_inverse_tonemap.inl
diff --git a/sdm845/hdmi_cec/Android.mk b/msm8909w_3100/hdmi_cec/Android.mk
similarity index 76%
copy from sdm845/hdmi_cec/Android.mk
copy to msm8909w_3100/hdmi_cec/Android.mk
index a333654..4fed1f0 100644
--- a/sdm845/hdmi_cec/Android.mk
+++ b/msm8909w_3100/hdmi_cec/Android.mk
@@ -8,11 +8,11 @@
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes)
LOCAL_HEADER_LIBRARIES := display_headers
-LOCAL_SHARED_LIBRARIES := $(common_libs) libqservice libbinder libqdutils
+LOCAL_SHARED_LIBRARIES := $(common_libs)
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhdmi_cec\" -Wno-sign-conversion
LOCAL_CLANG := true
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := qhdmi_cec.cpp \
- QHDMIClient.cpp
+LOCAL_SRC_FILES := qhdmi_cec.cpp
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/sdm845/hdmi_cec/qhdmi_cec.cpp b/msm8909w_3100/hdmi_cec/qhdmi_cec.cpp
similarity index 66%
rename from sdm845/hdmi_cec/qhdmi_cec.cpp
rename to msm8909w_3100/hdmi_cec/qhdmi_cec.cpp
index 0923d92..37c7cd8 100644
--- a/sdm845/hdmi_cec/qhdmi_cec.cpp
+++ b/msm8909w_3100/hdmi_cec/qhdmi_cec.cpp
@@ -29,14 +29,14 @@
#define DEBUG 0
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
-#include <cstdlib>
#include <cutils/log.h>
#include <errno.h>
-#include <fcntl.h>
#include <hardware/hdmi_cec.h>
#include <utils/Trace.h>
+#include <utils/debug.h>
+#include <utils/sys.h>
+#include <vector>
#include "qhdmi_cec.h"
-#include "QHDMIClient.h"
namespace qhdmicec {
@@ -45,6 +45,10 @@
const int MAX_CEC_FRAME_SIZE = 20;
const int MAX_SEND_MESSAGE_RETRIES = 1;
+const char* SYSFS_BASE = "/sys/devices/virtual/graphics/fb";
+const char* UEVENT_SWITCH_HDMI = "change@/devices/virtual/switch/hdmi";
+const char* FB_PATH = "/sys/devices/virtual/graphics/fb";
+
enum {
LOGICAL_ADDRESS_SET = 1,
LOGICAL_ADDRESS_UNSET = -1,
@@ -66,6 +70,17 @@
static void cec_close_context(cec_context_t* ctx __unused);
static int cec_enable(cec_context_t *ctx, int enable);
static int cec_is_connected(const struct hdmi_cec_device* dev, int port_id);
+static void cec_monitor_deinit(cec_context_t* ctx);
+static void handle_cec_msg_event(cec_context_t* ctx, uint32_t node_event);
+
+void event_monitor(cec_context_t* ctx); // hdmi event monitor function
+static int get_event_value(const char *uevent_data, int length, const char *event_info);
+static int uevent_init(int *uevent_fd);
+static void handle_hdmihotplug_event(cec_context_t* ctx, uint32_t node_event);
+
+static int populate_event_data(cec_context_t* ctx, std::vector<eventData> *event_data_list);
+static int set_event_params(cec_context_t* ctx, uint32_t node_event, eventData *event_data);
+static void handle_exit_event(cec_context_t* ctx, uint32_t node_event);
static ssize_t read_node(const char *path, char *data)
{
@@ -108,12 +123,12 @@
const char *path_postfix,
const int value)
{
- char sysfs_full_path[MAX_PATH_LENGTH];
+ std::string sysfs_full_path;
char sysfs_data[MAX_SYSFS_DATA];
snprintf(sysfs_data, sizeof(sysfs_data), "%d",value);
- snprintf(sysfs_full_path,sizeof(sysfs_full_path), "%s/%s",
- ctx->fb_sysfs_path, path_postfix);
- ssize_t err = write_node(sysfs_full_path, sysfs_data, strlen(sysfs_data));
+ sysfs_full_path = ctx->fb_sysfs_path + "/";
+ sysfs_full_path.append(path_postfix);
+ ssize_t err = write_node(sysfs_full_path.c_str(), sysfs_data, strlen(sysfs_data));
return err;
}
@@ -135,21 +150,18 @@
//XXX: Do this from a common utility library across the display HALs
const int MAX_FB_DEVICES = 2;
ssize_t len = 0;
- char fb_type_path[MAX_PATH_LENGTH];
+ std::string fb_type_path;
char fb_type[MAX_SYSFS_DATA];
const char *dtv_panel_str = "dtv panel";
for(int num = 0; num < MAX_FB_DEVICES; num++) {
- snprintf(fb_type_path, sizeof(fb_type_path),"%s%d/msm_fb_type",
- SYSFS_BASE,num);
- ALOGD_IF(DEBUG, "%s: num: %d fb_type_path: %s", __FUNCTION__, num, fb_type_path);
- len = read_node(fb_type_path, fb_type);
+ fb_type_path = SYSFS_BASE + std::to_string(ctx->fb_num) + "/msm_fb_type";
+ len = read_node(fb_type_path.c_str(), fb_type);
ALOGD_IF(DEBUG, "%s: fb_type:%s", __FUNCTION__, fb_type);
if(len > 0 && (strncmp(fb_type, dtv_panel_str, strlen(dtv_panel_str)) == 0)){
ALOGD_IF(DEBUG, "%s: Found DTV panel at fb%d", __FUNCTION__, num);
ctx->fb_num = num;
- snprintf(ctx->fb_sysfs_path, sizeof(ctx->fb_sysfs_path),
- "%s%d", SYSFS_BASE, num);
+ ctx->fb_sysfs_path = SYSFS_BASE + std::to_string(ctx->fb_num);
break;
}
}
@@ -190,11 +202,11 @@
uint16_t* addr)
{
cec_context_t* ctx = (cec_context_t*)(dev);
- char pa_path[MAX_PATH_LENGTH];
+ std::string pa_path;
char pa_data[MAX_SYSFS_DATA];
- snprintf (pa_path, sizeof(pa_path),"%s/pa",
- ctx->fb_sysfs_path);
- int err = (int) read_node(pa_path, pa_data);
+ pa_path = ctx->fb_sysfs_path;
+ pa_path.append("/pa");
+ int err = (int) read_node(pa_path.c_str(), pa_data);
*addr = (uint16_t) atoi(pa_data);
ALOGD_IF(DEBUG, "%s: Physical Address: 0x%x", __FUNCTION__, *addr);
if (err < 0)
@@ -222,7 +234,7 @@
ALOGD_IF(DEBUG, "%s: message from framework: %s", __FUNCTION__, dump);
}
- char write_msg_path[MAX_PATH_LENGTH];
+ std::string write_msg_path;
char write_msg[MAX_CEC_FRAME_SIZE];
memset(write_msg, 0, sizeof(write_msg));
// See definition of struct hdmi_cec_msg in driver code
@@ -240,14 +252,13 @@
//msg length + initiator + destination
write_msg[CEC_OFFSET_FRAME_LENGTH] = (unsigned char) (msg->length + 1);
hex_to_string(write_msg, sizeof(write_msg), dump);
- ALOGD_IF(DEBUG, "%s: message to driver: %s", __FUNCTION__, dump);
- snprintf(write_msg_path, sizeof(write_msg_path), "%s/cec/wr_msg",
- ctx->fb_sysfs_path);
+ write_msg_path = ctx->fb_sysfs_path;
+ write_msg_path.append("/cec/wr_msg");
int retry_count = 0;
ssize_t err = 0;
//HAL spec requires us to retry at least once.
while (true) {
- err = write_node(write_msg_path, write_msg, sizeof(write_msg));
+ err = write_node(write_msg_path.c_str(), write_msg, sizeof(write_msg));
retry_count++;
if (err == -EAGAIN && retry_count <= MAX_SEND_MESSAGE_RETRIES) {
ALOGE("%s: CEC line busy, retrying", __FUNCTION__);
@@ -383,11 +394,11 @@
// Ignore port_id since we have only one port
int connected = 0;
cec_context_t* ctx = (cec_context_t*)(dev);
- char connected_path[MAX_PATH_LENGTH];
+ std::string connected_path;
char connected_data[MAX_SYSFS_DATA];
- snprintf (connected_path, sizeof(connected_path),"%s/connected",
- ctx->fb_sysfs_path);
- ssize_t err = read_node(connected_path, connected_data);
+ connected_path = ctx->fb_sysfs_path;
+ connected_path.append("/connected");
+ ssize_t err = read_node(connected_path.c_str(), connected_data);
connected = atoi(connected_data);
ALOGD_IF(DEBUG, "%s: HDMI at port %d is - %s", __FUNCTION__, port_id,
@@ -429,6 +440,7 @@
static void cec_init_context(cec_context_t *ctx)
{
ALOGD_IF(DEBUG, "%s: Initializing context", __FUNCTION__);
+ int err = -EINVAL;
cec_get_fb_node_number(ctx);
//Initialize ports - We support only one output port
@@ -445,20 +457,42 @@
ctx->vendor_id = 0xA47733;
cec_clear_logical_address((hdmi_cec_device_t*)ctx);
- //Set up listener for HDMI events
- ctx->disp_client = new qClient::QHDMIClient();
- ctx->disp_client->setCECContext(ctx);
- ctx->disp_client->registerClient(ctx->disp_client);
-
//Enable CEC - framework expects it to be enabled by default
cec_enable(ctx, true);
ALOGD("%s: CEC enabled", __FUNCTION__);
+
+ ctx->node_list.push_back("cec_msg_event");
+ ctx->node_list.push_back("hotplug_event");
+ ctx->node_list.push_back("exit_event");
+
+ err = populate_event_data(ctx, &ctx->event_data_list);
+ if (err < 0) {
+ ALOGE("Failed to populate poll parameters for monitoring HDMI CEC events. Exiting.");
+ cec_enable(ctx, false);
+ return;
+ }
+
+ ctx->hdmi_cec_monitor = std::thread(event_monitor, ctx);
+
}
static void cec_close_context(cec_context_t* ctx __unused)
{
ALOGD("%s: Closing context", __FUNCTION__);
+
+ uint64_t exit_value = 1;
+ long int write_size = write(ctx->exit_fd, &exit_value, sizeof(uint64_t));
+
+ if (write_size != sizeof(uint64_t)) {
+ ALOGE("Error triggering exit_fd (%d). write size = %ld, error = %s",
+ ctx->exit_fd, write_size, strerror(errno));
+ return;
+ }
+
+ if (ctx->hdmi_cec_monitor.joinable()) {
+ ctx->hdmi_cec_monitor.join();
+ }
}
static int cec_device_open(const struct hw_module_t* module,
@@ -472,7 +506,6 @@
dev = (cec_context_t *) calloc (1, sizeof(*dev));
if (dev) {
cec_init_context(dev);
-
//Setup CEC methods
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = HDMI_CEC_DEVICE_API_VERSION_1_0;
@@ -498,6 +531,176 @@
}
return status;
}
+
+void event_monitor(cec_context_t* ctx) {
+ ALOGD("%s IN", __FUNCTION__);
+ int err = -EINVAL;
+
+ prctl(PR_SET_NAME, "cec_monitor", 0, 0, 0);
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+ while (!ctx->cec_exit_thread) {
+ err = poll(ctx->poll_fds.data(), (nfds_t)ctx->event_data_list.size(), -1);
+ if ( err <= 0 ) {
+ ALOGI("Failed to poll, Error %s", strerror(errno));
+ continue;
+ }
+
+ for (uint32_t event = 0; event < ctx->event_data_list.size(); event++) {
+ pollfd &poll_fd = ctx->poll_fds[event];
+
+ if (poll_fd.revents & POLLIN || poll_fd.revents & POLLPRI) {
+ ctx->event_data_list[event].event_parser(ctx, event);
+ }
+ }
+ }
+
+ cec_monitor_deinit(ctx);
+ ALOGD("%s OUT", __FUNCTION__);
+ return;
+}
+
+static int populate_event_data(cec_context_t* ctx, std::vector<eventData> *event_data_list) {
+ int err = -EINVAL;
+ ctx->poll_fds.resize(ctx->node_list.size());
+
+ for (uint32_t event = 0; event < ctx->node_list.size(); event++) {
+ const char *event_name = ctx->node_list.at(event).c_str();
+ eventData event_data;
+ event_data.event_name = event_name;
+ err = set_event_params(ctx, event, &event_data);
+ if (err < 0) {
+ ALOGE("Failed to set poll event parameters");
+ return err;
+ }
+
+ event_data_list->push_back(event_data);
+ }
+
+ return 0;
+}
+
+static int set_event_params(cec_context_t* ctx, uint32_t node_event, eventData *event_data) {
+ pollfd poll_fd;
+ poll_fd.fd = -EINVAL;
+
+ if (!strncmp(event_data->event_name, "cec_msg_event", strlen("cec_msg_event"))) {
+ char node_path[MAX_STRING_LENGTH] = {0};
+
+ snprintf(node_path, sizeof(node_path), "%s%d/%s", FB_PATH, ctx->fb_num, "cec/rd_msg");
+ poll_fd.fd = open(node_path, O_RDONLY);
+ if (poll_fd.fd < 0) {
+ ALOGE("Node open failed for display %d event %s error %s",
+ ctx->fb_num, "cec/rd_msg", strerror(errno));
+ return poll_fd.fd;
+ }
+
+ poll_fd.events |= POLLPRI | POLLERR;
+ // Read once on fd to clear the data
+ pread(poll_fd.fd, ctx->data, MAX_STRING_LENGTH, 0);
+ event_data->event_parser = &handle_cec_msg_event;
+ } else if (!strncmp(event_data->event_name, "hotplug_event", strlen("hotplug_event"))) {
+ if (!uevent_init(&poll_fd.fd)) {
+ ALOGE("Failed to register uevent for hotplug detection");
+ return -1;
+ }
+
+ poll_fd.events |= POLLIN | POLLERR;
+ event_data->event_parser = &handle_hdmihotplug_event;
+ } else if (!strncmp(event_data->event_name, "exit_event", strlen("exit_event"))) {
+ poll_fd.fd = eventfd(0, 0);
+ poll_fd.events |= POLLIN;
+ event_data->event_parser = &handle_exit_event;
+ ctx->exit_fd = poll_fd.fd;
+ }
+
+ ctx->poll_fds[node_event] = poll_fd;
+ return 0;
+}
+
+static void handle_cec_msg_event(cec_context_t* ctx, uint32_t node_event) {
+ if ((ctx->poll_fds[node_event].revents & POLLPRI) &&
+ (pread(ctx->poll_fds[node_event].fd, ctx->data, MAX_STRING_LENGTH, 0) > 0)) {
+ ALOGD_IF(DEBUG, "Handling CEC message %s", __FUNCTION__);
+ cec_receive_message(ctx, ctx->data, 0);
+ }
+
+ return;
+}
+
+static void handle_hdmihotplug_event(cec_context_t* ctx, uint32_t node_event) {
+ char uevent_data[PAGE_SIZE];
+ int count = 0;
+
+ if (ctx->poll_fds[node_event].revents & POLLIN) {
+ count = static_cast<int> (recv(ctx->poll_fds[node_event].fd, uevent_data,
+ (INT32(sizeof(uevent_data))) - 2, 0));
+
+ if ((count > 0) && (strcasestr(UEVENT_SWITCH_HDMI, uevent_data))) {
+ int connected = get_event_value(uevent_data, count, "SWITCH_STATE=");
+ ALOGD("HDMI CEC is %s", connected ? "connected" : "disconnected");
+ cec_hdmi_hotplug(ctx, connected);
+ }
+ }
+
+ return;
+}
+
+static void handle_exit_event(cec_context_t* ctx, uint32_t node_event) {
+ ALOGD_IF(DEBUG, "Enter %s", __FUNCTION__);
+
+ if (ctx->poll_fds[node_event].revents & POLLIN) {
+ ctx->cec_exit_thread = true;
+ }
+
+ return;
+}
+
+static void cec_monitor_deinit(cec_context_t* ctx) {
+ for (uint32_t event = 0; event < ctx->poll_fds.size(); event++) {
+ close(ctx->poll_fds[event].fd);
+ ctx->poll_fds[event].fd = -1;
+ }
+}
+
+static int get_event_value(const char *uevent_data, int length, const char *event_info) {
+ const char *iterator_str = uevent_data;
+ while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
+ const char *pstr = strstr(iterator_str, event_info);
+ if (pstr != NULL) {
+ return (atoi(iterator_str + strlen(event_info)));
+ }
+ iterator_str += strlen(iterator_str) + 1;
+ }
+ return -1;
+}
+
+/* Returns 0 on failure, 1 on success */
+static int uevent_init(int *uevent_fd) {
+ struct sockaddr_nl addr;
+ int sz = 64*1024;
+ int s;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.nl_family = AF_NETLINK;
+ addr.nl_pid = getpid();
+ addr.nl_groups = 0xffffffff;
+
+ s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+ if (s < 0)
+ return 0;
+
+ setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz));
+
+ if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ close(s);
+ return 0;
+ }
+
+ *uevent_fd = s;
+ return (*uevent_fd > 0);
+}
+
}; //namespace qhdmicec
// Standard HAL module, should be outside qhdmicec namespace
@@ -516,5 +719,3 @@
.methods = &cec_module_methods,
}
};
-
-
diff --git a/sdm845/hdmi_cec/qhdmi_cec.h b/msm8909w_3100/hdmi_cec/qhdmi_cec.h
similarity index 74%
copy from sdm845/hdmi_cec/qhdmi_cec.h
copy to msm8909w_3100/hdmi_cec/qhdmi_cec.h
index aa97620..e2c9755 100644
--- a/sdm845/hdmi_cec/qhdmi_cec.h
+++ b/msm8909w_3100/hdmi_cec/qhdmi_cec.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,16 +30,17 @@
#define QHDMI_CEC_H
#include <hardware/hdmi_cec.h>
-#include <utils/RefBase.h>
-
-namespace qClient {
- class QHDMIClient;
-};
+#include <sys/poll.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/resource.h>
+#include <linux/netlink.h>
+#include <thread>
+#include <vector>
namespace qhdmicec {
-#define SYSFS_BASE "/sys/class/graphics/fb"
-#define MAX_PATH_LENGTH 128
+static const int MAX_STRING_LENGTH = 1024;
struct cec_callback_t {
// Function in HDMI service to call back on CEC messages
@@ -49,6 +50,8 @@
};
+struct eventData;
+
struct cec_context_t {
hdmi_cec_device_t device; // Device for HW module
cec_callback_t callback; // Struct storing callback object
@@ -56,7 +59,7 @@
bool arc_enabled;
bool system_control; // If true, HAL/driver handle CEC messages
int fb_num; // Framebuffer node for HDMI
- char fb_sysfs_path[MAX_PATH_LENGTH];
+ std::string fb_sysfs_path;
hdmi_port_info *port_info; // HDMI port info
// Logical address is stored in an array, the index of the array is the
@@ -64,7 +67,21 @@
int logical_address[CEC_ADDR_BROADCAST];
int version;
uint32_t vendor_id;
- android::sp<qClient::QHDMIClient> disp_client;
+
+ std::vector<pollfd> poll_fds; // poll fds for cec message monitor and exit signal
+ // on cec message monitor thread
+ int exit_fd = -1;
+ bool cec_exit_thread = false;
+ std::thread hdmi_cec_monitor; // hdmi plugin monitor thread variable
+ char data[MAX_STRING_LENGTH] = {0};
+
+ std::vector<std::string> node_list = {};
+ std::vector<eventData> event_data_list = {};
+};
+
+struct eventData {
+ const char* event_name = NULL;
+ void (*event_parser)(cec_context_t* ctx, uint32_t node_event) = NULL;
};
void cec_receive_message(cec_context_t *ctx, char *msg, ssize_t len);
diff --git a/sdm845/include/Android.mk b/msm8909w_3100/include/Android.mk
similarity index 100%
rename from sdm845/include/Android.mk
rename to msm8909w_3100/include/Android.mk
diff --git a/sdm845/include/color_metadata.h b/msm8909w_3100/include/color_metadata.h
similarity index 100%
copy from sdm845/include/color_metadata.h
copy to msm8909w_3100/include/color_metadata.h
diff --git a/sdm845/libcopybit/Android.mk b/msm8909w_3100/libcopybit/Android.mk
similarity index 100%
rename from sdm845/libcopybit/Android.mk
rename to msm8909w_3100/libcopybit/Android.mk
diff --git a/sdm845/libcopybit/MODULE_LICENSE_APACHE2 b/msm8909w_3100/libcopybit/MODULE_LICENSE_APACHE2
similarity index 100%
rename from sdm845/libcopybit/MODULE_LICENSE_APACHE2
rename to msm8909w_3100/libcopybit/MODULE_LICENSE_APACHE2
diff --git a/sdm845/libcopybit/NOTICE b/msm8909w_3100/libcopybit/NOTICE
similarity index 100%
rename from sdm845/libcopybit/NOTICE
rename to msm8909w_3100/libcopybit/NOTICE
diff --git a/sdm845/libcopybit/c2d2.h b/msm8909w_3100/libcopybit/c2d2.h
similarity index 100%
rename from sdm845/libcopybit/c2d2.h
rename to msm8909w_3100/libcopybit/c2d2.h
diff --git a/sdm845/libcopybit/copybit.cpp b/msm8909w_3100/libcopybit/copybit.cpp
similarity index 100%
rename from sdm845/libcopybit/copybit.cpp
rename to msm8909w_3100/libcopybit/copybit.cpp
diff --git a/sdm845/libcopybit/copybit.h b/msm8909w_3100/libcopybit/copybit.h
similarity index 100%
rename from sdm845/libcopybit/copybit.h
rename to msm8909w_3100/libcopybit/copybit.h
diff --git a/sdm845/libcopybit/copybit_c2d.cpp b/msm8909w_3100/libcopybit/copybit_c2d.cpp
similarity index 100%
rename from sdm845/libcopybit/copybit_c2d.cpp
rename to msm8909w_3100/libcopybit/copybit_c2d.cpp
diff --git a/sdm845/libcopybit/copybit_priv.h b/msm8909w_3100/libcopybit/copybit_priv.h
similarity index 100%
rename from sdm845/libcopybit/copybit_priv.h
rename to msm8909w_3100/libcopybit/copybit_priv.h
diff --git a/sdm845/libcopybit/software_converter.cpp b/msm8909w_3100/libcopybit/software_converter.cpp
similarity index 100%
rename from sdm845/libcopybit/software_converter.cpp
rename to msm8909w_3100/libcopybit/software_converter.cpp
diff --git a/sdm845/libcopybit/software_converter.h b/msm8909w_3100/libcopybit/software_converter.h
similarity index 100%
rename from sdm845/libcopybit/software_converter.h
rename to msm8909w_3100/libcopybit/software_converter.h
diff --git a/msm8909w_3100/libdisplayconfig/Android.mk b/msm8909w_3100/libdisplayconfig/Android.mk
new file mode 100644
index 0000000..f6f1d3e
--- /dev/null
+++ b/msm8909w_3100/libdisplayconfig/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libdisplayconfig
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_HEADER_LIBRARIES := display_headers
+LOCAL_COPY_HEADERS := DisplayConfig.h
+LOCAL_SRC_FILES := DisplayConfig.cpp
+LOCAL_SHARED_LIBRARIES := libhidlbase libhidltransport libutils \
+ vendor.display.config@1.0
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/msm8909w_3100/libdisplayconfig/DisplayConfig.cpp b/msm8909w_3100/libdisplayconfig/DisplayConfig.cpp
new file mode 100644
index 0000000..29fcc94
--- /dev/null
+++ b/msm8909w_3100/libdisplayconfig/DisplayConfig.cpp
@@ -0,0 +1,363 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <vendor/display/config/1.0/IDisplayConfig.h>
+
+#include "DisplayConfig.h"
+
+namespace display {
+
+using vendor::display::config::V1_0::IDisplayConfig;
+
+//=============================================================================
+// The functions below run in the client process and wherever necessary
+// do a binder call to HWC to get/set data.
+
+IDisplayConfig::DisplayType MapDisplayType(int dpy) {
+ switch (dpy) {
+ case DISPLAY_PRIMARY:
+ return IDisplayConfig::DisplayType::DISPLAY_PRIMARY;
+
+ case DISPLAY_EXTERNAL:
+ return IDisplayConfig::DisplayType::DISPLAY_EXTERNAL;
+
+ case DISPLAY_VIRTUAL:
+ return IDisplayConfig::DisplayType::DISPLAY_VIRTUAL;
+
+ default:
+ break;
+ }
+
+ return IDisplayConfig::DisplayType::INVALID;
+}
+
+IDisplayConfig::DisplayExternalStatus MapExternalStatus(uint32_t status) {
+ switch (status) {
+ case EXTERNAL_OFFLINE:
+ return IDisplayConfig::DisplayExternalStatus::EXTERNAL_OFFLINE;
+
+ case EXTERNAL_ONLINE:
+ return IDisplayConfig::DisplayExternalStatus::EXTERNAL_ONLINE;
+
+ case EXTERNAL_PAUSE:
+ return IDisplayConfig::DisplayExternalStatus::EXTERNAL_PAUSE;
+
+ case EXTERNAL_RESUME:
+ return IDisplayConfig::DisplayExternalStatus::EXTERNAL_RESUME;
+
+ default:
+ break;
+ }
+
+ return IDisplayConfig::DisplayExternalStatus::INVALID;
+}
+
+IDisplayConfig::DisplayDynRefreshRateOp MapDynRefreshRateOp(uint32_t op) {
+ switch (op) {
+ case DISABLE_METADATA_DYN_REFRESH_RATE:
+ return IDisplayConfig::DisplayDynRefreshRateOp::DISABLE_METADATA_DYN_REFRESH_RATE;
+
+ case ENABLE_METADATA_DYN_REFRESH_RATE:
+ return IDisplayConfig::DisplayDynRefreshRateOp::ENABLE_METADATA_DYN_REFRESH_RATE;
+
+ case SET_BINDER_DYN_REFRESH_RATE:
+ return IDisplayConfig::DisplayDynRefreshRateOp::SET_BINDER_DYN_REFRESH_RATE;
+
+ default:
+ break;
+ }
+
+ return IDisplayConfig::DisplayDynRefreshRateOp::INVALID;
+}
+
+int MapDisplayPortType(IDisplayConfig::DisplayPortType panelType) {
+ switch (panelType) {
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DEFAULT:
+ return DISPLAY_PORT_DEFAULT;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DSI:
+ return DISPLAY_PORT_DSI;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DTV:
+ return DISPLAY_PORT_DTV;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_WRITEBACK:
+ return DISPLAY_PORT_WRITEBACK;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_LVDS:
+ return DISPLAY_PORT_LVDS;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_EDP:
+ return DISPLAY_PORT_EDP;
+
+ case IDisplayConfig::DisplayPortType::DISPLAY_PORT_DP:
+ return DISPLAY_PORT_DP;
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+int isExternalConnected() {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return 0;
+ }
+
+ int connected = 0;
+ intf->isDisplayConnected(IDisplayConfig::DisplayType::DISPLAY_EXTERNAL,
+ [&](const auto &tmpError, const auto &tmpStatus) {
+ if (tmpError) {
+ return;
+ }
+
+ connected = tmpStatus;
+ });
+
+ return connected;
+}
+
+int setSecondayDisplayStatus(int dpy, uint32_t status) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setSecondayDisplayStatus(MapDisplayType(dpy), MapExternalStatus(status));
+}
+
+int configureDynRefeshRate(uint32_t op, uint32_t refreshRate) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->configureDynRefeshRate(MapDynRefreshRateOp(op), refreshRate);
+}
+
+int getConfigCount(int dpy) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ int count = 0;
+ intf->getConfigCount(MapDisplayType(dpy),
+ [&](const auto &tmpError, const auto &tmpCount) {
+ if (tmpError) {
+ return;
+ }
+
+ count = tmpCount;
+ });
+
+ return count;
+}
+
+int getActiveConfig(int dpy) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ int config = 0;
+ intf->getActiveConfig(MapDisplayType(dpy),
+ [&](const auto &tmpError, const auto &tmpConfig) {
+ if (tmpError) {
+ return;
+ }
+
+ config = tmpConfig;
+ });
+
+ return config;
+}
+
+int setActiveConfig(int dpy, uint32_t config) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setActiveConfig(MapDisplayType(dpy), config);
+}
+
+DisplayAttributes getDisplayAttributes(uint32_t configIndex, int dpy) {
+ DisplayAttributes attributes;
+
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return attributes;
+ }
+
+ intf->getDisplayAttributes(configIndex, MapDisplayType(dpy),
+ [&](const auto &tmpError, const auto &tmpAttributes) {
+ if (tmpError) {
+ return;
+ }
+
+ attributes.vsync_period = tmpAttributes.vsyncPeriod;
+ attributes.xres = tmpAttributes.xRes;
+ attributes.yres = tmpAttributes.yRes;
+ attributes.xdpi = tmpAttributes.xDpi;
+ attributes.ydpi = tmpAttributes.yDpi;
+ attributes.panel_type = MapDisplayPortType(tmpAttributes.panelType);
+ attributes.is_yuv = tmpAttributes.isYuv;
+ });
+
+ return attributes;
+}
+
+int setPanelBrightness(uint32_t level) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setPanelBrightness(level);
+}
+
+uint32_t getPanelBrightness() {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return 0;
+ }
+
+ int level = 0;
+ intf->getPanelBrightness(
+ [&](const auto &tmpError, const auto &tmpLevel) {
+ if (tmpError) {
+ return;
+ }
+
+ level = tmpLevel;
+ });
+
+ return level;
+}
+
+int minHdcpEncryptionLevelChanged(int dpy, uint32_t min_enc_level) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->minHdcpEncryptionLevelChanged(MapDisplayType(dpy), min_enc_level);
+}
+
+int refreshScreen() {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->refreshScreen();
+}
+
+int controlPartialUpdate(int dpy, bool enable) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->controlPartialUpdate(MapDisplayType(dpy), enable);
+}
+
+int toggleScreenUpdate(uint32_t on) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->toggleScreenUpdate(on == 1);
+}
+
+int setIdleTimeout(uint32_t value) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setIdleTimeout(value);
+}
+
+int getHDRCapabilities(int dpy, DisplayHDRCapabilities *caps) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL || caps == NULL) {
+ return -1;
+ }
+
+ int error = -1;
+ intf->getHDRCapabilities(MapDisplayType(dpy),
+ [&](const auto &tmpError, const auto &tmpCaps) {
+ error = tmpError;
+ if (error) {
+ return;
+ }
+
+ caps->supported_hdr_types = tmpCaps.supportedHdrTypes;
+ caps->max_luminance = tmpCaps.maxLuminance;
+ caps->max_avg_luminance = tmpCaps.maxAvgLuminance;
+ caps->min_luminance = tmpCaps.minLuminance;
+ });
+
+ return error;
+}
+
+int setCameraLaunchStatus(uint32_t on) {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return -1;
+ }
+
+ return intf->setCameraLaunchStatus(on);
+}
+
+bool displayBWTransactionPending() {
+ android::sp<IDisplayConfig> intf = IDisplayConfig::getService();
+ if (intf == NULL) {
+ return 0;
+ }
+
+ int status = 0;
+ intf->displayBWTransactionPending(
+ [&](const auto &tmpError, const auto &tmpStatus) {
+ if (tmpError) {
+ return;
+ }
+
+ status = tmpStatus;
+ });
+
+ return status;
+}
+
+} // namespace display
diff --git a/msm8909w_3100/libdisplayconfig/DisplayConfig.h b/msm8909w_3100/libdisplayconfig/DisplayConfig.h
new file mode 100644
index 0000000..69a542a
--- /dev/null
+++ b/msm8909w_3100/libdisplayconfig/DisplayConfig.h
@@ -0,0 +1,110 @@
+/*
+ * Copyight (c) 2017 The Linux Foundation. All ights reserved.
+ *
+ * Redistibution and use in souce and binary forms, with or without
+ * modification, ae pemitted provided that the following conditions are
+ * met:
+ * * Redistibutions of souce code must retain the above copyright
+ * notice, this list of conditions and the following disclaime.
+ * * Redistibutions in binay form must reproduce the above
+ * copyight notice, this list of conditions and the following
+ * disclaime in the documentation and/o other materials provided
+ * with the distibution.
+ * * Neither the name of The Linux Foundation. no the names of its
+ * contibutos may be used to endorse or promote products derived
+ * fom this softwae without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DISPLAY_CONFIG_H__
+#define __DISPLAY_CONFIG_H__
+
+#include <stdint.h>
+#include <vector>
+
+// This header is for clients to use to set/get global display configuration.
+
+namespace display {
+
+enum {
+ DISPLAY_PRIMARY = 0,
+ DISPLAY_EXTERNAL,
+ DISPLAY_VIRTUAL,
+};
+
+enum {
+ EXTERNAL_OFFLINE = 0,
+ EXTERNAL_ONLINE,
+ EXTERNAL_PAUSE,
+ EXTERNAL_RESUME,
+};
+
+enum {
+ DISABLE_METADATA_DYN_REFRESH_RATE = 0,
+ ENABLE_METADATA_DYN_REFRESH_RATE,
+ SET_BINDER_DYN_REFRESH_RATE,
+};
+
+enum {
+ DISPLAY_PORT_DEFAULT = 0,
+ DISPLAY_PORT_DSI,
+ DISPLAY_PORT_DTV,
+ DISPLAY_PORT_WRITEBACK,
+ DISPLAY_PORT_LVDS,
+ DISPLAY_PORT_EDP,
+ DISPLAY_PORT_DP,
+};
+
+struct DisplayAttributes {
+ uint32_t vsync_period = 0; //nanoseconds
+ uint32_t xres = 0;
+ uint32_t yres = 0;
+ float xdpi = 0.0f;
+ float ydpi = 0.0f;
+ int panel_type = DISPLAY_PORT_DEFAULT;
+ bool is_yuv = false;
+};
+
+struct DisplayHDRCapabilities {
+ std::vector<int32_t> supported_hdr_types;
+ float max_luminance = 0.0f;
+ float max_avg_luminance = 0.0f;
+ float min_luminance = 0.0f;
+};
+
+//=============================================================================
+// The functions below run in the client pocess and wherever necessary
+// do a binder call to HWC to get/set data.
+
+int isExternalConnected();
+int setSecondayDisplayStatus(int dpy, uint32_t status);
+int configureDynRefeshRate(uint32_t op, uint32_t refreshRate);
+int getConfigCount(int dpy);
+int getActiveConfig(int dpy);
+int setActiveConfig(int dpy, uint32_t config);
+DisplayAttributes getDisplayAttributes(uint32_t configIndex, int dpy);
+int setPanelBrightness(uint32_t level);
+uint32_t getPanelBrightness();
+int minHdcpEncryptionLevelChanged(int dpy, uint32_t min_enc_level);
+int refreshScreen();
+int controlPartialUpdate(int dpy, bool enable);
+int toggleScreenUpdate(uint32_t on);
+int setIdleTimeout(uint32_t value);
+int getHDRCapabilities(int dpy, DisplayHDRCapabilities *caps);
+int setCameraLaunchStatus(uint32_t on);
+bool displayBWTransactionPending();
+
+} // namespace display
+
+#endif // __DISPLAY_CONFIG_H__
diff --git a/msm8909w_3100/libdrmutils/Android.mk b/msm8909w_3100/libdrmutils/Android.mk
new file mode 100644
index 0000000..7c5a4b0
--- /dev/null
+++ b/msm8909w_3100/libdrmutils/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libdrmutils
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := external/libdrm
+LOCAL_SHARED_LIBRARIES := libdrm libdl
+LOCAL_CFLAGS := -DLOG_TAG=\"DRMUTILS\" -Wall -std=c++11 -Werror -fno-operator-names
+LOCAL_CLANG := true
+LOCAL_SRC_FILES := drm_master.cpp drm_res_mgr.cpp drm_lib_loader.cpp
+LOCAL_COPY_HEADERS_TO := qcom/display
+LOCAL_COPY_HEADERS := drm_master.h drm_res_mgr.h drm_lib_loader.h drm_logger.h drm_interface.h
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/sdm845/libdrmutils/drm_interface.h b/msm8909w_3100/libdrmutils/drm_interface.h
similarity index 87%
copy from sdm845/libdrmutils/drm_interface.h
copy to msm8909w_3100/libdrmutils/drm_interface.h
index 71767e7..4c37e8c 100644
--- a/sdm845/libdrmutils/drm_interface.h
+++ b/msm8909w_3100/libdrmutils/drm_interface.h
@@ -39,9 +39,6 @@
#include "xf86drmMode.h"
namespace sde_drm {
-
-typedef std::map<std::pair<uint32_t, uint64_t>, float> CompRatioMap;
-
/*
* Drm Atomic Operation Codes
*/
@@ -144,24 +141,6 @@
*/
CRTC_SET_OUTPUT_FENCE_OFFSET,
/*
- * Op: Sets overall SDE core clock
- * Arg: uint32_t - CRTC ID
- * uint32_t - core_clk
- */
- CRTC_SET_CORE_CLK,
- /*
- * Op: Sets overall SDE core average bandwidth
- * Arg: uint32_t - CRTC ID
- * uint32_t - core_ab
- */
- CRTC_SET_CORE_AB,
- /*
- * Op: Sets overall SDE core instantaneous bandwidth
- * Arg: uint32_t - CRTC ID
- * uint32_t - core_ib
- */
- CRTC_SET_CORE_IB,
- /*
* Op: Returns release fence for this frame. Should be called after Commit() on
* DRMAtomicReqInterface.
* Arg: uint32_t - CRTC ID
@@ -175,13 +154,6 @@
*/
CRTC_SET_POST_PROC,
/*
- * Op: Sets CRTC ROIs.
- * Arg: uint32_t - CRTC ID
- * uint32_t - number of ROIs
- * DRMRect * - Array of CRTC ROIs
- */
- CRTC_SET_ROI,
- /*
* Op: Returns retire fence for this commit. Should be called after Commit() on
* DRMAtomicReqInterface.
* Arg: uint32_t - Connector ID
@@ -200,35 +172,14 @@
* uint32_t - Framebuffer ID
*/
CONNECTOR_SET_OUTPUT_FB_ID,
- /*
- * Op: Sets power mode for connector.
- * Arg: uint32_t - Connector ID
- * uint32_t - Power Mode
- */
- CONNECTOR_SET_POWER_MODE,
- /*
- * Op: Sets panel ROIs.
- * Arg: uint32_t - Connector ID
- * uint32_t - number of ROIs
- * DRMRect * - Array of Connector ROIs
- */
- CONNECTOR_SET_ROI,
};
enum struct DRMRotation {
FLIP_H = 0x1,
FLIP_V = 0x2,
- ROT_180 = FLIP_H | FLIP_V,
ROT_90 = 0x4,
};
-enum struct DRMPowerMode {
- ON,
- DOZE,
- DOZE_SUSPEND,
- OFF,
-};
-
enum struct DRMBlendType {
UNDEFINED = 0,
OPAQUE = 1,
@@ -275,21 +226,6 @@
uint32_t max_blend_stages;
QSEEDVersion qseed_version;
SmartDMARevision smart_dma_rev;
- float ib_fudge_factor;
- float clk_fudge_factor;
- uint32_t dest_scale_prefill_lines;
- uint32_t undersized_prefill_lines;
- uint32_t macrotile_prefill_lines;
- uint32_t nv12_prefill_lines;
- uint32_t linear_prefill_lines;
- uint32_t downscale_prefill_lines;
- uint32_t extra_prefill_lines;
- uint32_t amortized_threshold;
- uint64_t max_bandwidth_low;
- uint64_t max_bandwidth_high;
- uint32_t max_sde_clk;
- CompRatioMap comp_ratio_rt_map;
- CompRatioMap comp_ratio_nrt_map;
};
enum struct DRMPlaneType {
@@ -314,7 +250,6 @@
uint32_t max_downscale;
uint32_t max_horizontal_deci;
uint32_t max_vertical_deci;
- uint64_t max_pipe_bandwidth;
};
// All DRM Planes as map<Plane_id , plane_type_info> listed from highest to lowest priority
@@ -350,16 +285,6 @@
std::vector<std::pair<uint32_t, uint64_t>> formats_supported;
// Valid only if type is DRM_MODE_CONNECTOR_VIRTUAL
uint32_t max_linewidth;
- // Valid only if mode is command
- int num_roi;
- int xstart;
- int ystart;
- int walign;
- int halign;
- int wmin;
- int hmin;
- bool roi_merge;
- DRMRotation panel_orientation;
};
/* Identifier token for a display */
@@ -476,7 +401,7 @@
* Will query post propcessing feature info of a CRTC.
* [output]: DRMPPFeatureInfo: CRTC post processing feature info
*/
- virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo &info) = 0;
+ virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo &info) = 0;
/*
* Register a logical display to receive a token.
* Each display pipeline in DRM is identified by its CRTC and Connector(s).
diff --git a/sdm845/libdrmutils/drm_lib_loader.cpp b/msm8909w_3100/libdrmutils/drm_lib_loader.cpp
similarity index 100%
copy from sdm845/libdrmutils/drm_lib_loader.cpp
copy to msm8909w_3100/libdrmutils/drm_lib_loader.cpp
diff --git a/sdm845/libdrmutils/drm_lib_loader.h b/msm8909w_3100/libdrmutils/drm_lib_loader.h
similarity index 100%
copy from sdm845/libdrmutils/drm_lib_loader.h
copy to msm8909w_3100/libdrmutils/drm_lib_loader.h
diff --git a/sdm845/libdrmutils/drm_logger.h b/msm8909w_3100/libdrmutils/drm_logger.h
similarity index 100%
copy from sdm845/libdrmutils/drm_logger.h
copy to msm8909w_3100/libdrmutils/drm_logger.h
diff --git a/sdm845/libdrmutils/drm_master.cpp b/msm8909w_3100/libdrmutils/drm_master.cpp
similarity index 100%
copy from sdm845/libdrmutils/drm_master.cpp
copy to msm8909w_3100/libdrmutils/drm_master.cpp
diff --git a/sdm845/libdrmutils/drm_master.h b/msm8909w_3100/libdrmutils/drm_master.h
similarity index 100%
copy from sdm845/libdrmutils/drm_master.h
copy to msm8909w_3100/libdrmutils/drm_master.h
diff --git a/sdm845/libdrmutils/drm_res_mgr.cpp b/msm8909w_3100/libdrmutils/drm_res_mgr.cpp
similarity index 100%
copy from sdm845/libdrmutils/drm_res_mgr.cpp
copy to msm8909w_3100/libdrmutils/drm_res_mgr.cpp
diff --git a/sdm845/libdrmutils/drm_res_mgr.h b/msm8909w_3100/libdrmutils/drm_res_mgr.h
similarity index 100%
copy from sdm845/libdrmutils/drm_res_mgr.h
copy to msm8909w_3100/libdrmutils/drm_res_mgr.h
diff --git a/sdm845/libgralloc/Android.mk b/msm8909w_3100/libgralloc/Android.mk
similarity index 100%
rename from sdm845/libgralloc/Android.mk
rename to msm8909w_3100/libgralloc/Android.mk
diff --git a/sdm845/libgralloc/MODULE_LICENSE_APACHE2 b/msm8909w_3100/libgralloc/MODULE_LICENSE_APACHE2
similarity index 100%
rename from sdm845/libgralloc/MODULE_LICENSE_APACHE2
rename to msm8909w_3100/libgralloc/MODULE_LICENSE_APACHE2
diff --git a/sdm845/libgralloc/Makefile.am b/msm8909w_3100/libgralloc/Makefile.am
similarity index 100%
copy from sdm845/libgralloc/Makefile.am
copy to msm8909w_3100/libgralloc/Makefile.am
diff --git a/sdm845/libgralloc/NOTICE b/msm8909w_3100/libgralloc/NOTICE
similarity index 100%
rename from sdm845/libgralloc/NOTICE
rename to msm8909w_3100/libgralloc/NOTICE
diff --git a/sdm845/libgralloc/adreno_utils.h b/msm8909w_3100/libgralloc/adreno_utils.h
similarity index 100%
copy from sdm845/libgralloc/adreno_utils.h
copy to msm8909w_3100/libgralloc/adreno_utils.h
diff --git a/sdm845/libgralloc/alloc_controller.cpp b/msm8909w_3100/libgralloc/alloc_controller.cpp
similarity index 100%
rename from sdm845/libgralloc/alloc_controller.cpp
rename to msm8909w_3100/libgralloc/alloc_controller.cpp
diff --git a/sdm845/libgralloc/alloc_controller.h b/msm8909w_3100/libgralloc/alloc_controller.h
similarity index 100%
rename from sdm845/libgralloc/alloc_controller.h
rename to msm8909w_3100/libgralloc/alloc_controller.h
diff --git a/sdm845/libgralloc/fb_priv.h b/msm8909w_3100/libgralloc/fb_priv.h
similarity index 100%
rename from sdm845/libgralloc/fb_priv.h
rename to msm8909w_3100/libgralloc/fb_priv.h
diff --git a/sdm845/libgralloc/framebuffer.cpp b/msm8909w_3100/libgralloc/framebuffer.cpp
similarity index 100%
rename from sdm845/libgralloc/framebuffer.cpp
rename to msm8909w_3100/libgralloc/framebuffer.cpp
diff --git a/sdm845/libgralloc/gpu.cpp b/msm8909w_3100/libgralloc/gpu.cpp
similarity index 100%
rename from sdm845/libgralloc/gpu.cpp
rename to msm8909w_3100/libgralloc/gpu.cpp
diff --git a/sdm845/libgralloc/gpu.h b/msm8909w_3100/libgralloc/gpu.h
similarity index 100%
rename from sdm845/libgralloc/gpu.h
rename to msm8909w_3100/libgralloc/gpu.h
diff --git a/sdm845/libgralloc/gr.h b/msm8909w_3100/libgralloc/gr.h
similarity index 100%
rename from sdm845/libgralloc/gr.h
rename to msm8909w_3100/libgralloc/gr.h
diff --git a/sdm845/libgralloc/gralloc.cpp b/msm8909w_3100/libgralloc/gralloc.cpp
similarity index 100%
rename from sdm845/libgralloc/gralloc.cpp
rename to msm8909w_3100/libgralloc/gralloc.cpp
diff --git a/sdm845/libgralloc/gralloc_priv.h b/msm8909w_3100/libgralloc/gralloc_priv.h
similarity index 100%
rename from sdm845/libgralloc/gralloc_priv.h
rename to msm8909w_3100/libgralloc/gralloc_priv.h
diff --git a/sdm845/libgralloc/ionalloc.cpp b/msm8909w_3100/libgralloc/ionalloc.cpp
similarity index 100%
rename from sdm845/libgralloc/ionalloc.cpp
rename to msm8909w_3100/libgralloc/ionalloc.cpp
diff --git a/sdm845/libgralloc/ionalloc.h b/msm8909w_3100/libgralloc/ionalloc.h
similarity index 100%
rename from sdm845/libgralloc/ionalloc.h
rename to msm8909w_3100/libgralloc/ionalloc.h
diff --git a/sdm845/libgralloc/mapper.cpp b/msm8909w_3100/libgralloc/mapper.cpp
similarity index 98%
rename from sdm845/libgralloc/mapper.cpp
rename to msm8909w_3100/libgralloc/mapper.cpp
index acf5e2c..e9830e2 100644
--- a/sdm845/libgralloc/mapper.cpp
+++ b/msm8909w_3100/libgralloc/mapper.cpp
@@ -71,7 +71,7 @@
hnd, hnd->fd_metadata, strerror(errno));
return -errno;
}
- hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
+ hnd->base_metadata = uint64_t(mappedAddress);
}
return 0;
}
@@ -102,7 +102,7 @@
return -errno;
}
- hnd->base = uint64_t(mappedAddress) + hnd->offset;
+ hnd->base = uint64_t(mappedAddress);
} else {
// Cannot map secure buffers or framebuffers, but still need to map
// metadata for secure buffers.
diff --git a/sdm845/libgralloc/memalloc.h b/msm8909w_3100/libgralloc/memalloc.h
similarity index 100%
rename from sdm845/libgralloc/memalloc.h
rename to msm8909w_3100/libgralloc/memalloc.h
diff --git a/sdm845/libgralloc1/Android.mk b/msm8909w_3100/libgralloc1/Android.mk
similarity index 100%
rename from sdm845/libgralloc1/Android.mk
rename to msm8909w_3100/libgralloc1/Android.mk
diff --git a/sdm845/libgralloc1/gr_adreno_info.cpp b/msm8909w_3100/libgralloc1/gr_adreno_info.cpp
similarity index 87%
rename from sdm845/libgralloc1/gr_adreno_info.cpp
rename to msm8909w_3100/libgralloc1/gr_adreno_info.cpp
index ecac238..110a641 100644
--- a/sdm845/libgralloc1/gr_adreno_info.cpp
+++ b/msm8909w_3100/libgralloc1/gr_adreno_info.cpp
@@ -48,22 +48,16 @@
lock_guard<mutex> obj(s_lock);
if (!s_instance) {
s_instance = new AdrenoMemInfo();
- if (!s_instance->Init()) {
- delete s_instance;
- s_instance = nullptr;
- }
}
return s_instance;
}
-bool AdrenoMemInfo::Init() {
+AdrenoMemInfo::AdrenoMemInfo() {
libadreno_utils_ = ::dlopen("libadreno_utils.so", RTLD_NOW);
if (libadreno_utils_) {
*reinterpret_cast<void **>(&LINK_adreno_compute_aligned_width_and_height) =
::dlsym(libadreno_utils_, "compute_aligned_width_and_height");
- *reinterpret_cast<void **>(&LINK_adreno_compute_fmt_aligned_width_and_height) =
- ::dlsym(libadreno_utils_, "compute_fmt_aligned_width_and_height");
*reinterpret_cast<void **>(&LINK_adreno_compute_padding) =
::dlsym(libadreno_utils_, "compute_surface_padding");
*reinterpret_cast<void **>(&LINK_adreno_compute_compressedfmt_aligned_width_and_height) =
@@ -74,13 +68,12 @@
::dlsym(libadreno_utils_, "get_gpu_pixel_alignment");
} else {
ALOGE(" Failed to load libadreno_utils.so");
- return false;
}
- // Check if the overriding property debug.gralloc.gfx_ubwc_disable
+ // Check if the overriding property debug.gralloc.gfx_ubwc_disable_
// that disables UBWC allocations for the graphics stack is set
char property[PROPERTY_VALUE_MAX];
- property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
+ property_get("debug.gralloc.gfx_ubwc_disable_", property, "0");
if (!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
!(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
gfx_ubwc_disable_ = true;
@@ -91,8 +84,6 @@
(!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
map_fb_ = true;
}
-
- return true;
}
AdrenoMemInfo::~AdrenoMemInfo() {
@@ -132,15 +123,7 @@
int padding_threshold = 512; // Threshold for padding surfaces.
// the function below computes aligned width and aligned height
// based on linear or macro tile mode selected.
- if (LINK_adreno_compute_fmt_aligned_width_and_height) {
- // We call into adreno_utils only for RGB formats. So plane_id is 0 and
- // num_samples is 1 always. We may have to add uitility function to
- // find out these if there is a need to call this API for YUV formats.
- LINK_adreno_compute_fmt_aligned_width_and_height(
- width, height, 0/*plane_id*/, GetGpuPixelFormat(format), 1/*num_samples*/,
- tile_enabled, raster_mode, padding_threshold,
- reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h));
- } else if (LINK_adreno_compute_aligned_width_and_height) {
+ if (LINK_adreno_compute_aligned_width_and_height) {
LINK_adreno_compute_aligned_width_and_height(
width, height, bpp, tile_enabled, raster_mode, padding_threshold,
reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h));
@@ -152,7 +135,6 @@
} else {
ALOGW(
"%s: Warning!! Symbols compute_surface_padding and "
- "compute_fmt_aligned_width_and_height and "
"compute_aligned_width_and_height not found",
__FUNCTION__);
}
@@ -170,6 +152,8 @@
width, height, format, 0, raster_mode, padding_threshold,
reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h), &bytesPerPixel);
} else {
+ *aligned_w = (unsigned int)ALIGN(width, 32);
+ *aligned_h = (unsigned int)ALIGN(height, 32);
ALOGW("%s: Warning!! compute_compressedfmt_aligned_width_and_height not found", __FUNCTION__);
}
}
@@ -217,6 +201,8 @@
return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
case HAL_PIXEL_FORMAT_ABGR_2101010:
return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ return ADRENO_PIXELFORMAT_R8G8B8;
default:
ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
break;
diff --git a/sdm845/libgralloc1/gr_adreno_info.h b/msm8909w_3100/libgralloc1/gr_adreno_info.h
similarity index 92%
copy from sdm845/libgralloc1/gr_adreno_info.h
copy to msm8909w_3100/libgralloc1/gr_adreno_info.h
index 75ba507..478b527 100644
--- a/sdm845/libgralloc1/gr_adreno_info.h
+++ b/msm8909w_3100/libgralloc1/gr_adreno_info.h
@@ -71,8 +71,6 @@
class AdrenoMemInfo {
public:
- bool Init();
-
/*
* Function to compute aligned width and aligned height based on
* width, height, format and usage flags.
@@ -123,6 +121,7 @@
static AdrenoMemInfo *GetInstance();
private:
+ AdrenoMemInfo();
~AdrenoMemInfo();
// link(s)to adreno surface padding library.
int (*LINK_adreno_compute_padding)(int width, int bpp, int surface_tile_height,
@@ -131,11 +130,6 @@
int tile_mode, int raster_mode,
int padding_threshold, int *aligned_w,
int *aligned_h) = NULL;
- void (*LINK_adreno_compute_fmt_aligned_width_and_height)(int width, int height, int plane_id,
- int format, int num_samples,
- int tile_mode, int raster_mode,
- int padding_threshold, int *aligned_w,
- int *aligned_h) = NULL;
void (*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
int width, int height, int format, int tile_mode, int raster_mode, int padding_threshold,
int *aligned_w, int *aligned_h, int *bpp) = NULL;
diff --git a/sdm845/libgralloc1/gr_allocator.cpp b/msm8909w_3100/libgralloc1/gr_allocator.cpp
similarity index 100%
rename from sdm845/libgralloc1/gr_allocator.cpp
rename to msm8909w_3100/libgralloc1/gr_allocator.cpp
diff --git a/sdm845/libgralloc1/gr_allocator.h b/msm8909w_3100/libgralloc1/gr_allocator.h
similarity index 100%
rename from sdm845/libgralloc1/gr_allocator.h
rename to msm8909w_3100/libgralloc1/gr_allocator.h
diff --git a/sdm845/libgralloc1/gr_buf_descriptor.h b/msm8909w_3100/libgralloc1/gr_buf_descriptor.h
similarity index 100%
rename from sdm845/libgralloc1/gr_buf_descriptor.h
rename to msm8909w_3100/libgralloc1/gr_buf_descriptor.h
diff --git a/sdm845/libgralloc1/gr_buf_mgr.cpp b/msm8909w_3100/libgralloc1/gr_buf_mgr.cpp
similarity index 95%
rename from sdm845/libgralloc1/gr_buf_mgr.cpp
rename to msm8909w_3100/libgralloc1/gr_buf_mgr.cpp
index 7e0ba14..2bcc42e 100644
--- a/sdm845/libgralloc1/gr_buf_mgr.cpp
+++ b/msm8909w_3100/libgralloc1/gr_buf_mgr.cpp
@@ -49,13 +49,6 @@
map_fb_mem_ = true;
}
- // Enable UBWC for framebuffer
- if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
- (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
- ubwc_for_fb_ = true;
- }
-
handles_map_.clear();
allocator_ = new Allocator();
allocator_->Init();
@@ -214,7 +207,9 @@
private_handle_t * handle = const_cast<private_handle_t *>(hnd);
handle->fd = -1;
handle->fd_metadata = -1;
- delete handle;
+ if (!(handle->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED)) {
+ delete handle;
+ }
return GRALLOC1_ERROR_NONE;
}
@@ -260,27 +255,14 @@
ALOGD_IF(DEBUG, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);
hnd->base = 0;
- hnd->base_metadata = 0;
-
if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
hnd->fd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
-
- unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), getpagesize());
- if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
- hnd->offset_metadata, hnd->fd_metadata) != 0) {
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
return GRALLOC1_ERROR_NONE;
}
gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
- if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
- return GRALLOC1_ERROR_NONE;
- }
-
ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
gralloc1_error_t err = GRALLOC1_ERROR_NONE;
std::lock_guard<std::mutex> lock(buffer_lock_);
@@ -302,10 +284,6 @@
}
gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
- if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
- return GRALLOC1_ERROR_NONE;
- }
-
ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id);
std::lock_guard<std::mutex> lock(buffer_lock_);
auto buf = GetBufferFromHandleLocked(hnd);
@@ -573,6 +551,10 @@
int format = va_arg(args, int);
native_handle_t **handle = va_arg(args, native_handle_t **);
+ if (!handle) {
+ return GRALLOC1_ERROR_BAD_HANDLE;
+ }
+
private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
if (hnd) {
@@ -582,7 +564,7 @@
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
hnd->size = size;
hnd->offset = offset;
- hnd->base = uint64_t(base) + offset;
+ hnd->base = uint64_t(base);
hnd->gpuaddr = 0;
BufferInfo info(width, height, format);
GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
@@ -600,6 +582,11 @@
int format = va_arg(args, int);
int *stride = va_arg(args, int *);
unsigned int alignedw = 0, alignedh = 0;
+
+ if (!stride) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
BufferInfo info(width, width, format);
GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
*stride = INT(alignedw);
@@ -612,6 +599,10 @@
return GRALLOC1_ERROR_BAD_HANDLE;
}
+ if (!stride) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
BufferDim_t buffer_dim;
if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
*stride = buffer_dim.sliceWidth;
@@ -629,6 +620,10 @@
return GRALLOC1_ERROR_BAD_HANDLE;
}
+ if (!stride || !height) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
BufferDim_t buffer_dim;
if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
*stride = buffer_dim.sliceWidth;
@@ -653,6 +648,10 @@
int *aligned_width = va_arg(args, int *);
int *aligned_height = va_arg(args, int *);
int *tile_enabled = va_arg(args, int *);
+ if (!aligned_width || !aligned_height || !tile_enabled) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
unsigned int alignedw, alignedh;
BufferInfo info(width, height, format, prod_usage, cons_usage);
*tile_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
@@ -664,9 +663,15 @@
case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *color_space = va_arg(args, int *);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!color_space) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
*color_space = 0;
#ifdef USE_COLOR_METADATA
ColorMetaData color_metadata;
@@ -698,6 +703,11 @@
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!ycbcr) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
if (GetYUVPlaneInfo(hnd, ycbcr)) {
return GRALLOC1_ERROR_UNDEFINED;
}
@@ -706,10 +716,15 @@
case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *map_secure_buffer = va_arg(args, int *);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+ if (!map_secure_buffer) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) == 0) {
*map_secure_buffer = 0;
}
@@ -718,18 +733,36 @@
case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *flag = va_arg(args, int *);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!flag) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
*flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ int linear_format = 0;
+ if (getMetaData(hnd, GET_LINEAR_FORMAT, &linear_format) == 0) {
+ if (linear_format) {
+ *flag = 0;
+ }
+ }
} break;
case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
void **rgb_data = va_arg(args, void **);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!rgb_data) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
if (GetRgbDataAddress(hnd, rgb_data)) {
return GRALLOC1_ERROR_UNDEFINED;
}
@@ -746,6 +779,11 @@
uint32_t *aligned_width = va_arg(args, uint32_t *);
uint32_t *aligned_height = va_arg(args, uint32_t *);
uint32_t *size = va_arg(args, uint32_t *);
+
+ if (!aligned_width || !aligned_height || !size) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
auto info = BufferInfo(width, height, format, producer_usage, consumer_usage);
GetBufferSizeAndDimensions(info, size, aligned_width, aligned_height);
// Align size
@@ -753,8 +791,6 @@
*size = ALIGN(*size, align);
} break;
- // TODO(user): Break out similar functionality, preferably moving to a common lib.
-
case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
int width = va_arg(args, int);
int height = va_arg(args, int);
@@ -774,9 +810,15 @@
case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *flag = va_arg(args, int *);
+
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+
+ if (!flag) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
*flag = 0;
}
diff --git a/sdm845/libgralloc1/gr_buf_mgr.h b/msm8909w_3100/libgralloc1/gr_buf_mgr.h
similarity index 99%
rename from sdm845/libgralloc1/gr_buf_mgr.h
rename to msm8909w_3100/libgralloc1/gr_buf_mgr.h
index 4476eaf..861a7a7 100644
--- a/sdm845/libgralloc1/gr_buf_mgr.h
+++ b/msm8909w_3100/libgralloc1/gr_buf_mgr.h
@@ -118,7 +118,6 @@
std::shared_ptr<Buffer> GetBufferFromHandleLocked(const private_handle_t *hnd);
bool map_fb_mem_ = false;
- bool ubwc_for_fb_ = false;
Allocator *allocator_ = NULL;
std::mutex buffer_lock_;
std::mutex descriptor_lock_;
diff --git a/sdm845/libgralloc1/gr_device_impl.cpp b/msm8909w_3100/libgralloc1/gr_device_impl.cpp
similarity index 96%
rename from sdm845/libgralloc1/gr_device_impl.cpp
rename to msm8909w_3100/libgralloc1/gr_device_impl.cpp
index ee90090..3202f2b 100644
--- a/sdm845/libgralloc1/gr_device_impl.cpp
+++ b/msm8909w_3100/libgralloc1/gr_device_impl.cpp
@@ -27,10 +27,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
#include <cutils/log.h>
-#include <utils/Trace.h>
-#include <cutils/trace.h>
#include <sync/sync.h>
#include <algorithm>
#include <sstream>
@@ -347,6 +344,10 @@
gralloc1_error_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_producer_usage_t *outUsage) {
+ if (!outUsage) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
@@ -358,6 +359,10 @@
gralloc1_error_t GrallocImpl::GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *outStride) {
+ if (!outStride) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
*outStride = UINT(PRIV_HANDLE_CONST(buffer)->GetStride());
@@ -373,6 +378,10 @@
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
+ if (!device) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
GrallocImpl const *dev = GRALLOC_IMPL(device);
gralloc1_error_t status = dev->buf_mgr_->AllocateBuffers(num_descriptors, descriptors,
out_buffers);
@@ -404,6 +413,10 @@
gralloc1_error_t GrallocImpl::GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *out_num_planes) {
+ if (!out_num_planes) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
GrallocImpl const *dev = GRALLOC_IMPL(device);
@@ -424,17 +437,15 @@
gralloc1_consumer_usage_t cons_usage,
const gralloc1_rect_t *region, void **out_data,
int32_t acquire_fence) {
- ATRACE_CALL();
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
- if (status != GRALLOC1_ERROR_NONE) {
+ if (status != GRALLOC1_ERROR_NONE || !out_data ||
+ !region) { // currently we ignore the region/rect client wants to lock
CloseFdIfValid(acquire_fence);
return status;
}
if (acquire_fence > 0) {
- ATRACE_BEGIN("fence wait");
int error = sync_wait(acquire_fence, 1000);
- ATRACE_END();
CloseFdIfValid(acquire_fence);
if (error < 0) {
ALOGE("%s: sync_wait timedout! error = %s", __FUNCTION__, strerror(errno));
@@ -453,13 +464,8 @@
// return GRALLOC1_ERROR_BAD_VALUE;
}
- // currently we ignore the region/rect client wants to lock
- if (region == NULL) {
- return GRALLOC1_ERROR_BAD_VALUE;
- }
// TODO(user): Need to check if buffer was allocated with the same flags
status = dev->buf_mgr_->LockBuffer(hnd, prod_usage, cons_usage);
-
*out_data = reinterpret_cast<void *>(hnd->base);
return status;
@@ -471,7 +477,12 @@
const gralloc1_rect_t *region,
struct android_flex_layout *out_flex_layout,
int32_t acquire_fence) {
- void *out_data;
+ if (!out_flex_layout) {
+ CloseFdIfValid(acquire_fence);
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
+ void *out_data {};
gralloc1_error_t status = GrallocImpl::LockBuffer(device, buffer, prod_usage, cons_usage, region,
&out_data, acquire_fence);
if (status != GRALLOC1_ERROR_NONE) {
@@ -487,11 +498,14 @@
gralloc1_error_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
int32_t *release_fence) {
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
-
if (status != GRALLOC1_ERROR_NONE) {
return status;
}
+ if (!release_fence) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
GrallocImpl const *dev = GRALLOC_IMPL(device);
@@ -501,6 +515,10 @@
}
gralloc1_error_t GrallocImpl::Gralloc1Perform(gralloc1_device_t *device, int operation, ...) {
+ if (!device) {
+ return GRALLOC1_ERROR_BAD_VALUE;
+ }
+
va_list args;
va_start(args, operation);
GrallocImpl const *dev = GRALLOC_IMPL(device);
diff --git a/sdm845/libgralloc1/gr_device_impl.h b/msm8909w_3100/libgralloc1/gr_device_impl.h
similarity index 100%
rename from sdm845/libgralloc1/gr_device_impl.h
rename to msm8909w_3100/libgralloc1/gr_device_impl.h
diff --git a/sdm845/libgralloc1/gr_ion_alloc.cpp b/msm8909w_3100/libgralloc1/gr_ion_alloc.cpp
similarity index 95%
copy from sdm845/libgralloc1/gr_ion_alloc.cpp
copy to msm8909w_3100/libgralloc1/gr_ion_alloc.cpp
index c8300ab..aebbe12 100644
--- a/sdm845/libgralloc1/gr_ion_alloc.cpp
+++ b/msm8909w_3100/libgralloc1/gr_ion_alloc.cpp
@@ -36,8 +36,7 @@
#include <cutils/log.h>
#include <errno.h>
#include <utils/Trace.h>
-#include <cutils/trace.h>
-#include <string>
+#include <string.h>
#include "gralloc_priv.h"
#include "gr_utils.h"
@@ -79,29 +78,21 @@
ion_alloc_data.heap_id_mask = data->heap_id;
ion_alloc_data.flags = data->flags;
ion_alloc_data.flags |= data->uncached ? 0 : ION_FLAG_CACHED;
- std::string tag_name{};
- if (ATRACE_ENABLED()) {
- tag_name = "ION_IOC_ALLOC size: " + std::to_string(data->size);
- }
- ATRACE_BEGIN(tag_name.c_str());
if (ioctl(ion_dev_fd_, INT(ION_IOC_ALLOC), &ion_alloc_data)) {
err = -errno;
ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
return err;
}
- ATRACE_END();
fd_data.handle = ion_alloc_data.handle;
handle_data.handle = ion_alloc_data.handle;
- ATRACE_BEGIN("ION_IOC_MAP");
if (ioctl(ion_dev_fd_, INT(ION_IOC_MAP), &fd_data)) {
err = -errno;
ALOGE("%s: ION_IOC_MAP failed with error - %s", __FUNCTION__, strerror(errno));
ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
return err;
}
- ATRACE_END();
data->fd = fd_data.fd;
data->ion_handle = handle_data.handle;
diff --git a/sdm845/libgralloc1/gr_ion_alloc.h b/msm8909w_3100/libgralloc1/gr_ion_alloc.h
similarity index 100%
rename from sdm845/libgralloc1/gr_ion_alloc.h
rename to msm8909w_3100/libgralloc1/gr_ion_alloc.h
diff --git a/sdm845/libgralloc1/gr_priv_handle.h b/msm8909w_3100/libgralloc1/gr_priv_handle.h
similarity index 97%
rename from sdm845/libgralloc1/gr_priv_handle.h
rename to msm8909w_3100/libgralloc1/gr_priv_handle.h
index 49e09a5..775ad72 100644
--- a/sdm845/libgralloc1/gr_priv_handle.h
+++ b/msm8909w_3100/libgralloc1/gr_priv_handle.h
@@ -23,7 +23,11 @@
#include <cutils/log.h>
#include <hardware/gralloc1.h>
#include <hardware/gralloc.h>
+#ifdef __cplusplus
#include <cinttypes>
+#endif
+
+#include <errno.h>
#define GRALLOC1_FUNCTION_PERFORM 0x00001000
@@ -33,7 +37,12 @@
#define PRIV_HANDLE_CONST(exp) static_cast<const private_handle_t *>(exp)
+#ifdef __cplusplus
struct private_handle_t : public native_handle_t {
+#else
+struct private_handle_t {
+ native_handle_t nativeHandle;
+#endif
enum {
PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
PRIV_FLAGS_USES_ION = 0x00000008,
@@ -83,7 +92,7 @@
gralloc1_producer_usage_t producer_usage __attribute__((aligned(8)));
gralloc1_consumer_usage_t consumer_usage __attribute__((aligned(8)));
unsigned int layer_count;
-
+#ifdef __cplusplus
static const int kNumFds = 2;
static const int kMagic = 'gmsm';
@@ -160,7 +169,6 @@
return 0;
}
-
static void Dump(const private_handle_t *hnd) {
ALOGD("handle id:%" PRIu64 " wxh:%dx%d uwxuh:%dx%d size: %d fd:%d fd_meta:%d flags:0x%x "
"prod_usage:0x%" PRIx64" cons_usage:0x%" PRIx64 " format:0x%x layer_count: %d",
@@ -187,6 +195,7 @@
gralloc1_producer_usage_t GetProducerUsage() const { return producer_usage; }
uint64_t GetBackingstore() const { return id; }
+#endif
};
#endif // __GR_PRIV_HANDLE_H__
diff --git a/sdm845/libgralloc1/gr_utils.cpp b/msm8909w_3100/libgralloc1/gr_utils.cpp
similarity index 95%
copy from sdm845/libgralloc1/gr_utils.cpp
copy to msm8909w_3100/libgralloc1/gr_utils.cpp
index b3056e1..d89b8fe 100644
--- a/sdm845/libgralloc1/gr_utils.cpp
+++ b/msm8909w_3100/libgralloc1/gr_utils.cpp
@@ -357,29 +357,33 @@
bool interlaced = false;
memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
- MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
// Check if UBWC buffer has been rendered in linear format.
- if (metadata && (metadata->operation & LINEAR_FORMAT)) {
- format = INT(metadata->linearFormat);
+ int linear_format = 0;
+ if (getMetaData(const_cast<private_handle_t *>(hnd),
+ GET_LINEAR_FORMAT, &linear_format) == 0) {
+ format = INT(linear_format);
}
// Check metadata if the geometry has been updated.
- if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+ BufferDim_t buffer_dim;
+ if (getMetaData(const_cast<private_handle_t *>(hnd),
+ GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
int usage = 0;
-
if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
}
- BufferInfo info(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
+ BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format,
prod_usage, cons_usage);
GetAlignedWidthAndHeight(info, &width, &height);
}
// Check metadata for interlaced content.
- if (metadata && (metadata->operation & PP_PARAM_INTERLACED)) {
- interlaced = metadata->interlaced ? true : false;
+ int interlace_flag = 0;
+ if (getMetaData(const_cast<private_handle_t *>(hnd),
+ GET_PP_PARAM_INTERLACED, &interlace_flag) != 0) {
+ interlaced = interlace_flag;
}
// Get the chroma offsets from the handle width/height. We take advantage
@@ -509,7 +513,9 @@
// Query GPU for UBWC only if buffer is intended to be used by GPU.
if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
(prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
- enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
+ if (AdrenoMemInfo::GetInstance()) {
+ enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
+ }
}
// Allow UBWC, only if CPU usage flags are not set
@@ -675,8 +681,10 @@
int tile = ubwc_enabled;
if (IsUncompressedRGBFormat(format)) {
- AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
- alignedh);
+ if (AdrenoMemInfo::GetInstance()) {
+ AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
+ alignedh);
+ }
return;
}
@@ -686,7 +694,9 @@
}
if (IsCompressedRGBFormat(format)) {
- AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
+ if (AdrenoMemInfo::GetInstance()) {
+ AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
+ }
return;
}
@@ -698,6 +708,9 @@
switch (format) {
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ if (AdrenoMemInfo::GetInstance() == nullptr) {
+ return;
+ }
alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
aligned_w = ALIGN(width, alignment);
break;
diff --git a/sdm845/libgralloc1/gr_utils.h b/msm8909w_3100/libgralloc1/gr_utils.h
similarity index 100%
rename from sdm845/libgralloc1/gr_utils.h
rename to msm8909w_3100/libgralloc1/gr_utils.h
diff --git a/sdm845/libgralloc1/gralloc_priv.h b/msm8909w_3100/libgralloc1/gralloc_priv.h
similarity index 98%
rename from sdm845/libgralloc1/gralloc_priv.h
rename to msm8909w_3100/libgralloc1/gralloc_priv.h
index 1839d2f..c7a6beb 100644
--- a/sdm845/libgralloc1/gralloc_priv.h
+++ b/msm8909w_3100/libgralloc1/gralloc_priv.h
@@ -77,6 +77,7 @@
#define GRALLOC_USAGE_PRIVATE_IOMMU_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_IOMMU_HEAP
#define GRALLOC_USAGE_PRIVATE_WFD GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD
#define GRALLOC_USAGE_PRIVATE_CAMERA_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP
+#define GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY
#define GRALLOC_USAGE_PRIVATE_MM_HEAP 0x0
diff --git a/sdm845/liblight/Android.mk b/msm8909w_3100/liblight/Android.mk
similarity index 100%
rename from sdm845/liblight/Android.mk
rename to msm8909w_3100/liblight/Android.mk
diff --git a/sdm845/liblight/NOTICE b/msm8909w_3100/liblight/NOTICE
similarity index 100%
rename from sdm845/liblight/NOTICE
rename to msm8909w_3100/liblight/NOTICE
diff --git a/sdm845/liblight/lights.c b/msm8909w_3100/liblight/lights.c
similarity index 100%
rename from sdm845/liblight/lights.c
rename to msm8909w_3100/liblight/lights.c
diff --git a/sdm845/liblight/lights_prv.cpp b/msm8909w_3100/liblight/lights_prv.cpp
similarity index 100%
copy from sdm845/liblight/lights_prv.cpp
copy to msm8909w_3100/liblight/lights_prv.cpp
diff --git a/sdm845/liblight/lights_prv.h b/msm8909w_3100/liblight/lights_prv.h
similarity index 100%
copy from sdm845/liblight/lights_prv.h
copy to msm8909w_3100/liblight/lights_prv.h
diff --git a/sdm845/libmemtrack/Android.mk b/msm8909w_3100/libmemtrack/Android.mk
similarity index 100%
rename from sdm845/libmemtrack/Android.mk
rename to msm8909w_3100/libmemtrack/Android.mk
diff --git a/sdm845/libmemtrack/kgsl.c b/msm8909w_3100/libmemtrack/kgsl.c
similarity index 100%
rename from sdm845/libmemtrack/kgsl.c
rename to msm8909w_3100/libmemtrack/kgsl.c
diff --git a/sdm845/libmemtrack/memtrack_msm.c b/msm8909w_3100/libmemtrack/memtrack_msm.c
similarity index 100%
rename from sdm845/libmemtrack/memtrack_msm.c
rename to msm8909w_3100/libmemtrack/memtrack_msm.c
diff --git a/sdm845/libmemtrack/memtrack_msm.h b/msm8909w_3100/libmemtrack/memtrack_msm.h
similarity index 100%
rename from sdm845/libmemtrack/memtrack_msm.h
rename to msm8909w_3100/libmemtrack/memtrack_msm.h
diff --git a/sdm845/libqdutils/Android.mk b/msm8909w_3100/libqdutils/Android.mk
similarity index 100%
rename from sdm845/libqdutils/Android.mk
rename to msm8909w_3100/libqdutils/Android.mk
diff --git a/sdm845/libqdutils/Makefile.am b/msm8909w_3100/libqdutils/Makefile.am
similarity index 100%
copy from sdm845/libqdutils/Makefile.am
copy to msm8909w_3100/libqdutils/Makefile.am
diff --git a/sdm845/libqdutils/display_config.cpp b/msm8909w_3100/libqdutils/display_config.cpp
similarity index 95%
rename from sdm845/libqdutils/display_config.cpp
rename to msm8909w_3100/libqdutils/display_config.cpp
index 83d912e..ec24614 100644
--- a/sdm845/libqdutils/display_config.cpp
+++ b/msm8909w_3100/libqdutils/display_config.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2013-2014, 2016, 2018 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -316,6 +316,22 @@
return panel_brightness;
}
+int setStandByMode(int mode) {
+ status_t err = (status_t) FAILED_TRANSACTION;
+ sp<IQService> binder = getBinder();
+ Parcel inParcel, outParcel;
+
+ if(binder != NULL) {
+ inParcel.writeInt32(mode);
+ err = binder->dispatch(IQService::SET_STAND_BY_MODE,
+ &inParcel, &outParcel);
+ if(err) {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ }
+ }
+ return err;
+}
+
}// namespace
// ----------------------------------------------------------------------------
diff --git a/sdm845/libqdutils/display_config.h b/msm8909w_3100/libqdutils/display_config.h
similarity index 97%
rename from sdm845/libqdutils/display_config.h
rename to msm8909w_3100/libqdutils/display_config.h
index 6512bf5..d5b56ed 100644
--- a/sdm845/libqdutils/display_config.h
+++ b/msm8909w_3100/libqdutils/display_config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 - 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2016, 2018 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -158,6 +158,7 @@
// Retrieves the current panel brightness value
int getPanelBrightness();
+int setStandByMode(int mode);
}; //namespace
#endif
diff --git a/sdm845/libqdutils/profiler.cpp b/msm8909w_3100/libqdutils/profiler.cpp
similarity index 100%
rename from sdm845/libqdutils/profiler.cpp
rename to msm8909w_3100/libqdutils/profiler.cpp
diff --git a/sdm845/libqdutils/profiler.h b/msm8909w_3100/libqdutils/profiler.h
similarity index 100%
rename from sdm845/libqdutils/profiler.h
rename to msm8909w_3100/libqdutils/profiler.h
diff --git a/sdm845/libqdutils/qdMetaData.cpp b/msm8909w_3100/libqdutils/qdMetaData.cpp
similarity index 97%
rename from sdm845/libqdutils/qdMetaData.cpp
rename to msm8909w_3100/libqdutils/qdMetaData.cpp
index ae23b53..d9be570 100644
--- a/sdm845/libqdutils/qdMetaData.cpp
+++ b/msm8909w_3100/libqdutils/qdMetaData.cpp
@@ -120,8 +120,8 @@
case SET_VT_TIMESTAMP:
data->vtTimeStamp = *((uint64_t *)param);
break;
-#ifdef USE_COLOR_METADATA
case COLOR_METADATA:
+#ifdef USE_COLOR_METADATA
data->color = *((ColorMetaData *)param);
#endif
break;
@@ -239,8 +239,8 @@
ret = 0;
}
break;
-#ifdef USE_COLOR_METADATA
case GET_COLOR_METADATA:
+#ifdef USE_COLOR_METADATA
if (data->operation & COLOR_METADATA) {
*((ColorMetaData *)param) = data->color;
ret = 0;
@@ -265,7 +265,7 @@
MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
- memcpy(src_data, dst_data, getMetaDataSize());
+ *dst_data = *src_data;
return 0;
}
@@ -279,7 +279,7 @@
return err;
MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
- memcpy(src_data, dst_data, getMetaDataSize());
+ *dst_data = *src_data;
return 0;
}
@@ -293,7 +293,7 @@
return err;
MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
- memcpy(src_data, dst_data, getMetaDataSize());
+ *dst_data = *src_data;
return 0;
}
@@ -305,7 +305,7 @@
if (dst_data == nullptr)
return err;
- memcpy(src_data, dst_data, getMetaDataSize());
+ *dst_data = *src_data;
return 0;
}
diff --git a/sdm845/libqdutils/qdMetaData.h b/msm8909w_3100/libqdutils/qdMetaData.h
similarity index 100%
rename from sdm845/libqdutils/qdMetaData.h
rename to msm8909w_3100/libqdutils/qdMetaData.h
diff --git a/sdm845/libqdutils/qd_utils.cpp b/msm8909w_3100/libqdutils/qd_utils.cpp
similarity index 100%
rename from sdm845/libqdutils/qd_utils.cpp
rename to msm8909w_3100/libqdutils/qd_utils.cpp
diff --git a/sdm845/libqdutils/qd_utils.h b/msm8909w_3100/libqdutils/qd_utils.h
similarity index 100%
rename from sdm845/libqdutils/qd_utils.h
rename to msm8909w_3100/libqdutils/qd_utils.h
diff --git a/sdm845/libqservice/Android.mk b/msm8909w_3100/libqservice/Android.mk
similarity index 100%
rename from sdm845/libqservice/Android.mk
rename to msm8909w_3100/libqservice/Android.mk
diff --git a/sdm845/libqservice/IQClient.cpp b/msm8909w_3100/libqservice/IQClient.cpp
similarity index 100%
rename from sdm845/libqservice/IQClient.cpp
rename to msm8909w_3100/libqservice/IQClient.cpp
diff --git a/sdm845/libqservice/IQClient.h b/msm8909w_3100/libqservice/IQClient.h
similarity index 100%
rename from sdm845/libqservice/IQClient.h
rename to msm8909w_3100/libqservice/IQClient.h
diff --git a/sdm845/libqservice/IQHDMIClient.cpp b/msm8909w_3100/libqservice/IQHDMIClient.cpp
similarity index 100%
rename from sdm845/libqservice/IQHDMIClient.cpp
rename to msm8909w_3100/libqservice/IQHDMIClient.cpp
diff --git a/sdm845/libqservice/IQHDMIClient.h b/msm8909w_3100/libqservice/IQHDMIClient.h
similarity index 100%
copy from sdm845/libqservice/IQHDMIClient.h
copy to msm8909w_3100/libqservice/IQHDMIClient.h
diff --git a/sdm845/libqservice/IQService.cpp b/msm8909w_3100/libqservice/IQService.cpp
similarity index 100%
rename from sdm845/libqservice/IQService.cpp
rename to msm8909w_3100/libqservice/IQService.cpp
diff --git a/sdm845/libqservice/IQService.h b/msm8909w_3100/libqservice/IQService.h
similarity index 96%
rename from sdm845/libqservice/IQService.h
rename to msm8909w_3100/libqservice/IQService.h
index 5e327d7..47dd1b0 100644
--- a/sdm845/libqservice/IQService.h
+++ b/msm8909w_3100/libqservice/IQService.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, 2016, 2018 The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -75,7 +75,7 @@
SET_LAYER_MIXER_RESOLUTION = 33, // Enables client to set layer mixer resolution.
SET_COLOR_MODE = 34, // Overrides the QDCM mode on the display
GET_HDR_CAPABILITIES = 35, // Get HDR capabilities for legacy HWC interface
- SET_COLOR_MODE_BY_ID = 36, // Overrides the QDCM mode using the given mode ID
+ SET_STAND_BY_MODE = 36, //Set stand by mode for MDP3 hardware.
COMMAND_LIST_END = 400,
};
diff --git a/sdm845/libqservice/Makefile.am b/msm8909w_3100/libqservice/Makefile.am
similarity index 100%
copy from sdm845/libqservice/Makefile.am
copy to msm8909w_3100/libqservice/Makefile.am
diff --git a/sdm845/libqservice/QService.cpp b/msm8909w_3100/libqservice/QService.cpp
similarity index 100%
rename from sdm845/libqservice/QService.cpp
rename to msm8909w_3100/libqservice/QService.cpp
diff --git a/sdm845/libqservice/QService.h b/msm8909w_3100/libqservice/QService.h
similarity index 100%
rename from sdm845/libqservice/QService.h
rename to msm8909w_3100/libqservice/QService.h
diff --git a/sdm845/libqservice/QServiceUtils.h b/msm8909w_3100/libqservice/QServiceUtils.h
similarity index 100%
rename from sdm845/libqservice/QServiceUtils.h
rename to msm8909w_3100/libqservice/QServiceUtils.h
diff --git a/sdm845/sdm/include/core/buffer_allocator.h b/msm8909w_3100/sdm/include/core/buffer_allocator.h
similarity index 100%
copy from sdm845/sdm/include/core/buffer_allocator.h
copy to msm8909w_3100/sdm/include/core/buffer_allocator.h
diff --git a/sdm845/sdm/include/core/buffer_sync_handler.h b/msm8909w_3100/sdm/include/core/buffer_sync_handler.h
similarity index 100%
copy from sdm845/sdm/include/core/buffer_sync_handler.h
copy to msm8909w_3100/sdm/include/core/buffer_sync_handler.h
diff --git a/sdm845/sdm/include/core/core_interface.h b/msm8909w_3100/sdm/include/core/core_interface.h
similarity index 100%
rename from sdm845/sdm/include/core/core_interface.h
rename to msm8909w_3100/sdm/include/core/core_interface.h
diff --git a/sdm845/sdm/include/core/debug_interface.h b/msm8909w_3100/sdm/include/core/debug_interface.h
similarity index 97%
rename from sdm845/sdm/include/core/debug_interface.h
rename to msm8909w_3100/sdm/include/core/debug_interface.h
index da21944..f4e3fc3 100644
--- a/sdm845/sdm/include/core/debug_interface.h
+++ b/msm8909w_3100/sdm/include/core/debug_interface.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -49,7 +49,6 @@
kTagRotator, //!< Debug log is tagged for rotator.
kTagScalar, //!< Debug log is tagged for Scalar Helper.
kTagQDCM, //!< Debug log is tagged for display QDCM color managing.
- kTagQOSClient, //!< Debug log is tagged for Qos client
};
/*! @brief Display debug handler class.
diff --git a/sdm845/sdm/include/core/display_interface.h b/msm8909w_3100/sdm/include/core/display_interface.h
similarity index 97%
rename from sdm845/sdm/include/core/display_interface.h
rename to msm8909w_3100/sdm/include/core/display_interface.h
index 524141e..8715709 100644
--- a/sdm845/sdm/include/core/display_interface.h
+++ b/msm8909w_3100/sdm/include/core/display_interface.h
@@ -135,6 +135,12 @@
kPortDP, // Display is connected to DP port.
};
+/*! @brief This enum represents the events received by Display HAL. */
+enum DisplayEvent {
+ kIdleTimeout, // Event triggered by Idle Timer.
+ kThermalEvent, // Event triggered by Thermal.
+};
+
/*! @brief This structure defines configuration for fixed properties of a display device.
@sa DisplayInterface::GetConfig
@@ -245,6 +251,9 @@
*/
virtual DisplayError CECMessage(char *message) = 0;
+ /*! @brief Event handler for events received by Display HAL. */
+ virtual DisplayError HandleEvent(DisplayEvent event) = 0;
+
protected:
virtual ~DisplayEventHandler() { }
};
@@ -455,13 +464,11 @@
/*! @brief Method to set the refresh rate of a display.
- @param[in] refresh_rate new refresh rate of the display.
-
- @param[in] final_rate indicates whether refresh rate is final rate or can be changed by sdm
+ @param[in] new refresh rate of the display.
@return \link DisplayError \endlink
*/
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate) = 0;
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate) = 0;
/*! @brief Method to query whether scanning is support for the HDMI display.
@@ -541,13 +548,6 @@
*/
virtual DisplayError SetColorMode(const std::string &color_mode) = 0;
- /*! @brief Method to set the color mode by ID. This method is used for debugging only.
-
- @param[in] mode_name Mode ID which needs to be set
-
- @return \link DisplayError \endlink
- */
- virtual DisplayError SetColorModeById(int32_t color_mode_id) = 0;
/*! @brief Method to set the color transform
@param[in] length Mode name which needs to be set
diff --git a/sdm845/sdm/include/core/dump_interface.h b/msm8909w_3100/sdm/include/core/dump_interface.h
similarity index 100%
rename from sdm845/sdm/include/core/dump_interface.h
rename to msm8909w_3100/sdm/include/core/dump_interface.h
diff --git a/sdm845/sdm/include/core/layer_buffer.h b/msm8909w_3100/sdm/include/core/layer_buffer.h
similarity index 100%
copy from sdm845/sdm/include/core/layer_buffer.h
copy to msm8909w_3100/sdm/include/core/layer_buffer.h
diff --git a/sdm845/sdm/include/core/layer_stack.h b/msm8909w_3100/sdm/include/core/layer_stack.h
similarity index 98%
copy from sdm845/sdm/include/core/layer_stack.h
copy to msm8909w_3100/sdm/include/core/layer_stack.h
index b8977e2..f12e5c1 100644
--- a/sdm845/sdm/include/core/layer_stack.h
+++ b/msm8909w_3100/sdm/include/core/layer_stack.h
@@ -85,8 +85,8 @@
kCompositionSDE, //!< This layer will be composed by SDE. It must not be composed by
//!< GPU or Blit.
- kCompositionCursor, // This cursor layer can receive async position updates irrespective of
- // dedicated h/w cursor usage. It must not be composed by GPU or Blit
+ kCompositionHWCursor, //!< This layer will be composed by SDE using HW Cursor. It must not be
+ //!< composed by GPU or Blit.
kCompositionHybrid, //!< This layer will be drawn by a blit engine and SDE together.
//!< Display device will split the layer, update the blit rectangle
diff --git a/sdm845/sdm/include/core/sdm_types.h b/msm8909w_3100/sdm/include/core/sdm_types.h
similarity index 97%
copy from sdm845/sdm/include/core/sdm_types.h
copy to msm8909w_3100/sdm/include/core/sdm_types.h
index fae1153..f8bb4e3 100644
--- a/sdm845/sdm/include/core/sdm_types.h
+++ b/msm8909w_3100/sdm/include/core/sdm_types.h
@@ -55,6 +55,7 @@
kErrorShutDown, //!< Driver is processing shutdown sequence
kErrorPerfValidation, //!< Bandwidth or Clock requirement validation failure.
kErrorNoAppLayers, //!< No App layer(s) in the draw cycle.
+ kErrorNotValidated, //!< Draw cycle has not been validated.
};
/*! @brief This structure is defined for client and library compatibility check purpose only. This
diff --git a/sdm845/sdm/include/core/socket_handler.h b/msm8909w_3100/sdm/include/core/socket_handler.h
similarity index 100%
copy from sdm845/sdm/include/core/socket_handler.h
copy to msm8909w_3100/sdm/include/core/socket_handler.h
diff --git a/sdm845/sdm/include/private/color_interface.h b/msm8909w_3100/sdm/include/private/color_interface.h
similarity index 100%
copy from sdm845/sdm/include/private/color_interface.h
copy to msm8909w_3100/sdm/include/private/color_interface.h
diff --git a/sdm845/sdm/include/private/color_params.h b/msm8909w_3100/sdm/include/private/color_params.h
similarity index 97%
rename from sdm845/sdm/include/private/color_params.h
rename to msm8909w_3100/sdm/include/private/color_params.h
index 0a53832..97089d6 100644
--- a/sdm845/sdm/include/private/color_params.h
+++ b/msm8909w_3100/sdm/include/private/color_params.h
@@ -37,12 +37,16 @@
#include <core/sdm_types.h>
#include <core/display_interface.h>
+#include <utility>
#include <string>
+#include <vector>
#include "hw_info_types.h"
namespace sdm {
+typedef std::vector<std::pair<std::string, std::string>> AttrVal;
+
// Bitmap Pending action to indicate to the caller what's pending to be taken care of.
enum PendingAction {
kInvalidating = BITMAP(0),
@@ -89,7 +93,7 @@
static const std::string kSdr = "sdr";
static const std::string kNative = "native";
-static const std::string kDcip3 = "dci_p3";
+static const std::string kDcip3 = "dcip3";
static const std::string kSrgb = "srgb";
static const std::string kDisplayP3 = "display_p3";
@@ -578,9 +582,13 @@
// from ColorManager, containing all physical features to be programmed and also compute
// metadata/populate into T.
inline DisplayError AddFeature(uint32_t feature_id, PPFeatureInfo *feature) {
- if (feature_id < kMaxNumPPFeatures)
+ if (feature_id < kMaxNumPPFeatures) {
+ if (feature_[feature_id]) {
+ delete feature_[feature_id];
+ feature_[feature_id] = NULL;
+ }
feature_[feature_id] = feature;
-
+ }
return kErrorNone;
}
diff --git a/sdm845/sdm/include/private/dpps_control_interface.h b/msm8909w_3100/sdm/include/private/dpps_control_interface.h
similarity index 100%
copy from sdm845/sdm/include/private/dpps_control_interface.h
copy to msm8909w_3100/sdm/include/private/dpps_control_interface.h
diff --git a/sdm845/sdm/include/private/extension_interface.h b/msm8909w_3100/sdm/include/private/extension_interface.h
similarity index 100%
copy from sdm845/sdm/include/private/extension_interface.h
copy to msm8909w_3100/sdm/include/private/extension_interface.h
diff --git a/sdm845/sdm/include/private/hw_info_types.h b/msm8909w_3100/sdm/include/private/hw_info_types.h
similarity index 96%
rename from sdm845/sdm/include/private/hw_info_types.h
rename to msm8909w_3100/sdm/include/private/hw_info_types.h
index cdfec2e..54c07af 100644
--- a/sdm845/sdm/include/private/hw_info_types.h
+++ b/msm8909w_3100/sdm/include/private/hw_info_types.h
@@ -38,8 +38,6 @@
const int kMaxSDELayers = 16; // Maximum number of layers that can be handled by MDP5 hardware
// in a given layer stack.
-const int kMaxBlitLayers = 32; // Maximum number of layers that can be handled by MDP3 hardware
- // in a given layer stack.
#define MAX_PLANES 4
#define MAX_DETAIL_ENHANCE_CURVE 3
@@ -111,12 +109,11 @@
};
typedef std::map<HWSubBlockType, std::vector<LayerBufferFormat>> FormatsMap;
-typedef std::map<LayerBufferFormat, float> CompRatioMap;
struct HWDynBwLimitInfo {
uint32_t cur_mode = kBwDefault;
- uint64_t total_bw_limit[kBwModeMax] = { 0 };
- uint64_t pipe_bw_limit[kBwModeMax] = { 0 };
+ uint32_t total_bw_limit[kBwModeMax] = { 0 };
+ uint32_t pipe_bw_limit[kBwModeMax] = { 0 };
};
struct HWPipeCaps {
@@ -143,7 +140,6 @@
uint32_t max_input_width = 0;
uint32_t max_output_width = 0;
uint32_t max_scale_up = 1;
- uint32_t prefill_lines = 4;
};
enum SmartDMARevision {
@@ -171,7 +167,7 @@
uint32_t max_mixer_width = 2048;
uint32_t max_pipe_width = 2048;
uint32_t max_cursor_size = 0;
- uint64_t max_pipe_bw = 0;
+ uint32_t max_pipe_bw = 0;
uint32_t max_sde_clk = 0;
float clk_fudge_factor = 1.0f;
uint32_t macrotile_nv12_factor = 0;
@@ -187,6 +183,7 @@
bool has_macrotile = false;
bool has_non_scalar_rgb = false;
bool is_src_split = false;
+ bool perf_calc = false;
bool has_dyn_bw_support = false;
bool separate_rotator = false;
bool has_qseed3 = false;
@@ -201,11 +198,6 @@
bool has_avr = false;
bool has_hdr = false;
SmartDMARevision smart_dma_rev = SmartDMARevision::V1;
- float ib_fudge_factor = 1.0f;
- uint32_t undersized_prefill_lines = 0;
- CompRatioMap comp_ratio_rt_map;
- CompRatioMap comp_ratio_nrt_map;
-
void Reset() { *this = HWResourceInfo(); }
};
@@ -438,7 +430,6 @@
};
struct HWPipeInfo {
- HWPipeInfo *pair = NULL;
uint8_t rect = 255;
uint32_t pipe_id = 0;
HWSubBlockType sub_block_type = kHWSubBlockMax;
@@ -492,8 +483,10 @@
std::vector<LayerRect> left_frame_roi = {}; // Left ROI.
std::vector<LayerRect> right_frame_roi = {}; // Right ROI.
LayerRect partial_fb_roi = {}; // Damaged area in framebuffer.
+
bool roi_split = false; // Indicates separated left and right ROI
- bool async_cursor_updates = false; // Cursor layer allowed to have async updates
+
+ bool use_hw_cursor = false; // Indicates that HWCursor pipe needs to be used for cursor layer
DestScaleInfoMap dest_scale_info_map = {};
HWHDRLayerInfo hdr_layer_info = {};
Handle pvt_data = NULL; // Private data used by sdm extension only.
@@ -503,9 +496,8 @@
HWLayersInfo info;
HWLayerConfig config[kMaxSDELayers];
float output_compression = 1.0f;
- uint64_t ab_bps = 0;
- uint64_t ib_bps = 0;
- uint32_t clock_hz = 0;
+ uint32_t bandwidth = 0;
+ uint32_t clock = 0;
HWAVRInfo hw_avr_info = {};
};
diff --git a/sdm845/sdm/include/private/partial_update_interface.h b/msm8909w_3100/sdm/include/private/partial_update_interface.h
similarity index 92%
copy from sdm845/sdm/include/private/partial_update_interface.h
copy to msm8909w_3100/sdm/include/private/partial_update_interface.h
index a1c2382..b753587 100644
--- a/sdm845/sdm/include/private/partial_update_interface.h
+++ b/msm8909w_3100/sdm/include/private/partial_update_interface.h
@@ -35,6 +35,8 @@
struct PUConstraints {
bool enable = true; //!< If this is set, PU will be enabled or it will be disabled
+ bool enable_cursor_pu = false; //!< If this is set, PU will consider cursor layer in the layer
+ //!< stack for cursor partial update
};
class PartialUpdateInterface {
diff --git a/sdm845/sdm/include/private/resource_interface.h b/msm8909w_3100/sdm/include/private/resource_interface.h
similarity index 88%
copy from sdm845/sdm/include/private/resource_interface.h
copy to msm8909w_3100/sdm/include/private/resource_interface.h
index e140c33..356c566 100644
--- a/sdm845/sdm/include/private/resource_interface.h
+++ b/msm8909w_3100/sdm/include/private/resource_interface.h
@@ -48,7 +48,7 @@
const HWPanelInfo &hw_panel_info,
const HWMixerAttributes &mixer_attributes) = 0;
virtual DisplayError Start(Handle display_ctx) = 0;
- virtual DisplayError Stop(Handle display_ctx) = 0;
+ virtual DisplayError Stop(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers) = 0;
virtual DisplayError Commit(Handle display_ctx, HWLayers *hw_layers) = 0;
@@ -58,8 +58,11 @@
virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
bool rotate90, BufferLayout layout,
bool use_rotator_downscale) = 0;
- virtual DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
- int x, int y) = 0;
+ virtual DisplayError ValidateCursorConfig(Handle display_ctx, const Layer *layer,
+ bool is_top) = 0;
+ virtual DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
+ int x, int y,
+ DisplayConfigVariableInfo *fb_config) = 0;
virtual DisplayError SetMaxBandwidthMode(HWBwModes mode) = 0;
virtual DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info) = 0;
virtual DisplayError SetDetailEnhancerData(Handle display_ctx,
diff --git a/sdm845/sdm/include/private/strategy_interface.h b/msm8909w_3100/sdm/include/private/strategy_interface.h
similarity index 93%
copy from sdm845/sdm/include/private/strategy_interface.h
copy to msm8909w_3100/sdm/include/private/strategy_interface.h
index 1174e7f..f903d5f 100644
--- a/sdm845/sdm/include/private/strategy_interface.h
+++ b/msm8909w_3100/sdm/include/private/strategy_interface.h
@@ -36,6 +36,9 @@
//!< that requires minimum number of pipe for the current frame. i.e.,
//!< video only composition, secure only composition or GPU composition
+ bool use_cursor = false; //!< If this is set, strategy manager will configure cursor layer in the
+ //!< layer stack as hw cursor else it will be treated as a normal layer
+
uint32_t max_layers = kMaxSDELayers; //!< Maximum number of layers that shall be programmed
//!< on hardware for the given layer stack.
};
diff --git a/sdm845/sdm/include/utils/constants.h b/msm8909w_3100/sdm/include/utils/constants.h
similarity index 100%
copy from sdm845/sdm/include/utils/constants.h
copy to msm8909w_3100/sdm/include/utils/constants.h
diff --git a/sdm845/sdm/include/utils/debug.h b/msm8909w_3100/sdm/include/utils/debug.h
similarity index 100%
rename from sdm845/sdm/include/utils/debug.h
rename to msm8909w_3100/sdm/include/utils/debug.h
diff --git a/sdm845/sdm/include/utils/factory.h b/msm8909w_3100/sdm/include/utils/factory.h
similarity index 100%
copy from sdm845/sdm/include/utils/factory.h
copy to msm8909w_3100/sdm/include/utils/factory.h
diff --git a/sdm845/sdm/include/utils/formats.h b/msm8909w_3100/sdm/include/utils/formats.h
similarity index 100%
copy from sdm845/sdm/include/utils/formats.h
copy to msm8909w_3100/sdm/include/utils/formats.h
diff --git a/sdm845/sdm/include/utils/locker.h b/msm8909w_3100/sdm/include/utils/locker.h
similarity index 100%
copy from sdm845/sdm/include/utils/locker.h
copy to msm8909w_3100/sdm/include/utils/locker.h
diff --git a/sdm845/sdm/include/utils/rect.h b/msm8909w_3100/sdm/include/utils/rect.h
similarity index 100%
rename from sdm845/sdm/include/utils/rect.h
rename to msm8909w_3100/sdm/include/utils/rect.h
diff --git a/msm8909w_3100/sdm/include/utils/sync_task.h b/msm8909w_3100/sdm/include/utils/sync_task.h
new file mode 100644
index 0000000..725460a
--- /dev/null
+++ b/msm8909w_3100/sdm/include/utils/sync_task.h
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __SYNC_TASK_H__
+#define __SYNC_TASK_H__
+
+#include <thread>
+#include <mutex>
+#include <condition_variable> // NOLINT
+
+namespace sdm {
+
+template <class TaskCode>
+class SyncTask {
+ public:
+ // This class need to be overridden by caller to pass on a task context.
+ class TaskContext {
+ public:
+ virtual ~TaskContext() { }
+ };
+
+ // Methods to callback into caller for command codes executions in worker thread.
+ class TaskHandler {
+ public:
+ virtual ~TaskHandler() { }
+ virtual void OnTask(const TaskCode &task_code, TaskContext *task_context) = 0;
+ };
+
+ explicit SyncTask(TaskHandler &task_handler) : task_handler_(task_handler) {
+ // Block caller thread until worker thread has started and ready to listen to task commands.
+ // Worker thread will signal as soon as callback is received in the new thread.
+ std::unique_lock<std::mutex> caller_lock(caller_mutex_);
+ std::thread worker_thread(SyncTaskThread, this);
+ worker_thread_.swap(worker_thread);
+ caller_cv_.wait(caller_lock);
+ }
+
+ ~SyncTask() {
+ // Task code does not matter here.
+ PerformTask(task_code_, nullptr, true);
+ worker_thread_.join();
+ }
+
+ void PerformTask(const TaskCode &task_code, TaskContext *task_context) {
+ PerformTask(task_code, task_context, false);
+ }
+
+ private:
+ void PerformTask(const TaskCode &task_code, TaskContext *task_context, bool terminate) {
+ std::unique_lock<std::mutex> caller_lock(caller_mutex_);
+
+ // New scope to limit scope of worker lock to this block.
+ {
+ // Set task command code and notify worker thread.
+ std::unique_lock<std::mutex> worker_lock(worker_mutex_);
+ task_code_ = task_code;
+ task_context_ = task_context;
+ worker_thread_exit_ = terminate;
+ pending_code_ = true;
+ worker_cv_.notify_one();
+ }
+
+ // Wait for worker thread to finish and signal.
+ caller_cv_.wait(caller_lock);
+ }
+
+ static void SyncTaskThread(SyncTask *sync_task) {
+ if (sync_task) {
+ sync_task->OnThreadCallback();
+ }
+ }
+
+ void OnThreadCallback() {
+ // Acquire worker lock and start waiting for events.
+ // Wait must start before caller thread can post events, otherwise posted events will be lost.
+ // Caller thread will be blocked until worker thread signals readiness.
+ std::unique_lock<std::mutex> worker_lock(worker_mutex_);
+
+ // New scope to limit scope of caller lock to this block.
+ {
+ // Signal caller thread that worker thread is ready to listen to events.
+ std::unique_lock<std::mutex> caller_lock(caller_mutex_);
+ caller_cv_.notify_one();
+ }
+
+ while (!worker_thread_exit_) {
+ // Add predicate to handle spurious interrupts.
+ // Wait for caller thread to signal new command codes.
+ worker_cv_.wait(worker_lock, [this] { return pending_code_; });
+
+ // Call task handler which is implemented by the caller.
+ if (!worker_thread_exit_) {
+ task_handler_.OnTask(task_code_, task_context_);
+ }
+
+ pending_code_ = false;
+ // Notify completion of current task to the caller thread which is blocked.
+ std::unique_lock<std::mutex> caller_lock(caller_mutex_);
+ caller_cv_.notify_one();
+ }
+ }
+
+ TaskHandler &task_handler_;
+ TaskCode task_code_;
+ TaskContext *task_context_ = nullptr;
+ std::thread worker_thread_;
+ std::mutex caller_mutex_;
+ std::mutex worker_mutex_;
+ std::condition_variable caller_cv_;
+ std::condition_variable worker_cv_;
+ bool worker_thread_exit_ = false;
+ bool pending_code_ = false;
+};
+
+} // namespace sdm
+
+#endif // __SYNC_TASK_H__
diff --git a/sdm845/sdm/include/utils/sys.h b/msm8909w_3100/sdm/include/utils/sys.h
similarity index 100%
copy from sdm845/sdm/include/utils/sys.h
copy to msm8909w_3100/sdm/include/utils/sys.h
diff --git a/sdm845/sdm/include/utils/utils.h b/msm8909w_3100/sdm/include/utils/utils.h
similarity index 100%
copy from sdm845/sdm/include/utils/utils.h
copy to msm8909w_3100/sdm/include/utils/utils.h
diff --git a/sdm845/sdm/libs/core/Android.mk b/msm8909w_3100/sdm/libs/core/Android.mk
similarity index 95%
rename from sdm845/sdm/libs/core/Android.mk
rename to msm8909w_3100/sdm/libs/core/Android.mk
index c5002a9..1d55d96 100644
--- a/sdm845/sdm/libs/core/Android.mk
+++ b/msm8909w_3100/sdm/libs/core/Android.mk
@@ -7,7 +7,7 @@
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_HEADER_LIBRARIES := display_headers
-LOCAL_CFLAGS := -fno-operator-names -Wno-unused-parameter -DLOG_TAG=\"SDM\" \
+LOCAL_CFLAGS := -Wno-unused-parameter -DLOG_TAG=\"SDM\" \
$(common_flags)
LOCAL_HW_INTF_PATH_1 := fb
LOCAL_SHARED_LIBRARIES := libdl libsdmutils
@@ -51,7 +51,6 @@
$(LOCAL_HW_INTF_PATH_2)/hw_device_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_events_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_scale_drm.cpp \
- $(LOCAL_HW_INTF_PATH_2)/hw_virtual_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_color_manager_drm.cpp
endif
diff --git a/sdm845/sdm/libs/core/Makefile.am b/msm8909w_3100/sdm/libs/core/Makefile.am
similarity index 100%
copy from sdm845/sdm/libs/core/Makefile.am
copy to msm8909w_3100/sdm/libs/core/Makefile.am
diff --git a/sdm845/sdm/libs/core/color_manager.cpp b/msm8909w_3100/sdm/libs/core/color_manager.cpp
similarity index 100%
copy from sdm845/sdm/libs/core/color_manager.cpp
copy to msm8909w_3100/sdm/libs/core/color_manager.cpp
diff --git a/sdm845/sdm/libs/core/color_manager.h b/msm8909w_3100/sdm/libs/core/color_manager.h
similarity index 100%
copy from sdm845/sdm/libs/core/color_manager.h
copy to msm8909w_3100/sdm/libs/core/color_manager.h
diff --git a/sdm845/sdm/libs/core/comp_manager.cpp b/msm8909w_3100/sdm/libs/core/comp_manager.cpp
similarity index 87%
rename from sdm845/sdm/libs/core/comp_manager.cpp
rename to msm8909w_3100/sdm/libs/core/comp_manager.cpp
index d18b5b8..8d0e71e 100644
--- a/sdm845/sdm/libs/core/comp_manager.cpp
+++ b/msm8909w_3100/sdm/libs/core/comp_manager.cpp
@@ -33,6 +33,12 @@
namespace sdm {
+static bool NeedsScaledComposition(const DisplayConfigVariableInfo &fb_config,
+ const HWMixerAttributes &mixer_attributes) {
+ return ((fb_config.x_pixels != mixer_attributes.width) ||
+ (fb_config.y_pixels != mixer_attributes.height));
+}
+
DisplayError CompManager::Init(const HWResourceInfo &hw_res_info,
ExtensionInterface *extension_intf,
BufferAllocator *buffer_allocator,
@@ -121,6 +127,7 @@
registered_displays_[type] = 1;
display_comp_ctx->is_primary_panel = hw_panel_info.is_primary_panel;
display_comp_ctx->display_type = type;
+ display_comp_ctx->fb_config = fb_config;
*display_ctx = display_comp_ctx;
// New non-primary display device has been added, so move the composition mode to safe mode until
// resources for the added display is configured properly.
@@ -129,6 +136,7 @@
max_sde_ext_layers_ = UINT32(Debug::GetExtMaxlayers());
}
+ display_comp_ctx->scaled_composition = NeedsScaledComposition(fb_config, mixer_attributes);
DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
"display type %d", registered_displays_.to_ulong(), configured_displays_.to_ulong(),
display_comp_ctx->display_type);
@@ -207,6 +215,10 @@
}
}
+ display_comp_ctx->scaled_composition = NeedsScaledComposition(fb_config, mixer_attributes);
+ // Update new resolution.
+ display_comp_ctx->fb_config = fb_config;
+
return error;
}
@@ -216,6 +228,7 @@
StrategyConstraints *constraints = &display_comp_ctx->constraints;
constraints->safe_mode = safe_mode_;
+ constraints->use_cursor = false;
constraints->max_layers = max_layers_;
// Limit 2 layer SDE Comp if its not a Primary Display.
@@ -232,6 +245,9 @@
constraints->safe_mode = true;
}
+ // Set use_cursor constraint to Strategy
+ constraints->use_cursor = display_comp_ctx->valid_cursor;
+
// TODO(user): App layer count will change for hybrid composition
uint32_t app_layer_count = UINT32(hw_layers->info.stack->layers.size()) - 1;
if (display_comp_ctx->idle_fallback || display_comp_ctx->thermal_fallback_) {
@@ -249,6 +265,11 @@
SCOPE_LOCK(locker_);
DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
+ display_comp_ctx->valid_cursor = SupportLayerAsCursor(display_comp_ctx, hw_layers);
+
+ // pu constraints
+ display_comp_ctx->pu_constraints.enable_cursor_pu = display_comp_ctx->valid_cursor;
+
display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies,
display_comp_ctx->pu_constraints);
display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
@@ -286,10 +307,12 @@
}
if (error != kErrorNone) {
+ resource_intf_->Stop(display_resource_ctx, hw_layers);
DLOGE("Composition strategies exhausted for display = %d", display_comp_ctx->display_type);
+ return error;
}
- resource_intf_->Stop(display_resource_ctx);
+ error = resource_intf_->Stop(display_resource_ctx, hw_layers);
return error;
}
@@ -335,7 +358,7 @@
DLOGE("Reconfigure failed for display = %d", display_comp_ctx->display_type);
}
- resource_intf_->Stop(display_resource_ctx);
+ resource_intf_->Stop(display_resource_ctx, hw_layers);
if (error != kErrorNone) {
error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
}
@@ -459,13 +482,46 @@
return resource_intf_->ValidateScaling(crop, dst, rotate90, layout, true);
}
-DisplayError CompManager::ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
+DisplayError CompManager::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
int x, int y) {
DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
+ return resource_intf_->ValidateAndSetCursorPosition(display_resource_ctx, hw_layers, x, y,
+ &display_comp_ctx->fb_config);
+}
- return resource_intf_->ValidateCursorPosition(display_resource_ctx, hw_layers, x, y);
+bool CompManager::SupportLayerAsCursor(Handle comp_handle, HWLayers *hw_layers) {
+ DisplayCompositionContext *display_comp_ctx =
+ reinterpret_cast<DisplayCompositionContext *>(comp_handle);
+ Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
+ LayerStack *layer_stack = hw_layers->info.stack;
+ bool supported = false;
+ int32_t gpu_index = -1;
+
+ // HW Cursor cannot be used, if Display configuration needs scaled composition.
+ if (display_comp_ctx->scaled_composition || !layer_stack->flags.cursor_present) {
+ return supported;
+ }
+
+ for (int32_t i = INT32(layer_stack->layers.size() - 1); i >= 0; i--) {
+ Layer *layer = layer_stack->layers.at(UINT32(i));
+ if (layer->composition == kCompositionGPUTarget) {
+ gpu_index = i;
+ break;
+ }
+ }
+ if (gpu_index <= 0) {
+ return supported;
+ }
+ Layer *cursor_layer = layer_stack->layers.at(UINT32(gpu_index) - 1);
+ if (cursor_layer->flags.cursor && !cursor_layer->flags.skip &&
+ resource_intf_->ValidateCursorConfig(display_resource_ctx,
+ cursor_layer, true) == kErrorNone) {
+ supported = true;
+ }
+
+ return supported;
}
DisplayError CompManager::SetMaxBandwidthMode(HWBwModes mode) {
diff --git a/sdm845/sdm/libs/core/comp_manager.h b/msm8909w_3100/sdm/libs/core/comp_manager.h
similarity index 95%
rename from sdm845/sdm/libs/core/comp_manager.h
rename to msm8909w_3100/sdm/libs/core/comp_manager.h
index c6b8972..01899dc 100644
--- a/sdm845/sdm/libs/core/comp_manager.h
+++ b/msm8909w_3100/sdm/libs/core/comp_manager.h
@@ -67,6 +67,8 @@
void ControlPartialUpdate(Handle display_ctx, bool enable);
DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90);
DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
+ bool SupportLayerAsCursor(Handle display_ctx, HWLayers *hw_layers);
+ DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
bool SetDisplayState(Handle display_ctx, DisplayState state, DisplayType display_type);
DisplayError SetMaxBandwidthMode(HWBwModes mode);
DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info);
@@ -96,7 +98,10 @@
// Using primary panel flag of hw panel to configure Constraints. We do not need other hw
// panel parameters for now.
bool is_primary_panel = false;
+ bool valid_cursor = false;
PUConstraints pu_constraints = {};
+ bool scaled_composition = false;
+ DisplayConfigVariableInfo fb_config = {};
};
Locker locker_;
diff --git a/sdm845/sdm/libs/core/core_impl.cpp b/msm8909w_3100/sdm/libs/core/core_impl.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/core_impl.cpp
rename to msm8909w_3100/sdm/libs/core/core_impl.cpp
diff --git a/sdm845/sdm/libs/core/core_impl.h b/msm8909w_3100/sdm/libs/core/core_impl.h
similarity index 100%
rename from sdm845/sdm/libs/core/core_impl.h
rename to msm8909w_3100/sdm/libs/core/core_impl.h
diff --git a/sdm845/sdm/libs/core/core_interface.cpp b/msm8909w_3100/sdm/libs/core/core_interface.cpp
similarity index 100%
copy from sdm845/sdm/libs/core/core_interface.cpp
copy to msm8909w_3100/sdm/libs/core/core_interface.cpp
diff --git a/sdm845/sdm/libs/core/display_base.cpp b/msm8909w_3100/sdm/libs/core/display_base.cpp
similarity index 97%
rename from sdm845/sdm/libs/core/display_base.cpp
rename to msm8909w_3100/sdm/libs/core/display_base.cpp
index 618dd2e..78de716 100644
--- a/sdm845/sdm/libs/core/display_base.cpp
+++ b/msm8909w_3100/sdm/libs/core/display_base.cpp
@@ -211,6 +211,7 @@
DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = kErrorNone;
+ needs_validate_ = true;
if (!active_) {
return kErrorPermission;
@@ -250,7 +251,7 @@
error = hw_intf_->Validate(&hw_layers_);
if (error == kErrorNone) {
// Strategy is successful now, wait for Commit().
- pending_commit_ = true;
+ needs_validate_ = false;
break;
}
if (error == kErrorShutDown) {
@@ -269,7 +270,7 @@
DisplayError error = kErrorNone;
if (!active_) {
- pending_commit_ = false;
+ needs_validate_ = true;
return kErrorPermission;
}
@@ -277,13 +278,11 @@
return kErrorParameters;
}
- if (!pending_commit_) {
+ if (needs_validate_) {
DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_);
- return kErrorUndefined;
+ return kErrorNotValidated;
}
- pending_commit_ = false;
-
// Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp
if (layer_stack->flags.attributes_changed) {
error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_);
@@ -299,10 +298,9 @@
CommitLayerParams(layer_stack);
- if (comp_manager_->Commit(display_comp_ctx_, &hw_layers_)) {
- if (error != kErrorNone) {
- return error;
- }
+ error = comp_manager_->Commit(display_comp_ctx_, &hw_layers_);
+ if (error != kErrorNone) {
+ return error;
}
// check if feature list cache is dirty and pending.
@@ -343,7 +341,7 @@
error = hw_intf_->Flush();
if (error == kErrorNone) {
comp_manager_->Purge(display_comp_ctx_);
- pending_commit_ = false;
+ needs_validate_ = true;
} else {
DLOGW("Unable to flush display = %d", display_type_);
}
@@ -446,16 +444,9 @@
break;
case kStateDoze:
- error = hw_intf_->Doze();
- active = true;
- break;
-
case kStateDozeSuspend:
error = hw_intf_->DozeSuspend();
- if (display_type_ != kPrimary) {
- active = true;
- }
-
+ active = true;
break;
case kStateStandby:
@@ -664,7 +655,7 @@
switch (composition) {
case kCompositionGPU: return "GPU";
case kCompositionSDE: return "SDE";
- case kCompositionCursor: return "CURSOR";
+ case kCompositionHWCursor: return "CURSOR";
case kCompositionHybrid: return "HYBRID";
case kCompositionBlit: return "BLIT";
case kCompositionGPUTarget: return "GPU_TARGET";
@@ -803,10 +794,6 @@
return error;
}
-DisplayError DisplayBase::SetColorModeById(int32_t color_mode_id) {
- return color_mgr_->ColorMgrSetMode(color_mode_id);
-}
-
DisplayError DisplayBase::SetColorModeInternal(const std::string &color_mode) {
DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str());
@@ -830,7 +817,7 @@
return error;
}
-DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr, const std::string &type,
+DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr,const std::string &type,
std::string *value) {
if (!value) {
return kErrorParameters;
@@ -954,7 +941,8 @@
return kErrorNotSupported;
}
- DisplayError error = comp_manager_->ValidateCursorPosition(display_comp_ctx_, &hw_layers_, x, y);
+ DisplayError error = comp_manager_->ValidateAndSetCursorPosition(display_comp_ctx_, &hw_layers_,
+ x, y);
if (error == kErrorNone) {
return hw_intf_->SetCursorPosition(&hw_layers_, x, y);
}
@@ -986,14 +974,10 @@
DisplayError error = kErrorNone;
if (vsync_enable_ != enable) {
error = hw_intf_->SetVSyncState(enable);
- if (error == kErrorNotSupported) {
- error = hw_events_intf_->SetEventState(HWEvent::VSYNC, enable);
- }
if (error == kErrorNone) {
vsync_enable_ = enable;
}
}
-
return error;
}
@@ -1325,10 +1309,6 @@
sdm_layer->input_buffer.release_fence_fd = temp;
}
-
- // Reset the sync fence fds of HWLayer
- hw_layer.input_buffer.acquire_fence_fd = -1;
- hw_layer.input_buffer.release_fence_fd = -1;
}
return;
diff --git a/sdm845/sdm/libs/core/display_base.h b/msm8909w_3100/sdm/libs/core/display_base.h
similarity index 98%
rename from sdm845/sdm/libs/core/display_base.h
rename to msm8909w_3100/sdm/libs/core/display_base.h
index 4023229..58265df 100644
--- a/sdm845/sdm/libs/core/display_base.h
+++ b/msm8909w_3100/sdm/libs/core/display_base.h
@@ -96,7 +96,6 @@
virtual DisplayError GetColorModes(uint32_t *mode_count, std::vector<std::string> *color_modes);
virtual DisplayError GetColorModeAttr(const std::string &color_mode, AttrVal *attr);
virtual DisplayError SetColorMode(const std::string &color_mode);
- virtual DisplayError SetColorModeById(int32_t color_mode_id);
virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform);
virtual DisplayError GetDefaultColorMode(std::string *color_mode);
virtual DisplayError ApplyDefaultDisplayMode(void);
@@ -153,7 +152,7 @@
Handle hw_device_ = 0;
Handle display_comp_ctx_ = 0;
HWLayers hw_layers_;
- bool pending_commit_ = false;
+ bool needs_validate_ = true;
bool vsync_enable_ = false;
uint32_t max_mixer_stages_ = 0;
HWInfoInterface *hw_info_intf_ = NULL;
diff --git a/sdm845/sdm/libs/core/display_hdmi.cpp b/msm8909w_3100/sdm/libs/core/display_hdmi.cpp
similarity index 95%
rename from sdm845/sdm/libs/core/display_hdmi.cpp
rename to msm8909w_3100/sdm/libs/core/display_hdmi.cpp
index b31ac94..450a5fe 100644
--- a/sdm845/sdm/libs/core/display_hdmi.cpp
+++ b/msm8909w_3100/sdm/libs/core/display_hdmi.cpp
@@ -94,8 +94,6 @@
DLOGE("Failed to create hardware events interface. Error = %d", error);
}
- current_refresh_rate_ = hw_panel_info_.max_fps;
-
return error;
}
@@ -137,21 +135,18 @@
return error;
}
-DisplayError DisplayHDMI::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+DisplayError DisplayHDMI::SetRefreshRate(uint32_t refresh_rate) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!active_) {
return kErrorPermission;
}
- if (current_refresh_rate_ != refresh_rate) {
- DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
- if (error != kErrorNone) {
- return error;
- }
+ DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
+ if (error != kErrorNone) {
+ return error;
}
- current_refresh_rate_ = refresh_rate;
return DisplayBase::ReconfigureDisplay();
}
@@ -168,7 +163,6 @@
uint32_t DisplayHDMI::GetBestConfig(HWS3DMode s3d_mode) {
uint32_t best_index = 0, index;
uint32_t num_modes = 0;
- HWDisplayAttributes best_attrib;
hw_intf_->GetNumDisplayAttributes(&num_modes);
@@ -295,10 +289,6 @@
DisplayBase::ReconfigureDisplay();
}
-void DisplayHDMI::CECMessage(char *message) {
- event_handler_->CECMessage(message);
-}
-
DisplayError DisplayHDMI::VSync(int64_t timestamp) {
if (vsync_enable_) {
DisplayEventVSync vsync;
@@ -310,4 +300,3 @@
}
} // namespace sdm
-
diff --git a/sdm845/sdm/libs/core/display_hdmi.h b/msm8909w_3100/sdm/libs/core/display_hdmi.h
similarity index 92%
copy from sdm845/sdm/libs/core/display_hdmi.h
copy to msm8909w_3100/sdm/libs/core/display_hdmi.h
index ca09ce3..fbd632f 100644
--- a/sdm845/sdm/libs/core/display_hdmi.h
+++ b/msm8909w_3100/sdm/libs/core/display_hdmi.h
@@ -44,7 +44,7 @@
virtual DisplayError Init();
virtual DisplayError Prepare(LayerStack *layer_stack);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate);
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
virtual bool IsUnderscanSupported();
virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
@@ -53,7 +53,6 @@
virtual DisplayError Blank(bool blank) { return kErrorNone; }
virtual void IdleTimeout() { }
virtual void ThermalEvent(int64_t thermal_level) { }
- virtual void CECMessage(char *message);
virtual void IdlePowerCollapse() { }
private:
@@ -64,9 +63,8 @@
bool underscan_supported_ = false;
HWScanSupport scan_support_;
std::map<LayerBufferS3DFormat, HWS3DMode> s3d_format_to_mode_;
- std::vector<HWEvent> event_list_ = { HWEvent::VSYNC, HWEvent::IDLE_NOTIFY, HWEvent::EXIT,
- HWEvent::CEC_READ_MESSAGE };
- uint32_t current_refresh_rate_ = 0;
+ std::vector<HWEvent> event_list_ = { HWEvent::VSYNC, HWEvent::IDLE_NOTIFY, HWEvent::EXIT
+ };
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/display_primary.cpp b/msm8909w_3100/sdm/libs/core/display_primary.cpp
similarity index 86%
copy from sdm845/sdm/libs/core/display_primary.cpp
copy to msm8909w_3100/sdm/libs/core/display_primary.cpp
index 53a4fd9..af21297 100644
--- a/sdm845/sdm/libs/core/display_primary.cpp
+++ b/msm8909w_3100/sdm/libs/core/display_primary.cpp
@@ -77,8 +77,6 @@
HWInterface::Destroy(hw_intf_);
}
- current_refresh_rate_ = hw_panel_info_.max_fps;
-
return error;
}
@@ -89,32 +87,6 @@
uint32_t new_mixer_height = 0;
uint32_t display_width = display_attributes_.x_pixels;
uint32_t display_height = display_attributes_.y_pixels;
- bool needs_hv_flip = hw_panel_info_.panel_orientation.flip_horizontal &&
- hw_panel_info_.panel_orientation.flip_vertical;
- LayerRect src_domain = {};
- LayerTransform panel_transform = {};
- DisplayConfigVariableInfo variable_info = {};
-
- if (needs_hv_flip) {
- DisplayBase::GetFrameBufferConfig(&variable_info);
- src_domain.right = variable_info.x_pixels;
- src_domain.bottom = variable_info.y_pixels;
- panel_transform.flip_horizontal = hw_panel_info_.panel_orientation.flip_horizontal;
- panel_transform.flip_vertical = hw_panel_info_.panel_orientation.flip_vertical;
-
- for (Layer *layer : layer_stack->layers) {
- // Modify destination based on panel flip
- TransformHV(src_domain, layer->dst_rect, panel_transform, &layer->dst_rect);
-
- if (layer->flags.solid_fill) {
- continue;
- }
-
- layer->transform.flip_horizontal ^= (hw_panel_info_.panel_orientation.flip_horizontal);
- layer->transform.flip_vertical ^= (hw_panel_info_.panel_orientation.flip_vertical);
- // TODO(user): Check how to handle rotation, if panel has rotation.
- }
- }
if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
error = ReconfigureMixer(new_mixer_width, new_mixer_height);
@@ -264,7 +236,7 @@
return error;
}
-DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!active_ || !hw_panel_info_.dynamic_fps) {
@@ -276,21 +248,11 @@
return kErrorParameters;
}
- if (handle_idle_timeout_ && !final_rate) {
- refresh_rate = hw_panel_info_.min_fps;
+ DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
+ if (error != kErrorNone) {
+ return error;
}
- if ((current_refresh_rate_ != refresh_rate) || handle_idle_timeout_) {
- DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
- if (error != kErrorNone) {
- return error;
- }
- }
-
- // On success, set current refresh rate to new refresh rate
- current_refresh_rate_ = refresh_rate;
- handle_idle_timeout_ = false;
-
return DisplayBase::ReconfigureDisplay();
}
@@ -305,14 +267,15 @@
}
void DisplayPrimary::IdleTimeout() {
- handle_idle_timeout_ = true;
event_handler_->Refresh();
comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
+ event_handler_->HandleEvent(kIdleTimeout);
}
void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
+ event_handler_->HandleEvent(kThermalEvent);
}
void DisplayPrimary::IdlePowerCollapse() {
diff --git a/sdm845/sdm/libs/core/display_primary.h b/msm8909w_3100/sdm/libs/core/display_primary.h
similarity index 94%
rename from sdm845/sdm/libs/core/display_primary.h
rename to msm8909w_3100/sdm/libs/core/display_primary.h
index 314964a..6b9d49f 100644
--- a/sdm845/sdm/libs/core/display_primary.h
+++ b/msm8909w_3100/sdm/libs/core/display_primary.h
@@ -49,7 +49,7 @@
virtual void SetIdleTimeoutMs(uint32_t active_ms);
virtual DisplayError SetDisplayMode(uint32_t mode);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate);
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
virtual DisplayError SetPanelBrightness(int level);
virtual DisplayError GetPanelBrightness(int *level);
virtual DisplayError CachePanelBrightness(int level);
@@ -59,7 +59,6 @@
virtual DisplayError Blank(bool blank) { return kErrorNone; }
virtual void IdleTimeout();
virtual void ThermalEvent(int64_t thermal_level);
- virtual void CECMessage(char *message) { }
virtual void IdlePowerCollapse();
private:
@@ -69,8 +68,6 @@
HWEvent::SHOW_BLANK_EVENT, HWEvent::THERMAL_LEVEL, HWEvent::IDLE_POWER_COLLAPSE };
bool avr_prop_disabled_ = false;
bool switch_to_cmd_ = false;
- bool handle_idle_timeout_ = false;
- uint32_t current_refresh_rate_ = 0;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/display_virtual.cpp b/msm8909w_3100/sdm/libs/core/display_virtual.cpp
similarity index 100%
copy from sdm845/sdm/libs/core/display_virtual.cpp
copy to msm8909w_3100/sdm/libs/core/display_virtual.cpp
diff --git a/sdm845/sdm/libs/core/display_virtual.h b/msm8909w_3100/sdm/libs/core/display_virtual.h
similarity index 97%
rename from sdm845/sdm/libs/core/display_virtual.h
rename to msm8909w_3100/sdm/libs/core/display_virtual.h
index 185366c..aaebf46 100644
--- a/sdm845/sdm/libs/core/display_virtual.h
+++ b/msm8909w_3100/sdm/libs/core/display_virtual.h
@@ -53,7 +53,7 @@
virtual DisplayError SetVSyncState(bool enable) {
return kErrorNotSupported;
}
- virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+ virtual DisplayError SetRefreshRate(uint32_t refresh_rate) {
return kErrorNotSupported;
}
virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height) {
diff --git a/sdm845/sdm/libs/core/drm/hw_color_manager_drm.cpp b/msm8909w_3100/sdm/libs/core/drm/hw_color_manager_drm.cpp
similarity index 100%
copy from sdm845/sdm/libs/core/drm/hw_color_manager_drm.cpp
copy to msm8909w_3100/sdm/libs/core/drm/hw_color_manager_drm.cpp
diff --git a/sdm845/sdm/libs/core/drm/hw_color_manager_drm.h b/msm8909w_3100/sdm/libs/core/drm/hw_color_manager_drm.h
similarity index 100%
copy from sdm845/sdm/libs/core/drm/hw_color_manager_drm.h
copy to msm8909w_3100/sdm/libs/core/drm/hw_color_manager_drm.h
diff --git a/sdm845/sdm/libs/core/drm/hw_device_drm.cpp b/msm8909w_3100/sdm/libs/core/drm/hw_device_drm.cpp
similarity index 84%
rename from sdm845/sdm/libs/core/drm/hw_device_drm.cpp
rename to msm8909w_3100/sdm/libs/core/drm/hw_device_drm.cpp
index 1028663..f1e83bf 100644
--- a/sdm845/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/msm8909w_3100/sdm/libs/core/drm/hw_device_drm.cpp
@@ -48,7 +48,6 @@
#include <utils/debug.h>
#include <utils/formats.h>
#include <utils/sys.h>
-#include <drm/sde_drm.h>
#include <private/color_params.h>
#include <algorithm>
@@ -93,7 +92,6 @@
using sde_drm::DRMSrcConfig;
using sde_drm::DRMOps;
using sde_drm::DRMTopology;
-using sde_drm::DRMPowerMode;
namespace sdm {
@@ -216,6 +214,14 @@
}
void HWDeviceDRM::Registry::RegisterCurrent(HWLayers *hw_layers) {
+ DRMMaster *master = nullptr;
+ DRMMaster::GetInstance(&master);
+
+ if (!master) {
+ DLOGE("Failed to acquire DRM Master instance");
+ return;
+ }
+
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
@@ -229,41 +235,28 @@
input_buffer = &hw_rotator_session->output_buffer;
}
- MapBufferToFbId(input_buffer);
- }
-}
-
-void HWDeviceDRM::Registry::MapBufferToFbId(LayerBuffer* buffer) {
- int fd = buffer->planes[0].fd;
- DRMMaster *master = nullptr;
- DRMMaster::GetInstance(&master);
-
- if (!master) {
- DLOGE("Failed to acquire DRM Master instance");
- return;
- }
-
- if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
- AllocatedBufferInfo buf_info{};
- DRMBuffer layout{};
- buf_info.fd = layout.fd = fd;
- buf_info.aligned_width = layout.width = buffer->width;
- buf_info.aligned_height = layout.height = buffer->height;
- buf_info.format = buffer->format;
- GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
- buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
- &layout.num_planes);
- uint32_t fb_id = 0;
- int ret = master->CreateFbId(layout, &fb_id);
- if (ret < 0) {
- DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
- layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
- errno);
- } else {
- hashmap_[current_index_][fd] = fb_id;
+ int fd = input_buffer->planes[0].fd;
+ if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
+ AllocatedBufferInfo buf_info {};
+ DRMBuffer layout {};
+ buf_info.fd = layout.fd = fd;
+ buf_info.aligned_width = layout.width = input_buffer->width;
+ buf_info.aligned_height = layout.height = input_buffer->height;
+ buf_info.format = input_buffer->format;
+ GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
+ buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
+ &layout.num_planes);
+ uint32_t fb_id = 0;
+ int ret = master->CreateFbId(layout, &fb_id);
+ if (ret < 0) {
+ DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
+ layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
+ errno);
+ } else {
+ hashmap_[current_index_][fd] = fb_id;
+ }
}
}
- return;
}
void HWDeviceDRM::Registry::UnregisterNext() {
@@ -305,7 +298,6 @@
: hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
registry_(buffer_allocator) {
device_type_ = kDevicePrimary;
- disp_type_ = DRMDisplayType::PERIPHERAL;
device_name_ = "Peripheral Display";
hw_info_intf_ = hw_info_intf;
}
@@ -315,32 +307,36 @@
if (!default_mode_) {
DRMMaster *drm_master = {};
+ int dev_fd = -1;
DRMMaster::GetInstance(&drm_master);
- drm_master->GetHandle(&dev_fd_);
- DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd_, &drm_mgr_intf_);
- if (drm_mgr_intf_->RegisterDisplay(disp_type_, &token_)) {
- DLOGE("RegisterDisplay failed for display %d", disp_type_);
+ drm_master->GetHandle(&dev_fd);
+ DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
+ if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::PERIPHERAL, &token_)) {
+ DLOGE("RegisterDisplay failed");
return kErrorResources;
}
+
drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
InitializeConfigs();
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, ¤t_mode_);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET, token_.crtc_id, 1);
+
+ // TODO(user): Enable this and remove the one in SetupAtomic() onces underruns are fixed
+ // drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
// Commit to setup pipeline with mode, which then tells us the topology etc
-
- if (!deferred_initialize_) {
- if (drm_atomic_intf_->Commit(true /* synchronous */)) {
- DRM_LOGI("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id,
- token_.conn_id, device_name_);
- return kErrorResources;
- }
- // Reload connector info for updated info after 1st commit
-
- drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+ if (drm_atomic_intf_->Commit(true /* synchronous */)) {
+ DLOGE("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id, token_.conn_id,
+ device_name_);
+ return kErrorResources;
}
+
+ // Reload connector info for updated info after 1st commit
+ drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+ DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_);
}
+
PopulateDisplayAttributes();
PopulateHWPanelInfo();
UpdateMixerAttributes();
@@ -434,30 +430,23 @@
display_attributes_.x_pixels / 2;
}
- hw_panel_info_.partial_update = connector_info_.num_roi;
- hw_panel_info_.left_roi_count = UINT32(connector_info_.num_roi);
- hw_panel_info_.right_roi_count = UINT32(connector_info_.num_roi);
- hw_panel_info_.left_align = connector_info_.xstart;
- hw_panel_info_.top_align = connector_info_.ystart;
- hw_panel_info_.width_align = connector_info_.walign;
- hw_panel_info_.height_align = connector_info_.halign;
- hw_panel_info_.min_roi_width = connector_info_.wmin;
- hw_panel_info_.min_roi_height = connector_info_.hmin;
- hw_panel_info_.needs_roi_merge = connector_info_.roi_merge;
+ hw_panel_info_.partial_update = 0;
+ hw_panel_info_.left_align = 0;
+ hw_panel_info_.width_align = 0;
+ hw_panel_info_.top_align = 0;
+ hw_panel_info_.height_align = 0;
+ hw_panel_info_.min_roi_width = 0;
+ hw_panel_info_.min_roi_height = 0;
+ hw_panel_info_.needs_roi_merge = 0;
hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
hw_panel_info_.min_fps = 60;
hw_panel_info_.max_fps = 60;
hw_panel_info_.is_primary_panel = connector_info_.is_primary;
hw_panel_info_.is_pluggable = 0;
- // no supprt for 90 rotation only flips or 180 supported
- hw_panel_info_.panel_orientation.rotation = 0;
- hw_panel_info_.panel_orientation.flip_horizontal =
- (connector_info_.panel_orientation == DRMRotation::FLIP_H) ||
- (connector_info_.panel_orientation == DRMRotation::ROT_180);
- hw_panel_info_.panel_orientation.flip_vertical =
- (connector_info_.panel_orientation == DRMRotation::FLIP_V) ||
- (connector_info_.panel_orientation == DRMRotation::ROT_180);
+ if (!default_mode_) {
+ hw_panel_info_.needs_roi_merge = (connector_info_.topology == DRMTopology::DUAL_LM_MERGE);
+ }
GetHWDisplayPortAndMode();
GetHWPanelMaxBrightness();
@@ -574,35 +563,18 @@
DisplayError HWDeviceDRM::PowerOn() {
DTRACE_SCOPED();
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
- int ret = drm_atomic_intf_->Commit(false /* synchronous */);
- if (ret) {
- DLOGE("%s failed with error %d", __FUNCTION__, ret);
- return kErrorHardware;
- }
return kErrorNone;
}
DisplayError HWDeviceDRM::PowerOff() {
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
- int ret = drm_atomic_intf_->Commit(false /* synchronous */);
- if (ret) {
- DLOGE("%s failed with error %d", __FUNCTION__, ret);
- return kErrorHardware;
- }
return kErrorNone;
}
DisplayError HWDeviceDRM::Doze() {
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
return kErrorNone;
}
DisplayError HWDeviceDRM::DozeSuspend() {
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id,
- DRMPowerMode::DOZE_SUSPEND);
return kErrorNone;
}
@@ -618,34 +590,6 @@
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
- // TODO(user): Once destination scalar is enabled we can always send ROIs if driver allows
- if (hw_panel_info_.partial_update) {
- const int kNumMaxROIs = 4;
- DRMRect crtc_rects[kNumMaxROIs] = {{0, 0, mixer_attributes_.width, mixer_attributes_.height}};
- DRMRect conn_rects[kNumMaxROIs] = {{0, 0, display_attributes_.x_pixels,
- display_attributes_.y_pixels}};
-
- for (uint32_t i = 0; i < hw_layer_info.left_frame_roi.size(); i++) {
- auto &roi = hw_layer_info.left_frame_roi.at(i);
- // TODO(user): In multi PU, stitch ROIs vertically adjacent and upate plane destination
- crtc_rects[i].left = UINT32(roi.left);
- crtc_rects[i].right = UINT32(roi.right);
- crtc_rects[i].top = UINT32(roi.top);
- crtc_rects[i].bottom = UINT32(roi.bottom);
- // TODO(user): In Dest scaler + PU, populate from HWDestScaleInfo->panel_roi
- conn_rects[i].left = UINT32(roi.left);
- conn_rects[i].right = UINT32(roi.right);
- conn_rects[i].top = UINT32(roi.top);
- conn_rects[i].bottom = UINT32(roi.bottom);
- }
-
- uint32_t num_rects = std::max(1u, static_cast<uint32_t>(hw_layer_info.left_frame_roi.size()));
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id,
- num_rects, crtc_rects);
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id,
- num_rects, conn_rects);
- }
-
for (uint32_t i = 0; i < hw_layer_count; i++) {
Layer &layer = hw_layer_info.hw_layers.at(i);
LayerBuffer *input_buffer = &layer.input_buffer;
@@ -715,12 +659,8 @@
}
}
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, hw_layers->clock_hz);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, hw_layers->ab_bps);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, hw_layers->ib_bps);
-
- DLOGI_IF(kTagDriverConfig, "System: clock=%d Hz, ab=%llu Bps ib=%llu Bps", hw_layers->clock_hz,
- hw_layers->ab_bps, hw_layers->ib_bps);
+ // TODO(user): Remove this and enable the one in Init() onces underruns are fixed
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
}
}
@@ -811,7 +751,7 @@
int ret = drm_atomic_intf_->Commit(false /* synchronous */);
if (ret) {
- DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id);
+ DLOGE("%s failed with error %d", __FUNCTION__, ret);
return kErrorHardware;
}
@@ -887,6 +827,7 @@
DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
struct DRMPPFeatureInfo info = {};
+
for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) {
memset(&info, 0, sizeof(struct DRMPPFeatureInfo));
info.id = HWColorManagerDrm::ToDrmFeatureId(i);
@@ -929,7 +870,7 @@
}
DisplayError HWDeviceDRM::SetVSyncState(bool enable) {
- return kErrorNotSupported;
+ return kErrorNone;
}
void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {}
diff --git a/sdm845/sdm/libs/core/drm/hw_device_drm.h b/msm8909w_3100/sdm/libs/core/drm/hw_device_drm.h
similarity index 93%
copy from sdm845/sdm/libs/core/drm/hw_device_drm.h
copy to msm8909w_3100/sdm/libs/core/drm/hw_device_drm.h
index ad7a3e3..cc2ae7b 100644
--- a/sdm845/sdm/libs/core/drm/hw_device_drm.h
+++ b/msm8909w_3100/sdm/libs/core/drm/hw_device_drm.h
@@ -49,7 +49,7 @@
class HWDeviceDRM : public HWInterface {
public:
- HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ explicit HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
HWInfoInterface *hw_info_intf);
virtual ~HWDeviceDRM() {}
virtual DisplayError Init();
@@ -75,7 +75,6 @@
virtual DisplayError Flush();
virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
- // This API is no longer supported, expectation is to call the correct API on HWEvents
virtual DisplayError SetVSyncState(bool enable);
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
@@ -93,7 +92,6 @@
virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
- virtual void InitializeConfigs();
enum {
kHWEventVSync,
@@ -116,6 +114,7 @@
void ResetDisplayParams();
bool EnableHotPlugDetection(int enable);
void UpdateMixerAttributes();
+ void InitializeConfigs();
void SetBlending(const LayerBlending &source, sde_drm::DRMBlendType *target);
void SetSrcConfig(const LayerBuffer &input_buffer, uint32_t *config);
void SetRect(const LayerRect &source, sde_drm::DRMRect *target);
@@ -132,13 +131,11 @@
void UnregisterNext();
// Call on display disconnect to release all gem handles and fb_ids
void Clear();
- // Maps given fd to FB ID
- void MapBufferToFbId(LayerBuffer* buffer);
// Finds an fb_id corresponding to an fd in current map
uint32_t GetFbId(int fd);
private:
- static const int kCycleDelay = 3; // N cycle delay before destroy
+ static const int kCycleDelay = 1; // N cycle delay before destroy
// fd to fb_id map. fd is used as key only for a single draw cycle between
// prepare and commit. It should not be used for caching in future due to fd recycling
std::unordered_map<int, uint32_t> hashmap_[kCycleDelay] {};
@@ -146,30 +143,24 @@
BufferAllocator *buffer_allocator_ = {};
};
- protected:
- const char *device_name_ = {};
- bool deferred_initialize_ = false;
- sde_drm::DRMDisplayType disp_type_ = {};
- HWInfoInterface *hw_info_intf_ = {};
- BufferSyncHandler *buffer_sync_handler_ = {};
- int dev_fd_ = -1;
- Registry registry_;
- sde_drm::DRMDisplayToken token_ = {};
HWResourceInfo hw_resource_ = {};
HWPanelInfo hw_panel_info_ = {};
+ HWInfoInterface *hw_info_intf_ = {};
+ BufferSyncHandler *buffer_sync_handler_ = {};
HWDeviceType device_type_ = {};
+ const char *device_name_ = {};
+ bool synchronous_commit_ = false;
+ HWDisplayAttributes display_attributes_ = {};
+ HWMixerAttributes mixer_attributes_ = {};
sde_drm::DRMManagerInterface *drm_mgr_intf_ = {};
sde_drm::DRMAtomicReqInterface *drm_atomic_intf_ = {};
- sde_drm::DRMConnectorInfo connector_info_ = {};
+ sde_drm::DRMDisplayToken token_ = {};
drmModeModeInfo current_mode_ = {};
- HWDisplayAttributes display_attributes_ = {};
-
- private:
- bool synchronous_commit_ = false;
- HWMixerAttributes mixer_attributes_ = {};
bool default_mode_ = false;
+ sde_drm::DRMConnectorInfo connector_info_ = {};
std::string interface_str_ = "DSI";
HWScaleDRM *hw_scale_ = {};
+ Registry registry_;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/drm/hw_events_drm.cpp b/msm8909w_3100/sdm/libs/core/drm/hw_events_drm.cpp
similarity index 91%
copy from sdm845/sdm/libs/core/drm/hw_events_drm.cpp
copy to msm8909w_3100/sdm/libs/core/drm/hw_events_drm.cpp
index cea76fc..9c9023a 100644
--- a/sdm845/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/msm8909w_3100/sdm/libs/core/drm/hw_events_drm.cpp
@@ -81,7 +81,6 @@
Sys::pread_(poll_fds_[i].fd, data, kMaxStringLength, 0);
} break;
case HWEvent::IDLE_NOTIFY:
- case HWEvent::CEC_READ_MESSAGE:
case HWEvent::SHOW_BLANK_EVENT:
case HWEvent::THERMAL_LEVEL:
case HWEvent::IDLE_POWER_COLLAPSE:
@@ -103,9 +102,6 @@
case HWEvent::IDLE_NOTIFY:
event_data.event_parser = &HWEventsDRM::HandleIdleTimeout;
break;
- case HWEvent::CEC_READ_MESSAGE:
- event_data.event_parser = &HWEventsDRM::HandleCECMessage;
- break;
case HWEvent::EXIT:
event_data.event_parser = &HWEventsDRM::HandleThreadExit;
break;
@@ -160,30 +156,7 @@
DisplayError HWEventsDRM::Deinit() {
exit_threads_ = true;
Sys::pthread_cancel_(event_thread_);
- WakeUpEventThread();
- pthread_join(event_thread_, NULL);
- CloseFds();
- return kErrorNone;
-}
-
-DisplayError HWEventsDRM::SetEventState(HWEvent event, bool enable, void *arg) {
- switch (event) {
- case HWEvent::VSYNC:
- vsync_enabled_ = enable;
- if (enable) {
- WakeUpEventThread();
- }
- break;
- default:
- DLOGE("Event not supported");
- return kErrorNotSupported;
- }
-
- return kErrorNone;
-}
-
-void HWEventsDRM::WakeUpEventThread() {
for (uint32_t i = 0; i < event_data_list_.size(); i++) {
if (event_data_list_[i].event_type == HWEvent::EXIT) {
uint64_t exit_value = 1;
@@ -192,9 +165,13 @@
DLOGW("Error triggering exit fd (%d). write size = %d, error = %s", poll_fds_[i].fd,
write_size, strerror(errno));
}
- break;
}
}
+
+ pthread_join(event_thread_, NULL);
+ CloseFds();
+
+ return kErrorNone;
}
DisplayError HWEventsDRM::CloseFds() {
@@ -208,7 +185,6 @@
poll_fds_[i].fd = -1;
break;
case HWEvent::IDLE_NOTIFY:
- case HWEvent::CEC_READ_MESSAGE:
case HWEvent::SHOW_BLANK_EVENT:
case HWEvent::THERMAL_LEVEL:
case HWEvent::IDLE_POWER_COLLAPSE:
@@ -236,7 +212,7 @@
setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent);
while (!exit_threads_) {
- if (vsync_enabled_ && RegisterVSync() != kErrorNone) {
+ if (RegisterVSync() != kErrorNone) {
pthread_exit(0);
return nullptr;
}
@@ -260,7 +236,6 @@
}
break;
case HWEvent::IDLE_NOTIFY:
- case HWEvent::CEC_READ_MESSAGE:
case HWEvent::SHOW_BLANK_EVENT:
case HWEvent::THERMAL_LEVEL:
case HWEvent::IDLE_POWER_COLLAPSE:
@@ -316,10 +291,6 @@
event_handler_->IdleTimeout();
}
-void HWEventsDRM::HandleCECMessage(char *data) {
- event_handler_->CECMessage(data);
-}
-
void HWEventsDRM::HandleIdlePowerCollapse(char *data) {
event_handler_->IdlePowerCollapse();
}
diff --git a/sdm845/sdm/libs/core/drm/hw_events_drm.h b/msm8909w_3100/sdm/libs/core/drm/hw_events_drm.h
similarity index 94%
copy from sdm845/sdm/libs/core/drm/hw_events_drm.h
copy to msm8909w_3100/sdm/libs/core/drm/hw_events_drm.h
index 41050c7..f114b1f 100644
--- a/sdm845/sdm/libs/core/drm/hw_events_drm.h
+++ b/msm8909w_3100/sdm/libs/core/drm/hw_events_drm.h
@@ -48,7 +48,6 @@
virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
const vector<HWEvent> &event_list);
virtual DisplayError Deinit();
- virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr);
private:
static const int kMaxStringLength = 1024;
@@ -67,13 +66,11 @@
void *DisplayEventHandler();
void HandleVSync(char *data);
void HandleIdleTimeout(char *data);
- void HandleCECMessage(char *data);
void HandleThreadExit(char *data) {}
void HandleThermal(char *data) {}
void HandleBlank(char *data) {}
void HandleIdlePowerCollapse(char *data);
void PopulateHWEventData(const vector<HWEvent> &event_list);
- void WakeUpEventThread();
DisplayError SetEventParser();
DisplayError InitializePollFd();
DisplayError CloseFds();
@@ -86,7 +83,6 @@
std::string event_thread_name_ = "SDM_EventThread";
bool exit_threads_ = false;
uint32_t vsync_index_ = 0;
- bool vsync_enabled_ = true;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/core/drm/hw_info_drm.cpp b/msm8909w_3100/sdm/libs/core/drm/hw_info_drm.cpp
similarity index 92%
rename from sdm845/sdm/libs/core/drm/hw_info_drm.cpp
rename to msm8909w_3100/sdm/libs/core/drm/hw_info_drm.cpp
index 6258d73..f8c9125 100644
--- a/sdm845/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/msm8909w_3100/sdm/libs/core/drm/hw_info_drm.cpp
@@ -135,7 +135,7 @@
DisplayError HWInfoDRM::GetDynamicBWLimits(HWResourceInfo *hw_resource) {
HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
for (int index = 0; index < kBwModeMax; index++) {
- bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
+ bw_info->total_bw_limit[index] = UINT32(hw_resource->max_bandwidth_low);
bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
}
@@ -164,13 +164,14 @@
hw_resource->linear_factor = 1;
hw_resource->scale_factor = 1;
hw_resource->extra_fudge_factor = 2;
- hw_resource->amortizable_threshold = 25;
+ hw_resource->amortizable_threshold = 0;
hw_resource->system_overhead_lines = 0;
hw_resource->hw_dest_scalar_info.count = 0;
hw_resource->hw_dest_scalar_info.max_scale_up = 0;
hw_resource->hw_dest_scalar_info.max_input_width = 0;
hw_resource->hw_dest_scalar_info.max_output_width = 0;
hw_resource->is_src_split = true;
+ hw_resource->perf_calc = false;
hw_resource->has_dyn_bw_support = false;
hw_resource->has_qseed3 = false;
hw_resource->has_concurrent_writeback = false;
@@ -253,33 +254,6 @@
hw_resource->num_blending_stages = info.max_blend_stages;
hw_resource->smart_dma_rev = (info.smart_dma_rev == sde_drm::SmartDMARevision::V2) ?
SmartDMARevision::V2 : SmartDMARevision::V1;
- hw_resource->ib_fudge_factor = info.ib_fudge_factor;
- hw_resource->hw_dest_scalar_info.prefill_lines = info.dest_scale_prefill_lines;
- hw_resource->undersized_prefill_lines = info.undersized_prefill_lines;
- hw_resource->macrotile_factor = info.macrotile_prefill_lines;
- hw_resource->macrotile_nv12_factor = info.nv12_prefill_lines;
- hw_resource->linear_factor = info.linear_prefill_lines;
- hw_resource->scale_factor = info.downscale_prefill_lines;
- hw_resource->extra_fudge_factor = info.extra_prefill_lines;
- hw_resource->amortizable_threshold = info.amortized_threshold;
- hw_resource->max_bandwidth_low = info.max_bandwidth_low / kKiloUnit;
- hw_resource->max_bandwidth_high = info.max_bandwidth_high / kKiloUnit;
- hw_resource->max_sde_clk = info.max_sde_clk;
-
- std::vector<LayerBufferFormat> sdm_format;
- for (auto &it : info.comp_ratio_rt_map) {
- std::pair<uint32_t, uint64_t> drm_format = it.first;
- GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
- hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
- sdm_format.clear();
- }
-
- for (auto &it : info.comp_ratio_nrt_map) {
- std::pair<uint32_t, uint64_t> drm_format = it.first;
- GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
- hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
- sdm_format.clear();
- }
}
void HWInfoDRM::GetHWPlanesInfo(HWResourceInfo *hw_resource) {
@@ -331,13 +305,12 @@
hw_resource->max_scale_down = info.max_downscale;
hw_resource->max_scale_up = info.max_upscale;
hw_resource->has_decimation = info.max_horizontal_deci > 1 && info.max_vertical_deci > 1;
- hw_resource->max_pipe_bw = info.max_pipe_bandwidth / kKiloUnit;
}
void HWInfoDRM::PopulateSupportedFmts(HWSubBlockType sub_blk_type,
const sde_drm::DRMPlaneTypeInfo &info,
HWResourceInfo *hw_resource) {
- vector<LayerBufferFormat> sdm_formats = {};
+ vector<LayerBufferFormat> sdm_formats;
FormatsMap &fmts_map = hw_resource->supported_formats_map;
if (fmts_map.find(sub_blk_type) == fmts_map.end()) {
@@ -351,7 +324,7 @@
void HWInfoDRM::GetWBInfo(HWResourceInfo *hw_resource) {
HWSubBlockType sub_blk_type = kHWWBIntfOutput;
- vector<LayerBufferFormat> supported_sdm_formats = {};
+ vector<LayerBufferFormat> supported_sdm_formats;
sde_drm::DRMDisplayToken token;
// Fake register
diff --git a/sdm845/sdm/libs/core/drm/hw_info_drm.h b/msm8909w_3100/sdm/libs/core/drm/hw_info_drm.h
similarity index 98%
rename from sdm845/sdm/libs/core/drm/hw_info_drm.h
rename to msm8909w_3100/sdm/libs/core/drm/hw_info_drm.h
index 5d92c41..91829cb 100644
--- a/sdm845/sdm/libs/core/drm/hw_info_drm.h
+++ b/msm8909w_3100/sdm/libs/core/drm/hw_info_drm.h
@@ -71,8 +71,6 @@
// TODO(user): Read Mdss version from the driver
static const int kHWMdssVersion5 = 500; // MDSS_V5
static const int kMaxStringLength = 1024;
- static const int kKiloUnit = 1000;
-
static HWResourceInfo *hw_resource_;
};
diff --git a/sdm845/sdm/libs/core/drm/hw_scale_drm.cpp b/msm8909w_3100/sdm/libs/core/drm/hw_scale_drm.cpp
similarity index 100%
copy from sdm845/sdm/libs/core/drm/hw_scale_drm.cpp
copy to msm8909w_3100/sdm/libs/core/drm/hw_scale_drm.cpp
diff --git a/sdm845/sdm/libs/core/drm/hw_scale_drm.h b/msm8909w_3100/sdm/libs/core/drm/hw_scale_drm.h
similarity index 100%
copy from sdm845/sdm/libs/core/drm/hw_scale_drm.h
copy to msm8909w_3100/sdm/libs/core/drm/hw_scale_drm.h
diff --git a/sdm845/sdm/libs/core/dump_impl.cpp b/msm8909w_3100/sdm/libs/core/dump_impl.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/dump_impl.cpp
rename to msm8909w_3100/sdm/libs/core/dump_impl.cpp
diff --git a/sdm845/sdm/libs/core/dump_impl.h b/msm8909w_3100/sdm/libs/core/dump_impl.h
similarity index 100%
rename from sdm845/sdm/libs/core/dump_impl.h
rename to msm8909w_3100/sdm/libs/core/dump_impl.h
diff --git a/sdm845/sdm/libs/core/fb/hw_color_manager.cpp b/msm8909w_3100/sdm/libs/core/fb/hw_color_manager.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_color_manager.cpp
rename to msm8909w_3100/sdm/libs/core/fb/hw_color_manager.cpp
diff --git a/sdm845/sdm/libs/core/fb/hw_color_manager.h b/msm8909w_3100/sdm/libs/core/fb/hw_color_manager.h
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_color_manager.h
rename to msm8909w_3100/sdm/libs/core/fb/hw_color_manager.h
diff --git a/sdm845/sdm/libs/core/fb/hw_device.cpp b/msm8909w_3100/sdm/libs/core/fb/hw_device.cpp
similarity index 98%
rename from sdm845/sdm/libs/core/fb/hw_device.cpp
rename to msm8909w_3100/sdm/libs/core/fb/hw_device.cpp
index 773845b..5cfdf45 100644
--- a/sdm845/sdm/libs/core/fb/hw_device.cpp
+++ b/msm8909w_3100/sdm/libs/core/fb/hw_device.cpp
@@ -208,6 +208,7 @@
HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
bool is_rotator_used = (hw_rotator_session->hw_block_count != 0);
+ bool is_cursor_pipe_used = (hw_layer_info.use_hw_cursor & layer.flags.cursor);
for (uint32_t count = 0; count < 2; count++) {
HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
@@ -246,7 +247,7 @@
#endif
SetRect(pipe_info->src_roi, &mdp_layer.src_rect);
SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
- SetMDPFlags(&layer, is_rotator_used, hw_layer_info.async_cursor_updates, &mdp_layer.flags);
+ SetMDPFlags(&layer, is_rotator_used, is_cursor_pipe_used, &mdp_layer.flags);
SetCSC(layer.input_buffer.color_metadata, &mdp_layer.color_space);
if (pipe_info->flags & kIGC) {
SetIGC(&layer.input_buffer, mdp_layer_count);
@@ -709,7 +710,7 @@
}
void HWDevice::SetMDPFlags(const Layer *layer, const bool &is_rotator_used,
- bool async_cursor_updates, uint32_t *mdp_flags) {
+ bool is_cursor_pipe_used, uint32_t *mdp_flags) {
const LayerBuffer &input_buffer = layer->input_buffer;
// Flips will be taken care by rotator, if layer uses rotator for downscale/rotation. So ignore
@@ -742,7 +743,7 @@
*mdp_flags |= MDP_LAYER_SOLID_FILL;
}
- if (layer->flags.cursor && async_cursor_updates) {
+ if (hw_panel_info_.mode != kModeCommand && layer->flags.cursor && is_cursor_pipe_used) {
// command mode panels does not support async position update
*mdp_flags |= MDP_LAYER_ASYNC;
}
@@ -1141,8 +1142,8 @@
async_layer.pipe_ndx = left_pipe->pipe_id;
async_layer.src.x = UINT32(left_pipe->src_roi.left);
async_layer.src.y = UINT32(left_pipe->src_roi.top);
- async_layer.dst.x = UINT32(x);
- async_layer.dst.y = UINT32(y);
+ async_layer.dst.x = UINT32(left_pipe->dst_roi.left);
+ async_layer.dst.y = UINT32(left_pipe->dst_roi.top);
mdp_position_update pos_update = {};
pos_update.input_layer_cnt = 1;
diff --git a/sdm845/sdm/libs/core/fb/hw_device.h b/msm8909w_3100/sdm/libs/core/fb/hw_device.h
similarity index 98%
copy from sdm845/sdm/libs/core/fb/hw_device.h
copy to msm8909w_3100/sdm/libs/core/fb/hw_device.h
index 2eea87b..374df56 100644
--- a/sdm845/sdm/libs/core/fb/hw_device.h
+++ b/msm8909w_3100/sdm/libs/core/fb/hw_device.h
@@ -116,7 +116,7 @@
void SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target);
void SetRect(const LayerRect &source, mdp_rect *target);
void SetMDPFlags(const Layer *layer, const bool &is_rotator_used,
- bool async_cursor_updates, uint32_t *mdp_flags);
+ bool is_cursor_pipe_used, uint32_t *mdp_flags);
// Retrieves HW FrameBuffer Node Index
int GetFBNodeIndex(HWDeviceType device_type);
// Populates HWPanelInfo based on node index
diff --git a/sdm845/sdm/libs/core/fb/hw_events.cpp b/msm8909w_3100/sdm/libs/core/fb/hw_events.cpp
similarity index 95%
copy from sdm845/sdm/libs/core/fb/hw_events.cpp
copy to msm8909w_3100/sdm/libs/core/fb/hw_events.cpp
index c0467f9..52a8011 100644
--- a/sdm845/sdm/libs/core/fb/hw_events.cpp
+++ b/msm8909w_3100/sdm/libs/core/fb/hw_events.cpp
@@ -89,9 +89,6 @@
case HWEvent::IDLE_NOTIFY:
event_data->event_parser = &HWEvents::HandleIdleTimeout;
break;
- case HWEvent::CEC_READ_MESSAGE:
- event_data->event_parser = &HWEvents::HandleCECMessage;
- break;
case HWEvent::EXIT:
event_data->event_parser = &HWEvents::HandleThreadExit;
break;
@@ -134,8 +131,7 @@
event_thread_name_ += " - " + std::to_string(fb_num_);
map_event_to_node_ = {{HWEvent::VSYNC, "vsync_event"}, {HWEvent::EXIT, "thread_exit"},
{HWEvent::IDLE_NOTIFY, "idle_notify"}, {HWEvent::SHOW_BLANK_EVENT, "show_blank_event"},
- {HWEvent::CEC_READ_MESSAGE, "cec/rd_msg"}, {HWEvent::THERMAL_LEVEL, "msm_fb_thermal_level"},
- {HWEvent::IDLE_POWER_COLLAPSE, "idle_power_collapse"}};
+ {HWEvent::THERMAL_LEVEL, "msm_fb_thermal_level"}, {HWEvent::IDLE_POWER_COLLAPSE, "idle_power_collapse"}};
PopulateHWEventData();
@@ -234,10 +230,6 @@
event_handler_->ThermalEvent(thermal_level);
}
-void HWEvents::HandleCECMessage(char *data) {
- event_handler_->CECMessage(data);
-}
-
void HWEvents::HandleIdlePowerCollapse(char *data) {
event_handler_->IdlePowerCollapse();
}
diff --git a/sdm845/sdm/libs/core/fb/hw_events.h b/msm8909w_3100/sdm/libs/core/fb/hw_events.h
similarity index 94%
copy from sdm845/sdm/libs/core/fb/hw_events.h
copy to msm8909w_3100/sdm/libs/core/fb/hw_events.h
index 3d9cec8..b4607a8 100644
--- a/sdm845/sdm/libs/core/fb/hw_events.h
+++ b/msm8909w_3100/sdm/libs/core/fb/hw_events.h
@@ -44,9 +44,6 @@
virtual DisplayError Init(int fb_num, HWEventHandler *event_handler,
const vector<HWEvent> &event_list);
virtual DisplayError Deinit();
- virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) {
- return kErrorNotSupported;
- }
private:
static const int kMaxStringLength = 1024;
@@ -64,7 +61,6 @@
void HandleBlank(char *data) { }
void HandleIdleTimeout(char *data);
void HandleThermal(char *data);
- void HandleCECMessage(char *data);
void HandleThreadExit(char *data) { }
void HandleIdlePowerCollapse(char *data);
void PopulateHWEventData();
diff --git a/sdm845/sdm/libs/core/fb/hw_hdmi.cpp b/msm8909w_3100/sdm/libs/core/fb/hw_hdmi.cpp
similarity index 98%
rename from sdm845/sdm/libs/core/fb/hw_hdmi.cpp
rename to msm8909w_3100/sdm/libs/core/fb/hw_hdmi.cpp
index 334a043..60801c5 100644
--- a/sdm845/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/msm8909w_3100/sdm/libs/core/fb/hw_hdmi.cpp
@@ -176,6 +176,18 @@
info->grayscale = V4L2_PIX_FMT_NV12;
}
+ if (!mode->active_low_h) {
+ info->sync |= (uint32_t)FB_SYNC_HOR_HIGH_ACT;
+ } else {
+ info->sync &= (uint32_t)~FB_SYNC_HOR_HIGH_ACT;
+ }
+
+ if (!mode->active_low_v) {
+ info->sync |= (uint32_t)FB_SYNC_VERT_HIGH_ACT;
+ } else {
+ info->sync &= (uint32_t)~FB_SYNC_VERT_HIGH_ACT;
+ }
+
return true;
}
diff --git a/sdm845/sdm/libs/core/fb/hw_hdmi.h b/msm8909w_3100/sdm/libs/core/fb/hw_hdmi.h
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_hdmi.h
rename to msm8909w_3100/sdm/libs/core/fb/hw_hdmi.h
diff --git a/sdm845/sdm/libs/core/fb/hw_info.cpp b/msm8909w_3100/sdm/libs/core/fb/hw_info.cpp
similarity index 97%
rename from sdm845/sdm/libs/core/fb/hw_info.cpp
rename to msm8909w_3100/sdm/libs/core/fb/hw_info.cpp
index f2a13e3..0623183 100644
--- a/sdm845/sdm/libs/core/fb/hw_info.cpp
+++ b/msm8909w_3100/sdm/libs/core/fb/hw_info.cpp
@@ -95,7 +95,7 @@
HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
for (int index = 0; index < kBwModeMax; index++) {
- bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
+ bw_info->total_bw_limit[index] = UINT32(hw_resource->max_bandwidth_low);
bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
}
@@ -169,9 +169,9 @@
} else if (!strncmp(tokens[0], "max_upscale_ratio", strlen("max_upscale_ratio"))) {
hw_resource_->max_scale_up = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_bandwidth_low", strlen("max_bandwidth_low"))) {
- hw_resource_->max_bandwidth_low = std::stoull(tokens[1]);
+ hw_resource_->max_bandwidth_low = UINT64(atol(tokens[1]));
} else if (!strncmp(tokens[0], "max_bandwidth_high", strlen("max_bandwidth_high"))) {
- hw_resource_->max_bandwidth_high = std::stoull(tokens[1]);
+ hw_resource_->max_bandwidth_high = UINT64(atol(tokens[1]));
} else if (!strncmp(tokens[0], "max_mixer_width", strlen("max_mixer_width"))) {
hw_resource_->max_mixer_width = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_pipe_width", strlen("max_pipe_width"))) {
@@ -179,7 +179,7 @@
} else if (!strncmp(tokens[0], "max_cursor_size", strlen("max_cursor_size"))) {
hw_resource_->max_cursor_size = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_pipe_bw", strlen("max_pipe_bw"))) {
- hw_resource_->max_pipe_bw = std::stoull(tokens[1]);
+ hw_resource_->max_pipe_bw = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_mdp_clk", strlen("max_mdp_clk"))) {
hw_resource_->max_sde_clk = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "clk_fudge_factor", strlen("clk_fudge_factor"))) {
@@ -224,6 +224,8 @@
hw_resource_->is_src_split = true;
} else if (!strncmp(tokens[i], "non_scalar_rgb", strlen("non_scalar_rgb"))) {
hw_resource_->has_non_scalar_rgb = true;
+ } else if (!strncmp(tokens[i], "perf_calc", strlen("perf_calc"))) {
+ hw_resource_->perf_calc = true;
} else if (!strncmp(tokens[i], "dynamic_bw_limit", strlen("dynamic_bw_limit"))) {
hw_resource_->has_dyn_bw_support = true;
} else if (!strncmp(tokens[i], "separate_rotator", strlen("separate_rotator"))) {
@@ -313,7 +315,8 @@
hw_resource_->macrotile_nv12_factor, hw_resource_->macrotile_factor,
hw_resource_->linear_factor, hw_resource_->scale_factor, hw_resource_->extra_fudge_factor);
- if (hw_resource_->separate_rotator || hw_resource_->num_dma_pipe) {
+ // Avoid rotator for MDP3 harware.
+ if ((hw_resource_->separate_rotator || hw_resource_->num_dma_pipe) && !hw_resource_->has_ppp) {
GetHWRotatorInfo(hw_resource_);
}
diff --git a/sdm845/sdm/libs/core/fb/hw_info.h b/msm8909w_3100/sdm/libs/core/fb/hw_info.h
similarity index 100%
copy from sdm845/sdm/libs/core/fb/hw_info.h
copy to msm8909w_3100/sdm/libs/core/fb/hw_info.h
diff --git a/sdm845/sdm/libs/core/fb/hw_primary.cpp b/msm8909w_3100/sdm/libs/core/fb/hw_primary.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_primary.cpp
rename to msm8909w_3100/sdm/libs/core/fb/hw_primary.cpp
diff --git a/sdm845/sdm/libs/core/fb/hw_primary.h b/msm8909w_3100/sdm/libs/core/fb/hw_primary.h
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_primary.h
rename to msm8909w_3100/sdm/libs/core/fb/hw_primary.h
diff --git a/sdm845/sdm/libs/core/fb/hw_scale.cpp b/msm8909w_3100/sdm/libs/core/fb/hw_scale.cpp
similarity index 100%
rename from sdm845/sdm/libs/core/fb/hw_scale.cpp
rename to msm8909w_3100/sdm/libs/core/fb/hw_scale.cpp
diff --git a/sdm845/sdm/libs/core/fb/hw_scale.h b/msm8909w_3100/sdm/libs/core/fb/hw_scale.h
similarity index 100%
copy from sdm845/sdm/libs/core/fb/hw_scale.h
copy to msm8909w_3100/sdm/libs/core/fb/hw_scale.h
diff --git a/sdm845/sdm/libs/core/fb/hw_virtual.cpp b/msm8909w_3100/sdm/libs/core/fb/hw_virtual.cpp
similarity index 100%
copy from sdm845/sdm/libs/core/fb/hw_virtual.cpp
copy to msm8909w_3100/sdm/libs/core/fb/hw_virtual.cpp
diff --git a/sdm845/sdm/libs/core/fb/hw_virtual.h b/msm8909w_3100/sdm/libs/core/fb/hw_virtual.h
similarity index 100%
copy from sdm845/sdm/libs/core/fb/hw_virtual.h
copy to msm8909w_3100/sdm/libs/core/fb/hw_virtual.h
diff --git a/sdm845/sdm/libs/core/hw_events_interface.cpp b/msm8909w_3100/sdm/libs/core/hw_events_interface.cpp
similarity index 100%
copy from sdm845/sdm/libs/core/hw_events_interface.cpp
copy to msm8909w_3100/sdm/libs/core/hw_events_interface.cpp
diff --git a/sdm845/sdm/libs/core/hw_events_interface.h b/msm8909w_3100/sdm/libs/core/hw_events_interface.h
similarity index 95%
copy from sdm845/sdm/libs/core/hw_events_interface.h
copy to msm8909w_3100/sdm/libs/core/hw_events_interface.h
index 482e077..17fb7df 100644
--- a/sdm845/sdm/libs/core/hw_events_interface.h
+++ b/msm8909w_3100/sdm/libs/core/hw_events_interface.h
@@ -38,7 +38,6 @@
VSYNC = 0,
EXIT,
IDLE_NOTIFY,
- CEC_READ_MESSAGE,
SHOW_BLANK_EVENT,
THERMAL_LEVEL,
IDLE_POWER_COLLAPSE,
@@ -49,7 +48,6 @@
virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
const std::vector<HWEvent> &event_list) = 0;
virtual DisplayError Deinit() = 0;
- virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) = 0;
static DisplayError Create(int display_type, HWEventHandler *event_handler,
const std::vector<HWEvent> &event_list, HWEventsInterface **intf);
diff --git a/sdm845/sdm/libs/core/hw_info_interface.cpp b/msm8909w_3100/sdm/libs/core/hw_info_interface.cpp
similarity index 100%
copy from sdm845/sdm/libs/core/hw_info_interface.cpp
copy to msm8909w_3100/sdm/libs/core/hw_info_interface.cpp
diff --git a/sdm845/sdm/libs/core/hw_info_interface.h b/msm8909w_3100/sdm/libs/core/hw_info_interface.h
similarity index 100%
copy from sdm845/sdm/libs/core/hw_info_interface.h
copy to msm8909w_3100/sdm/libs/core/hw_info_interface.h
diff --git a/sdm845/sdm/libs/core/hw_interface.cpp b/msm8909w_3100/sdm/libs/core/hw_interface.cpp
similarity index 93%
copy from sdm845/sdm/libs/core/hw_interface.cpp
copy to msm8909w_3100/sdm/libs/core/hw_interface.cpp
index a27c5f8..b5c9fe9 100644
--- a/sdm845/sdm/libs/core/hw_interface.cpp
+++ b/msm8909w_3100/sdm/libs/core/hw_interface.cpp
@@ -37,7 +37,6 @@
#include "fb/hw_virtual.h"
#ifdef COMPILE_DRM
#include "drm/hw_device_drm.h"
-#include "drm/hw_virtual_drm.h"
#endif
#define __CLASS__ "HWInterface"
@@ -70,11 +69,9 @@
break;
case kVirtual:
if (driver_type == DriverType::FB) {
- hw = new HWVirtual(buffer_sync_handler,hw_info_intf);
+ hw = new HWVirtual(buffer_sync_handler, hw_info_intf);
} else {
-#ifdef COMPILE_DRM
- hw = new HWVirtualDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
-#endif
+ return kErrorNotSupported;
}
break;
default:
diff --git a/sdm845/sdm/libs/core/hw_interface.h b/msm8909w_3100/sdm/libs/core/hw_interface.h
similarity index 98%
copy from sdm845/sdm/libs/core/hw_interface.h
copy to msm8909w_3100/sdm/libs/core/hw_interface.h
index 5dbeb11..312ad98 100644
--- a/sdm845/sdm/libs/core/hw_interface.h
+++ b/msm8909w_3100/sdm/libs/core/hw_interface.h
@@ -59,7 +59,6 @@
virtual DisplayError Blank(bool blank) = 0;
virtual void IdleTimeout() = 0;
virtual void ThermalEvent(int64_t thermal_level) = 0;
- virtual void CECMessage(char *message) = 0;
virtual void IdlePowerCollapse() = 0;
protected:
diff --git a/sdm845/sdm/libs/core/resource_default.cpp b/msm8909w_3100/sdm/libs/core/resource_default.cpp
similarity index 97%
copy from sdm845/sdm/libs/core/resource_default.cpp
copy to msm8909w_3100/sdm/libs/core/resource_default.cpp
index 2d74941..6a4f3e5 100644
--- a/sdm845/sdm/libs/core/resource_default.cpp
+++ b/msm8909w_3100/sdm/libs/core/resource_default.cpp
@@ -212,7 +212,7 @@
return kErrorNone;
}
-DisplayError ResourceDefault::Stop(Handle display_ctx) {
+DisplayError ResourceDefault::Stop(Handle display_ctx, HWLayers *hw_layers) {
locker_.Unlock();
return kErrorNone;
@@ -923,8 +923,14 @@
return kErrorNone;
}
-DisplayError ResourceDefault::ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
- int x, int y) {
+DisplayError ResourceDefault::ValidateCursorConfig(Handle display_ctx, const Layer *layer,
+ bool is_top) {
+ return kErrorNotSupported;
+}
+
+DisplayError ResourceDefault::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
+ int x, int y,
+ DisplayConfigVariableInfo *fb_config) {
return kErrorNotSupported;
}
diff --git a/sdm845/sdm/libs/core/resource_default.h b/msm8909w_3100/sdm/libs/core/resource_default.h
similarity index 96%
copy from sdm845/sdm/libs/core/resource_default.h
copy to msm8909w_3100/sdm/libs/core/resource_default.h
index f835410..a67eb09 100644
--- a/sdm845/sdm/libs/core/resource_default.h
+++ b/msm8909w_3100/sdm/libs/core/resource_default.h
@@ -50,7 +50,7 @@
const HWPanelInfo &hw_panel_info,
const HWMixerAttributes &mixer_attributes);
virtual DisplayError Start(Handle display_ctx);
- virtual DisplayError Stop(Handle display_ctx);
+ virtual DisplayError Stop(Handle display_ctx, HWLayers *hw_layers);
virtual DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers);
virtual DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
virtual DisplayError Commit(Handle display_ctx, HWLayers *hw_layers);
@@ -60,7 +60,8 @@
virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90,
BufferLayout layout, bool use_rotator_downscale);
DisplayError ValidateCursorConfig(Handle display_ctx, const Layer *layer, bool is_top);
- DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
+ DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y,
+ DisplayConfigVariableInfo *fb_config);
DisplayError SetMaxBandwidthMode(HWBwModes mode);
virtual DisplayError SetDetailEnhancerData(Handle display_ctx,
const DisplayDetailEnhancerData &de_data);
diff --git a/sdm845/sdm/libs/core/strategy.cpp b/msm8909w_3100/sdm/libs/core/strategy.cpp
similarity index 100%
copy from sdm845/sdm/libs/core/strategy.cpp
copy to msm8909w_3100/sdm/libs/core/strategy.cpp
diff --git a/sdm845/sdm/libs/core/strategy.h b/msm8909w_3100/sdm/libs/core/strategy.h
similarity index 100%
copy from sdm845/sdm/libs/core/strategy.h
copy to msm8909w_3100/sdm/libs/core/strategy.h
diff --git a/sdm845/sdm/libs/hwc/Android.mk b/msm8909w_3100/sdm/libs/hwc/Android.mk
similarity index 100%
copy from sdm845/sdm/libs/hwc/Android.mk
copy to msm8909w_3100/sdm/libs/hwc/Android.mk
diff --git a/sdm845/sdm/libs/hwc/blit_engine.h b/msm8909w_3100/sdm/libs/hwc/blit_engine.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/blit_engine.h
copy to msm8909w_3100/sdm/libs/hwc/blit_engine.h
diff --git a/sdm845/sdm/libs/hwc/blit_engine_c2d.cpp b/msm8909w_3100/sdm/libs/hwc/blit_engine_c2d.cpp
similarity index 100%
copy from sdm845/sdm/libs/hwc/blit_engine_c2d.cpp
copy to msm8909w_3100/sdm/libs/hwc/blit_engine_c2d.cpp
diff --git a/sdm845/sdm/libs/hwc/blit_engine_c2d.h b/msm8909w_3100/sdm/libs/hwc/blit_engine_c2d.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/blit_engine_c2d.h
copy to msm8909w_3100/sdm/libs/hwc/blit_engine_c2d.h
diff --git a/sdm845/sdm/libs/hwc/cpuhint.cpp b/msm8909w_3100/sdm/libs/hwc/cpuhint.cpp
similarity index 100%
rename from sdm845/sdm/libs/hwc/cpuhint.cpp
rename to msm8909w_3100/sdm/libs/hwc/cpuhint.cpp
diff --git a/sdm845/sdm/libs/hwc/cpuhint.h b/msm8909w_3100/sdm/libs/hwc/cpuhint.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/cpuhint.h
copy to msm8909w_3100/sdm/libs/hwc/cpuhint.h
diff --git a/sdm845/sdm/libs/hwc/hwc_buffer_allocator.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_buffer_allocator.cpp
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_buffer_allocator.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_buffer_allocator.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_buffer_allocator.h b/msm8909w_3100/sdm/libs/hwc/hwc_buffer_allocator.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_buffer_allocator.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_buffer_allocator.h
diff --git a/sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
similarity index 99%
rename from sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
rename to msm8909w_3100/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
index 784e91b..094f5bb 100644
--- a/sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_buffer_sync_handler.cpp
@@ -30,6 +30,7 @@
#include <sync/sync.h>
#include <utils/constants.h>
#include <utils/debug.h>
+#include <errno.h>
#include "hwc_debugger.h"
#include "hwc_buffer_sync_handler.h"
@@ -88,4 +89,3 @@
}
} // namespace sdm
-
diff --git a/sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.h b/msm8909w_3100/sdm/libs/hwc/hwc_buffer_sync_handler.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_buffer_sync_handler.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_buffer_sync_handler.h
diff --git a/sdm845/sdm/libs/hwc/hwc_color_manager.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_color_manager.cpp
similarity index 99%
copy from sdm845/sdm/libs/hwc/hwc_color_manager.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_color_manager.cpp
index 471ca49..a02f1ce 100644
--- a/sdm845/sdm/libs/hwc/hwc_color_manager.cpp
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_color_manager.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -424,7 +424,6 @@
PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
if (de_tuning_cfg_data->cfg_pending == true) {
if (!de_tuning_cfg_data->cfg_en) {
- de_data.override_flags = kOverrideDEEnable;
de_data.enable = 0;
} else {
de_data.override_flags = kOverrideDEEnable;
diff --git a/sdm845/sdm/libs/hwc/hwc_color_manager.h b/msm8909w_3100/sdm/libs/hwc/hwc_color_manager.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_color_manager.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_color_manager.h
diff --git a/sdm845/sdm/libs/hwc/hwc_debugger.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_debugger.cpp
similarity index 96%
rename from sdm845/sdm/libs/hwc/hwc_debugger.cpp
rename to msm8909w_3100/sdm/libs/hwc/hwc_debugger.cpp
index 0cc0501..84a77b1 100644
--- a/sdm845/sdm/libs/hwc/hwc_debugger.cpp
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_debugger.cpp
@@ -150,11 +150,9 @@
void HWCDebugHandler::BeginTrace(const char *class_name, const char *function_name,
const char *custom_string) {
- if (atrace_is_tag_enabled(ATRACE_TAG)) {
- char name[PATH_MAX] = {0};
- snprintf(name, sizeof(name), "%s::%s::%s", class_name, function_name, custom_string);
- atrace_begin(ATRACE_TAG, name);
- }
+ char name[PATH_MAX] = {0};
+ snprintf(name, sizeof(name), "%s::%s::%s", class_name, function_name, custom_string);
+ atrace_begin(ATRACE_TAG, name);
}
void HWCDebugHandler::EndTrace() {
diff --git a/sdm845/sdm/libs/hwc/hwc_debugger.h b/msm8909w_3100/sdm/libs/hwc/hwc_debugger.h
similarity index 95%
rename from sdm845/sdm/libs/hwc/hwc_debugger.h
rename to msm8909w_3100/sdm/libs/hwc/hwc_debugger.h
index 01319ab..50cd14b 100644
--- a/sdm845/sdm/libs/hwc/hwc_debugger.h
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_debugger.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -43,6 +43,7 @@
class HWCDebugHandler : public DebugHandler {
public:
static inline DebugHandler* Get() { return &debug_handler_; }
+ static const char* DumpDir() { return "/data/vendor/display"; }
static void DebugAll(bool enable, int verbose_level);
static void DebugResources(bool enable, int verbose_level);
diff --git a/sdm845/sdm/libs/hwc/hwc_display.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_display.cpp
similarity index 99%
copy from sdm845/sdm/libs/hwc/hwc_display.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_display.cpp
index 2c5c885..47915c7 100644
--- a/sdm845/sdm/libs/hwc/hwc_display.cpp
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_display.cpp
@@ -943,7 +943,7 @@
case kCompositionGPUTarget: *target = HWC_FRAMEBUFFER_TARGET; break;
case kCompositionGPU: *target = HWC_FRAMEBUFFER; break;
case kCompositionGPUS3D: *target = HWC_FRAMEBUFFER; break;
- case kCompositionCursor: *target = HWC_CURSOR_OVERLAY; break;
+ case kCompositionHWCursor: *target = HWC_CURSOR_OVERLAY; break;
default: *target = HWC_OVERLAY; break;
}
}
diff --git a/sdm845/sdm/libs/hwc/hwc_display.h b/msm8909w_3100/sdm/libs/hwc/hwc_display.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_display.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_display.h
diff --git a/sdm845/sdm/libs/hwc/hwc_display_external.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_display_external.cpp
similarity index 97%
copy from sdm845/sdm/libs/hwc/hwc_display_external.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_external.cpp
index da216f7..a535819 100644
--- a/sdm845/sdm/libs/hwc/hwc_display_external.cpp
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_display_external.cpp
@@ -137,11 +137,12 @@
bool one_video_updating_layer = SingleVideoLayerUpdating(UINT32(content_list->numHwLayers - 1));
uint32_t refresh_rate = GetOptimalRefreshRate(one_video_updating_layer);
- bool final_rate = force_refresh_rate_ ? true : false;
- error = display_intf_->SetRefreshRate(refresh_rate, final_rate);
- if (error == kErrorNone) {
- // On success, set current refresh rate to new refresh rate
- current_refresh_rate_ = refresh_rate;
+ if (current_refresh_rate_ != refresh_rate) {
+ error = display_intf_->SetRefreshRate(refresh_rate);
+ if (error == kErrorNone) {
+ // On success, set current refresh rate to new refresh rate
+ current_refresh_rate_ = refresh_rate;
+ }
}
status = PrepareLayerStack(content_list);
diff --git a/sdm845/sdm/libs/hwc/hwc_display_external.h b/msm8909w_3100/sdm/libs/hwc/hwc_display_external.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_display_external.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_external.h
diff --git a/sdm845/sdm/libs/hwc/hwc_display_external_test.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_display_external_test.cpp
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_display_external_test.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_external_test.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_display_external_test.h b/msm8909w_3100/sdm/libs/hwc/hwc_display_external_test.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_display_external_test.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_external_test.h
diff --git a/sdm845/sdm/libs/hwc/hwc_display_null.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_display_null.cpp
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_display_null.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_null.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_display_null.h b/msm8909w_3100/sdm/libs/hwc/hwc_display_null.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_display_null.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_null.h
diff --git a/sdm845/sdm/libs/hwc/hwc_display_primary.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_display_primary.cpp
similarity index 97%
copy from sdm845/sdm/libs/hwc/hwc_display_primary.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_primary.cpp
index 8d6f31b..ba351b5 100644
--- a/sdm845/sdm/libs/hwc/hwc_display_primary.cpp
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_display_primary.cpp
@@ -192,13 +192,21 @@
}
uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
- bool final_rate = force_refresh_rate_ ? true : false;
- error = display_intf_->SetRefreshRate(refresh_rate, final_rate);
+ // TODO(user): Need to read current refresh rate to avoid
+ // redundant calls to set refresh rate during idle fall back.
+ if ((current_refresh_rate_ != refresh_rate) || (handle_idle_timeout_)) {
+ error = display_intf_->SetRefreshRate(refresh_rate);
+ }
+
if (error == kErrorNone) {
// On success, set current refresh rate to new refresh rate
current_refresh_rate_ = refresh_rate;
}
+ if (handle_idle_timeout_) {
+ handle_idle_timeout_ = false;
+ }
+
if (content_list->numHwLayers <= 1) {
flush_ = true;
}
@@ -362,6 +370,8 @@
uint32_t HWCDisplayPrimary::GetOptimalRefreshRate(bool one_updating_layer) {
if (force_refresh_rate_) {
return force_refresh_rate_;
+ } else if (handle_idle_timeout_) {
+ return min_refresh_rate_;
} else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
return metadata_refresh_rate_;
}
@@ -378,6 +388,7 @@
}
hwc_procs->invalidate(hwc_procs);
+ handle_idle_timeout_ = true;
return error;
}
diff --git a/sdm845/sdm/libs/hwc/hwc_display_primary.h b/msm8909w_3100/sdm/libs/hwc/hwc_display_primary.h
similarity index 98%
copy from sdm845/sdm/libs/hwc/hwc_display_primary.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_primary.h
index e937980..8a2ff87 100644
--- a/sdm845/sdm/libs/hwc/hwc_display_primary.h
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_display_primary.h
@@ -69,6 +69,7 @@
BufferAllocator *buffer_allocator_ = nullptr;
CPUHint cpu_hint_;
+ bool handle_idle_timeout_ = false;
// Primary output buffer configuration
LayerBuffer output_buffer_ = {};
diff --git a/sdm845/sdm/libs/hwc/hwc_display_virtual.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_display_virtual.cpp
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_display_virtual.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_virtual.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_display_virtual.h b/msm8909w_3100/sdm/libs/hwc/hwc_display_virtual.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_display_virtual.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_display_virtual.h
diff --git a/sdm845/sdm/libs/hwc/hwc_session.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_session.cpp
similarity index 97%
copy from sdm845/sdm/libs/hwc/hwc_session.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_session.cpp
index 98e14ee..3159440 100644
--- a/sdm845/sdm/libs/hwc/hwc_session.cpp
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_session.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -289,7 +289,7 @@
}
if (hwc_session->need_invalidate_) {
- hwc_session->AsyncRefresh();
+ hwc_procs->invalidate(hwc_procs);
hwc_session->need_invalidate_ = false;
}
@@ -420,8 +420,6 @@
hwc_session->bw_mode_release_fd_ = dup(content_list->retireFenceFd);
}
- locker_.Signal();
-
// This is only indicative of how many times SurfaceFlinger posts
// frames to the display.
CALC_FPS();
@@ -695,14 +693,6 @@
return 0;
}
-static void PostRefresh(hwc_procs_t const *hwc_procs) {
- hwc_procs->invalidate(hwc_procs);
-}
-
-void HWCSession::AsyncRefresh() {
- future_ = std::async(PostRefresh, hwc_procs_);
-}
-
android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
SEQUENCE_WAIT_SCOPE_LOCK(locker_);
@@ -715,7 +705,7 @@
break;
case qService::IQService::SCREEN_REFRESH:
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case qService::IQService::SET_IDLE_TIMEOUT:
@@ -866,7 +856,7 @@
}
android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
+ android::Parcel *out) {
DisplayError error = kErrorNone;
int ret = 0;
uint32_t disp_id = UINT32(input_parcel->readInt32());
@@ -875,14 +865,14 @@
if (disp_id != HWC_DISPLAY_PRIMARY) {
DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
ret = -EINVAL;
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
DLOGE("primary display object is not instantiated");
ret = -EINVAL;
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
@@ -891,30 +881,31 @@
if (error == kErrorNone) {
if (!pending) {
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
} else if (error == kErrorNotSupported) {
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
} else {
ret = -EINVAL;
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
- AsyncRefresh();
+ // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
+ hwc_procs_->invalidate(hwc_procs_);
// Wait until partial update control is complete
ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
- output_parcel->writeInt32(ret);
+ out->writeInt32(ret);
return ret;
}
android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
+ android::Parcel *output_parcel) {
int config = input_parcel->readInt32();
int dpy = input_parcel->readInt32();
int error = android::BAD_VALUE;
@@ -926,7 +917,7 @@
if (hwc_display_[dpy]) {
error = hwc_display_[dpy]->SetActiveDisplayConfig(config);
if (error == 0) {
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
}
}
@@ -1018,7 +1009,7 @@
DisplayPort sdm_disp_port = kPortDefault;
int hwc_disp_port = qdutils::DISPLAY_PORT_DEFAULT;
- if (dpy > HWC_DISPLAY_VIRTUAL) {
+ if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
return android::BAD_VALUE;
}
@@ -1137,7 +1128,7 @@
HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault;
// trigger invalidate to apply new bw caps.
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
error = core_intf_->SetMaxBandwidthMode(mode);
if (error != kErrorNone) {
@@ -1334,7 +1325,7 @@
switch (pending_action.action) {
case kInvalidating:
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kEnterQDCMMode:
ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
@@ -1345,12 +1336,12 @@
case kApplySolidFill:
ret = color_mgr_->SetSolidFill(pending_action.params,
true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kDisableSolidFill:
ret = color_mgr_->SetSolidFill(pending_action.params,
false, hwc_display_[HWC_DISPLAY_PRIMARY]);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kSetPanelBrightness:
brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
@@ -1364,7 +1355,7 @@
case kEnableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params,
true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kDisableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params,
@@ -1373,7 +1364,7 @@
case kConfigureDetailedEnhancer:
ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
hwc_display_[HWC_DISPLAY_PRIMARY]);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kInvalidatingAndkSetPanelBrightness:
brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
@@ -1383,7 +1374,7 @@
}
if (HWC_DISPLAY_PRIMARY == display_id)
ret = hwc_display_[HWC_DISPLAY_PRIMARY]->CachePanelBrightness(*brightness_value);
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
break;
case kNoAction:
break;
@@ -1469,7 +1460,7 @@
if (panel_reset == 0) {
if (hwc_procs_) {
reset_panel_ = true;
- AsyncRefresh();
+ hwc_procs_->invalidate(hwc_procs_);
} else {
DLOGW("Ignore resetpanel - hwc_proc not registered");
}
@@ -1699,7 +1690,7 @@
android::Parcel *output_parcel) {
int dpy = input_parcel->readInt32();
- if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) {
+ if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
return android::BAD_VALUE;;
}
diff --git a/sdm845/sdm/libs/hwc/hwc_session.h b/msm8909w_3100/sdm/libs/hwc/hwc_session.h
similarity index 97%
copy from sdm845/sdm/libs/hwc/hwc_session.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_session.h
index ce21c46..1cd3e33 100644
--- a/sdm845/sdm/libs/hwc/hwc_session.h
+++ b/msm8909w_3100/sdm/libs/hwc/hwc_session.h
@@ -28,7 +28,6 @@
#include <hardware/hwcomposer.h>
#include <core/core_interface.h>
#include <utils/locker.h>
-#include <future> // NOLINT
#include "hwc_display_primary.h"
#include "hwc_display_external.h"
@@ -89,7 +88,6 @@
int GetVsyncPeriod(int disp);
int CreateExternalDisplay(int disp, uint32_t primary_width, uint32_t primary_height,
bool use_primary_res);
- void AsyncRefresh();
// QClient methods
virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
@@ -105,8 +103,7 @@
android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
- android::status_t ControlPartialUpdate(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
+ android::status_t ControlPartialUpdate(const android::Parcel *input_parcel, android::Parcel *out);
android::status_t OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
android::status_t SetPanelBrightness(const android::Parcel *input_parcel,
@@ -154,7 +151,6 @@
qService::QService *qservice_ = NULL;
bool is_hdmi_primary_ = false;
bool is_hdmi_yuv_ = false;
- std::future<void> future_;
std::bitset<HWC_NUM_DISPLAY_TYPES> connected_displays_; // Bit mask of connected displays
HWCSocketHandler socket_handler_;
Locker uevent_locker_;
diff --git a/sdm845/sdm/libs/hwc/hwc_socket_handler.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_socket_handler.cpp
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_socket_handler.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_socket_handler.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_socket_handler.h b/msm8909w_3100/sdm/libs/hwc/hwc_socket_handler.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_socket_handler.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_socket_handler.h
diff --git a/sdm845/sdm/libs/hwc/hwc_tonemapper.cpp b/msm8909w_3100/sdm/libs/hwc/hwc_tonemapper.cpp
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_tonemapper.cpp
copy to msm8909w_3100/sdm/libs/hwc/hwc_tonemapper.cpp
diff --git a/sdm845/sdm/libs/hwc/hwc_tonemapper.h b/msm8909w_3100/sdm/libs/hwc/hwc_tonemapper.h
similarity index 100%
copy from sdm845/sdm/libs/hwc/hwc_tonemapper.h
copy to msm8909w_3100/sdm/libs/hwc/hwc_tonemapper.h
diff --git a/sdm845/sdm/libs/hwc2/Android.mk b/msm8909w_3100/sdm/libs/hwc2/Android.mk
similarity index 80%
rename from sdm845/sdm/libs/hwc2/Android.mk
rename to msm8909w_3100/sdm/libs/hwc2/Android.mk
index 557b55f..200d5ed 100644
--- a/sdm845/sdm/libs/hwc2/Android.mk
+++ b/msm8909w_3100/sdm/libs/hwc2/Android.mk
@@ -15,11 +15,17 @@
-std=c++11 -fcolor-diagnostics\
-DLOG_TAG=\"SDM\" $(common_flags) \
-I $(display_top)/sdm/libs/hwc
+
+ifeq ($(TARGET_EXCLUDES_DISPLAY_PP), true)
+LOCAL_CFLAGS += -DEXCLUDE_DISPLAY_PP
+endif
LOCAL_CLANG := true
+# TODO: Remove libui after addressing gpu_tonemapper issues
LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware libhardware_legacy \
- libutils libcutils libsync libqdutils libqdMetaData libdl \
- libpowermanager libsdmutils libc++ liblog libgrallocutils \
+ libutils libcutils libsync libqdutils libqdMetaData libdl libdrmutils \
+ libsdmutils libc++ liblog libgrallocutils libdl \
+ vendor.display.config@1.0 libhidlbase libhidltransport \
libui libgpu_tonemapper
ifneq ($(TARGET_USES_GRALLOC1), true)
@@ -27,6 +33,7 @@
endif
LOCAL_SRC_FILES := hwc_session.cpp \
+ hwc_session_services.cpp \
hwc_display.cpp \
hwc_display_primary.cpp \
hwc_display_external.cpp \
@@ -38,6 +45,7 @@
hwc_callbacks.cpp \
../hwc/cpuhint.cpp \
../hwc/hwc_socket_handler.cpp \
+ display_null.cpp \
hwc_tonemapper.cpp
ifneq ($(TARGET_USES_GRALLOC1), true)
diff --git a/msm8909w_3100/sdm/libs/hwc2/display_null.cpp b/msm8909w_3100/sdm/libs/hwc2/display_null.cpp
new file mode 100644
index 0000000..16f4da6
--- /dev/null
+++ b/msm8909w_3100/sdm/libs/hwc2/display_null.cpp
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "display_null.h"
+
+#define __CLASS__ "DisplayNull"
+
+namespace sdm {
+
+DisplayError DisplayNull::Commit(LayerStack *layer_stack) {
+ for (Layer *layer : layer_stack->layers) {
+ if (layer->composition != kCompositionGPUTarget) {
+ layer->composition = kCompositionSDE;
+ layer->input_buffer.release_fence_fd = -1;
+ }
+ }
+ layer_stack->retire_fence_fd = -1;
+
+ return kErrorNone;
+}
+
+DisplayError DisplayNull::GetDisplayState(DisplayState *state) {
+ *state = state_;
+ return kErrorNone;
+}
+
+DisplayError DisplayNull::SetDisplayState(DisplayState state) {
+ state_ = state;
+ return kErrorNone;
+}
+
+DisplayError DisplayNull::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
+ fb_config_ = variable_info;
+ return kErrorNone;
+}
+
+DisplayError DisplayNull::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
+ *variable_info = fb_config_;
+ return kErrorNone;
+}
+
+} // namespace sdm
diff --git a/msm8909w_3100/sdm/libs/hwc2/display_null.h b/msm8909w_3100/sdm/libs/hwc2/display_null.h
new file mode 100644
index 0000000..540ddda
--- /dev/null
+++ b/msm8909w_3100/sdm/libs/hwc2/display_null.h
@@ -0,0 +1,107 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DISPLAY_NULL_H__
+#define __DISPLAY_NULL_H__
+
+#include <core/display_interface.h>
+#include <string>
+#include <vector>
+
+namespace sdm {
+
+#define MAKE_NO_OP(virtual_method_name) \
+ virtual DisplayError virtual_method_name { return kErrorNone; }
+
+class DisplayNull : public DisplayInterface {
+ public:
+ virtual ~DisplayNull() { }
+ virtual DisplayError Commit(LayerStack *layer_stack);
+ virtual DisplayError GetDisplayState(DisplayState *state);
+ virtual DisplayError SetDisplayState(DisplayState state);
+ virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info);
+ virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
+ virtual bool IsUnderscanSupported() { return true; }
+ virtual void SetIdleTimeoutMs(uint32_t active_ms) { }
+ virtual bool IsPrimaryDisplay() { return true; }
+
+ void SetActive(bool active) {
+ active_ = active;
+ }
+
+ bool IsActive() {
+ return active_;
+ }
+
+ MAKE_NO_OP(Prepare(LayerStack *))
+ MAKE_NO_OP(Flush())
+ MAKE_NO_OP(GetNumVariableInfoConfigs(uint32_t *))
+ MAKE_NO_OP(GetConfig(uint32_t, DisplayConfigVariableInfo *))
+ MAKE_NO_OP(GetConfig(DisplayConfigFixedInfo *))
+ MAKE_NO_OP(GetActiveConfig(uint32_t *))
+ MAKE_NO_OP(GetVSyncState(bool *))
+ MAKE_NO_OP(SetActiveConfig(uint32_t))
+ MAKE_NO_OP(SetActiveConfig(DisplayConfigVariableInfo *))
+ MAKE_NO_OP(SetMaxMixerStages(uint32_t))
+ MAKE_NO_OP(ControlPartialUpdate(bool, uint32_t *))
+ MAKE_NO_OP(DisablePartialUpdateOneFrame())
+ MAKE_NO_OP(SetDisplayMode(uint32_t))
+ MAKE_NO_OP(SetPanelBrightness(int))
+ MAKE_NO_OP(CachePanelBrightness(int))
+ MAKE_NO_OP(OnMinHdcpEncryptionLevelChange(uint32_t))
+ MAKE_NO_OP(ColorSVCRequestRoute(const PPDisplayAPIPayload &, PPDisplayAPIPayload *,
+ PPPendingParams *))
+ MAKE_NO_OP(GetColorModeCount(uint32_t *))
+ MAKE_NO_OP(GetColorModes(uint32_t *, std::vector<std::string> *))
+ MAKE_NO_OP(GetColorModeAttr(const std::string &, AttrVal *))
+ MAKE_NO_OP(SetColorMode(const std::string &))
+ MAKE_NO_OP(SetColorModeById(int32_t))
+ MAKE_NO_OP(SetColorTransform(const uint32_t, const double *))
+ MAKE_NO_OP(GetDefaultColorMode(std::string *))
+ MAKE_NO_OP(ApplyDefaultDisplayMode())
+ MAKE_NO_OP(SetCursorPosition(int, int))
+ MAKE_NO_OP(GetRefreshRateRange(uint32_t *, uint32_t *))
+ MAKE_NO_OP(SetRefreshRate(uint32_t))
+ MAKE_NO_OP(GetPanelBrightness(int *))
+ MAKE_NO_OP(SetVSyncState(bool))
+ MAKE_NO_OP(SetMixerResolution(uint32_t, uint32_t))
+ MAKE_NO_OP(GetMixerResolution(uint32_t *, uint32_t *))
+ MAKE_NO_OP(SetDetailEnhancerData(const DisplayDetailEnhancerData &))
+ MAKE_NO_OP(GetDisplayPort(DisplayPort *))
+ MAKE_NO_OP(SetCompositionState(LayerComposition, bool))
+
+ private:
+ bool active_ = false;
+ DisplayState state_ = kStateOff;
+ DisplayConfigVariableInfo fb_config_ = {};
+};
+
+} // namespace sdm
+
+#endif // __DISPLAY_NULL_H__
diff --git a/sdm845/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_buffer_allocator.cpp
similarity index 91%
rename from sdm845/sdm/libs/hwc2/hwc_buffer_allocator.cpp
rename to msm8909w_3100/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index 3c8d460..35a2b43 100644
--- a/sdm845/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -48,10 +48,14 @@
} else {
gralloc1_open(module_, &gralloc_device_);
}
- ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
- gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
- Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
- gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
+ if (gralloc_device_ != nullptr) {
+ ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
+ gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
+ Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
+ gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
+ Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>(
+ gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK));
+ }
}
HWCBufferAllocator::~HWCBufferAllocator() {
@@ -133,6 +137,9 @@
if (alloc_type & GRALLOC_USAGE_HW_FB) {
consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
}
+ if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
+ producer_usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ }
Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format,
producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled);
@@ -354,4 +361,21 @@
return kErrorNone;
}
+DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) {
+ void* buffer_ptr = NULL;
+ const gralloc1_rect_t accessRegion = {
+ .left = 0,
+ .top = 0,
+ .width = 0,
+ .height = 0
+ };
+ Lock_(gralloc_device_, handle, GRALLOC1_PRODUCER_USAGE_CPU_READ, GRALLOC1_CONSUMER_USAGE_NONE,
+ &accessRegion, &buffer_ptr, acquire_fence);
+ if (!buffer_ptr) {
+ return kErrorUndefined;
+ }
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_buffer_allocator.h b/msm8909w_3100/sdm/libs/hwc2/hwc_buffer_allocator.h
similarity index 96%
rename from sdm845/sdm/libs/hwc2/hwc_buffer_allocator.h
rename to msm8909w_3100/sdm/libs/hwc2/hwc_buffer_allocator.h
index d574401..925edce 100644
--- a/sdm845/sdm/libs/hwc2/hwc_buffer_allocator.h
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_buffer_allocator.h
@@ -61,12 +61,14 @@
uint32_t stride[4], uint32_t offset[4],
uint32_t *num_planes);
int SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags);
+ DisplayError MapBuffer(const private_handle_t *handle, int acquire_fence);
private:
gralloc1_device_t *gralloc_device_ = nullptr;
const hw_module_t *module_;
GRALLOC1_PFN_RELEASE ReleaseBuffer_ = nullptr;
GRALLOC1_PFN_PERFORM Perform_ = nullptr;
+ GRALLOC1_PFN_LOCK Lock_ = nullptr;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_callbacks.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_callbacks.cpp
similarity index 78%
copy from sdm845/sdm/libs/hwc2/hwc_callbacks.cpp
copy to msm8909w_3100/sdm/libs/hwc2/hwc_callbacks.cpp
index 48ae398..3be3bf6 100644
--- a/sdm845/sdm/libs/hwc2/hwc_callbacks.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_callbacks.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -34,22 +34,28 @@
namespace sdm {
-void HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
- if (hotplug_) {
- hotplug_(hotplug_data_, display, INT32(state));
+HWC2::Error HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
+ if (!hotplug_) {
+ return HWC2::Error::NoResources;
}
+ hotplug_(hotplug_data_, display, INT32(state));
+ return HWC2::Error::None;
}
-void HWCCallbacks::Refresh(hwc2_display_t display) {
- if (refresh_) {
- refresh_(refresh_data_, display);
+HWC2::Error HWCCallbacks::Refresh(hwc2_display_t display) {
+ if (!refresh_) {
+ return HWC2::Error::NoResources;
}
+ refresh_(refresh_data_, display);
+ return HWC2::Error::None;
}
-void HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
- if (vsync_) {
- vsync_(vsync_data_, display, timestamp);
+HWC2::Error HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
+ if (!vsync_) {
+ return HWC2::Error::NoResources;
}
+ vsync_(vsync_data_, display, timestamp);
+ return HWC2::Error::None;
}
HWC2::Error HWCCallbacks::Register(HWC2::Callback descriptor, hwc2_callback_data_t callback_data,
diff --git a/sdm845/sdm/libs/hwc2/hwc_callbacks.h b/msm8909w_3100/sdm/libs/hwc2/hwc_callbacks.h
similarity index 92%
copy from sdm845/sdm/libs/hwc2/hwc_callbacks.h
copy to msm8909w_3100/sdm/libs/hwc2/hwc_callbacks.h
index 015bf5d..d3f4e52 100644
--- a/sdm845/sdm/libs/hwc2/hwc_callbacks.h
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_callbacks.h
@@ -40,9 +40,9 @@
class HWCCallbacks {
public:
- void Hotplug(hwc2_display_t display, HWC2::Connection state);
- void Refresh(hwc2_display_t display);
- void Vsync(hwc2_display_t display, int64_t timestamp);
+ HWC2::Error Hotplug(hwc2_display_t display, HWC2::Connection state);
+ HWC2::Error Refresh(hwc2_display_t display);
+ HWC2::Error Vsync(hwc2_display_t display, int64_t timestamp);
HWC2::Error Register(HWC2::Callback, hwc2_callback_data_t callback_data,
hwc2_function_pointer_t pointer);
diff --git a/sdm845/sdm/libs/hwc2/hwc_color_manager.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_color_manager.cpp
similarity index 91%
copy from sdm845/sdm/libs/hwc2/hwc_color_manager.cpp
copy to msm8909w_3100/sdm/libs/hwc2/hwc_color_manager.cpp
index 9f336a0..163e2dd 100644
--- a/sdm845/sdm/libs/hwc2/hwc_color_manager.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_color_manager.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,7 +28,6 @@
*/
#include <dlfcn.h>
-#include <powermanager/IPowerManager.h>
#include <cutils/sockets.h>
#include <cutils/native_handle.h>
#include <utils/String16.h>
@@ -235,7 +234,7 @@
return -EFAULT;
} else {
frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer);
- frame_capture_data->buffer_stride = buffer_info.buffer_config.width;
+ frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.stride;
frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size;
}
ret = hwc_display->FrameCaptureAsync(buffer_info, 1);
@@ -272,7 +271,6 @@
PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
if (de_tuning_cfg_data->cfg_pending == true) {
if (!de_tuning_cfg_data->cfg_en) {
- de_data.override_flags = kOverrideDEEnable;
de_data.enable = 0;
} else {
de_data.override_flags = kOverrideDEEnable;
@@ -386,17 +384,6 @@
// retrieve system GPU idle timeout value for later to recover.
mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs());
-
- // acquire the binder handle to Android system PowerManager for later use.
- android::sp<android::IBinder> binder =
- android::defaultServiceManager()->checkService(android::String16("power"));
- if (binder == NULL) {
- DLOGW("Application can't connect to power manager service");
- delete mode_mgr;
- mode_mgr = NULL;
- } else {
- mode_mgr->power_mgr_ = android::interface_cast<android::IPowerManager>(binder);
- }
}
return mode_mgr;
@@ -407,30 +394,6 @@
::close(socket_fd_);
}
-int HWCQDCMModeManager::AcquireAndroidWakeLock(bool enable) {
- int ret = 0;
-
- if (enable) {
- if (wakelock_token_ == NULL) {
- android::sp<android::IBinder> binder = new android::BBinder();
- android::status_t status = power_mgr_->acquireWakeLock(
- (kFullWakeLock | kAcquireCauseWakeup | kONAfterRelease), binder,
- android::String16(kTagName), android::String16(kPackageName));
- if (status == android::NO_ERROR) {
- wakelock_token_ = binder;
- }
- }
- } else {
- if (wakelock_token_ != NULL && power_mgr_ != NULL) {
- power_mgr_->releaseWakeLock(wakelock_token_, 0);
- wakelock_token_.clear();
- wakelock_token_ = NULL;
- }
- }
-
- return ret;
-}
-
int HWCQDCMModeManager::EnableActiveFeatures(bool enable,
const HWCQDCMModeManager::ActiveFeatureCMD &cmds,
bool *was_running) {
@@ -486,7 +449,6 @@
ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature],
&cabl_was_running_);
- ret = AcquireAndroidWakeLock(enable);
// if enter QDCM mode, disable GPU fallback idle timeout.
if (hwc_display) {
@@ -497,4 +459,4 @@
return ret;
}
-} // namespace sdm
+} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_color_manager.h b/msm8909w_3100/sdm/libs/hwc2/hwc_color_manager.h
similarity index 97%
copy from sdm845/sdm/libs/hwc2/hwc_color_manager.h
copy to msm8909w_3100/sdm/libs/hwc2/hwc_color_manager.h
index 62d5535..f88a5bb 100644
--- a/sdm845/sdm/libs/hwc2/hwc_color_manager.h
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_color_manager.h
@@ -32,7 +32,6 @@
#include <stdlib.h>
#include <binder/Parcel.h>
-#include <powermanager/IPowerManager.h>
#include <binder/BinderService.h>
#include <core/sdm_types.h>
#include <utils/locker.h>
@@ -94,7 +93,6 @@
bool cabl_was_running_ = false;
int socket_fd_ = -1;
android::sp<android::IBinder> wakelock_token_ = NULL;
- android::sp<android::IPowerManager> power_mgr_ = NULL;
uint32_t entry_timeout_ = 0;
static const char *const kSocketName;
static const char *const kTagName;
diff --git a/sdm845/sdm/libs/hwc2/hwc_display.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_display.cpp
similarity index 92%
rename from sdm845/sdm/libs/hwc2/hwc_display.cpp
rename to msm8909w_3100/sdm/libs/hwc2/hwc_display.cpp
index 4f623ce..2b87d78 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_display.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -54,6 +54,8 @@
namespace sdm {
+std::bitset<kDisplayMax> HWCDisplay::validated_ = 0;
+
// This weight function is needed because the color primaries are not sorted by gamut size
static ColorPrimaries WidestPrimaries(ColorPrimaries p1, ColorPrimaries p2) {
int weight = 10;
@@ -87,8 +89,11 @@
uint32_t HWCColorMode::GetColorModeCount() {
uint32_t count = UINT32(color_mode_transform_map_.size());
DLOGI("Supported color mode count = %d", count);
-
+#ifdef EXCLUDE_DISPLAY_PP
+ return count;
+#else
return std::max(1U, count);
+#endif
}
HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
@@ -104,10 +109,14 @@
HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
// first mode in 2D matrix is the mode (identity)
- if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
+ if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_P3) {
DLOGE("Could not find mode: %d", mode);
return HWC2::Error::BadParameter;
}
+ if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
+ return HWC2::Error::Unsupported;
+ }
+
auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
if (status != HWC2::Error::None) {
DLOGE("failed for mode = %d", mode);
@@ -116,17 +125,9 @@
return status;
}
-HWC2::Error HWCColorMode::SetColorModeById(int32_t color_mode_id) {
- DLOGI("Applying mode: %d", color_mode_id);
- DisplayError error = display_intf_->SetColorModeById(color_mode_id);
- if (error != kErrorNone) {
- return HWC2::Error::BadParameter;
- }
- return HWC2::Error::None;
-}
-
HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
- if (!matrix) {
+ if (!matrix || (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
+ hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)) {
return HWC2::Error::BadParameter;
}
@@ -162,7 +163,7 @@
// if the mode count is 1, then only native mode is supported, so just apply matrix w/o
// setting mode
- if (color_mode_transform_map_.size() > 1U) {
+ if (color_mode_transform_map_.size() > 1U && current_color_mode_ != mode) {
color_mode_transform = color_mode_transform_map_[mode][transform_hint];
DisplayError error = display_intf_->SetColorMode(color_mode_transform);
if (error != kErrorNone) {
@@ -170,6 +171,7 @@
// failure to force client composition
return HWC2::Error::Unsupported;
}
+ DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
}
if (use_matrix) {
@@ -184,7 +186,6 @@
current_color_mode_ = mode;
current_color_transform_ = hint;
CopyColorTransformMatrix(matrix, color_matrix_);
- DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
return HWC2::Error::None;
}
@@ -194,8 +195,10 @@
// SDM returns modes which is string combination of mode + transform.
DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
if (error != kErrorNone || (color_mode_count == 0)) {
+#ifndef EXCLUDE_DISPLAY_PP
DLOGW("GetColorModeCount failed, use native color mode");
PopulateTransform(HAL_COLOR_MODE_NATIVE, "native", "identity");
+#endif
return;
}
@@ -209,8 +212,8 @@
DLOGV_IF(kTagQDCM, "Color Mode[%d] = %s", i, mode_string.c_str());
AttrVal attr;
error = display_intf_->GetColorModeAttr(mode_string, &attr);
+ std::string color_gamut, dynamic_range, pic_quality;
if (!attr.empty()) {
- std::string color_gamut, dynamic_range, pic_quality;
for (auto &it : attr) {
if (it.first.find(kColorGamutAttribute) != std::string::npos) {
color_gamut = it.second;
@@ -231,12 +234,15 @@
PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, color_transform);
} else if ((color_gamut == kDcip3) &&
(pic_quality.empty() || pic_quality == kStandard)) {
- PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string, color_transform);
+ PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
} else if ((color_gamut == kDisplayP3) &&
(pic_quality.empty() || pic_quality == kStandard)) {
PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
}
- } else {
+ }
+
+ // Look at the mode name, if no color gamut is found
+ if (color_gamut.empty()) {
if (mode_string.find("hal_native") != std::string::npos) {
PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, mode_string);
} else if (mode_string.find("hal_srgb") != std::string::npos) {
@@ -345,6 +351,7 @@
return -EINVAL;
}
+ validated_.reset();
HWCDebugHandler::Get()->GetProperty("sys.hwc_disable_hdr", &disable_hdr_handling_);
if (disable_hdr_handling_) {
DLOGI("HDR Handling disabled");
@@ -364,11 +371,20 @@
// TODO(user): Add blit engine when needed
}
+ error = display_intf_->GetNumVariableInfoConfigs(&num_configs_);
+ if (error != kErrorNone) {
+ DLOGE("Getting config count failed. Error = %d", error);
+ return -EINVAL;
+ }
+
tone_mapper_ = new HWCToneMapper(buffer_allocator_);
display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
current_refresh_rate_ = max_refresh_rate_;
+
+ GetUnderScanConfig();
DLOGI("Display created with id: %d", id_);
+
return 0;
}
@@ -397,8 +413,8 @@
HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_, buffer_allocator_));
layer_map_.emplace(std::make_pair(layer->GetId(), layer));
*out_layer_id = layer->GetId();
- validated_ = false;
geometry_changes_ |= GeometryChanges::kAdded;
+ validated_.reset();
return HWC2::Error::None;
}
@@ -428,9 +444,9 @@
break;
}
}
- validated_ = false;
geometry_changes_ |= GeometryChanges::kRemoved;
+ validated_.reset();
return HWC2::Error::None;
}
@@ -441,12 +457,12 @@
metadata_refresh_rate_ = 0;
auto working_primaries = ColorPrimaries_BT709_5;
+ uint32_t color_mode_count = 0;
+ display_intf_->GetColorModeCount(&color_mode_count);
+
// Add one layer for fb target
// TODO(user): Add blit target layers
for (auto hwc_layer : layer_set_) {
- // Reset layer data which SDM may change
- hwc_layer->ResetPerFrameData();
-
Layer *layer = hwc_layer->GetSDMLayer();
layer->flags = {}; // Reset earlier flags
if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) {
@@ -510,7 +526,7 @@
bool hdr_layer = layer->input_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
(layer->input_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
layer->input_buffer.color_metadata.transfer == Transfer_HLG);
- if (hdr_layer && !disable_hdr_handling_) {
+ if (hdr_layer && !disable_hdr_handling_ && color_mode_count) {
// dont honor HDR when its handling is disabled
layer->input_buffer.flags.hdr = true;
layer_stack_.flags.hdr_present = true;
@@ -588,7 +604,6 @@
DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
return HWC2::Error::BadLayer;
}
- validated_ = false;
const auto layer = map_layer->second;
const auto z_range = layer_set_.equal_range(layer);
@@ -681,6 +696,8 @@
}
DisplayError error = display_intf_->SetDisplayState(state);
+ validated_.reset();
+
if (error == kErrorNone) {
flush_on_error_ = flush_on_error;
} else {
@@ -718,12 +735,15 @@
}
HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
- // TODO(user): Actually handle multiple configs
if (out_configs == nullptr) {
- *out_num_configs = 1;
- } else {
- *out_num_configs = 1;
- out_configs[0] = 0;
+ *out_num_configs = num_configs_;
+ return HWC2::Error::None;
+ }
+
+ *out_num_configs = num_configs_;
+
+ for (uint32_t i = 0; i < num_configs_; i++) {
+ out_configs[i] = i;
}
return HWC2::Error::None;
@@ -732,16 +752,11 @@
HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
int32_t *out_value) {
DisplayConfigVariableInfo variable_config;
- DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
- if (error != kErrorNone) {
- DLOGV("Get variable config failed. Error = %d", error);
+ if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
+ DLOGE("Get variable config failed");
return HWC2::Error::BadDisplay;
}
- if (config != 0) { // We only use config[0] - see TODO above
- return HWC2::Error::BadConfig;
- }
-
switch (attribute) {
case HWC2::Attribute::VsyncPeriod:
*out_value = INT32(variable_config.vsync_period_ns);
@@ -806,14 +821,19 @@
}
}
-// TODO(user): Store configurations and hook them up here
HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
- if (out_config != nullptr) {
- *out_config = 0;
- return HWC2::Error::None;
- } else {
- return HWC2::Error::BadParameter;
+ if (out_config == nullptr) {
+ return HWC2::Error::BadDisplay;
}
+
+ uint32_t active_index = 0;
+ if (GetActiveDisplayConfig(&active_index) != kErrorNone) {
+ return HWC2::Error::BadConfig;
+ }
+
+ *out_config = active_index;
+
+ return HWC2::Error::None;
}
HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
@@ -838,10 +858,11 @@
}
HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
- if (config != 0) {
+ if (SetActiveDisplayConfig(config) != kErrorNone) {
return HWC2::Error::BadConfig;
}
- // We have only one config right now - do nothing
+
+ validated_.reset();
return HWC2::Error::None;
}
@@ -859,6 +880,7 @@
}
DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
+ validated_.reset();
}
HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
@@ -884,6 +906,20 @@
return kErrorNone;
}
+DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
+ switch (event) {
+ case kIdleTimeout:
+ case kThermalEvent:
+ validated_.reset();
+ break;
+ default:
+ DLOGW("Unknown event: %d", event);
+ break;
+ }
+
+ return kErrorNone;
+}
+
HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
layer_changes_.clear();
layer_requests_.clear();
@@ -903,6 +939,8 @@
flush_ = true;
}
return HWC2::Error::BadDisplay;
+ } else {
+ validated_.set(type_);
}
} else {
// Skip is not set
@@ -931,10 +969,11 @@
if (requested_composition != device_composition) {
layer_changes_[hwc_layer->GetId()] = device_composition;
}
+ hwc_layer->ResetValidation();
}
*out_num_types = UINT32(layer_changes_.size());
*out_num_requests = UINT32(layer_requests_.size());
- validated_ = true;
+ skip_validate_ = false;
if (*out_num_types > 0) {
return HWC2::Error::HasChanges;
} else {
@@ -947,7 +986,7 @@
return HWC2::Error::None;
}
- if (!validated_) {
+ if (!validated_.test(type_)) {
return HWC2::Error::NotValidated;
}
@@ -969,10 +1008,11 @@
return HWC2::Error::None;
}
- if (!validated_) {
+ if (!validated_.test(type_)) {
DLOGW("Display is not validated");
return HWC2::Error::NotValidated;
}
+
*out_num_elements = UINT32(layer_changes_.size());
if (out_layers != nullptr && out_types != nullptr) {
int i = 0;
@@ -1002,18 +1042,19 @@
HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
uint32_t *out_num_elements, hwc2_layer_t *out_layers,
int32_t *out_layer_requests) {
- // No display requests for now
- // Use for sharing blit buffers and
- // writing wfd buffer directly to output if there is full GPU composition
- // and no color conversion needed
if (layer_set_.empty()) {
return HWC2::Error::None;
}
- if (!validated_) {
+ // No display requests for now
+ // Use for sharing blit buffers and
+ // writing wfd buffer directly to output if there is full GPU composition
+ // and no color conversion needed
+ if (!validated_.test(type_)) {
DLOGW("Display is not validated");
return HWC2::Error::NotValidated;
}
+
*out_display_requests = 0;
*out_num_elements = UINT32(layer_requests_.size());
if (out_layers != nullptr && out_layer_requests != nullptr) {
@@ -1064,15 +1105,19 @@
HWC2::Error HWCDisplay::CommitLayerStack(void) {
- if (shutdown_pending_ || layer_set_.empty()) {
- return HWC2::Error::None;
+ if (skip_validate_ && !CanSkipValidate()) {
+ validated_.reset(type_);
}
- if (!validated_) {
- DLOGW("Display is not validated");
+ if (!validated_.test(type_)) {
+ DLOGV_IF(kTagCompManager, "Display %d is not validated", id_);
return HWC2::Error::NotValidated;
}
+ if (shutdown_pending_ || layer_set_.empty()) {
+ return HWC2::Error::None;
+ }
+
DumpInputBuffers();
if (!flush_) {
@@ -1089,7 +1134,6 @@
}
}
error = display_intf_->Commit(&layer_stack_);
- validated_ = false;
if (error == kErrorNone) {
// A commit is successfully submitted, start flushing on failure now onwards.
@@ -1098,6 +1142,9 @@
if (error == kErrorShutDown) {
shutdown_pending_ = true;
return HWC2::Error::Unsupported;
+ } else if (error == kErrorNotValidated) {
+ validated_.reset(type_);
+ return HWC2::Error::NotValidated;
} else if (error != kErrorPermission) {
DLOGE("Commit failed. Error = %d", error);
// To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
@@ -1107,6 +1154,7 @@
}
}
+ skip_validate_ = true;
return HWC2::Error::None;
}
@@ -1116,6 +1164,7 @@
// Do no call flush on errors, if a successful buffer is never submitted.
if (flush_ && flush_on_error_) {
display_intf_->Flush();
+ validated_.reset();
}
if (tone_mapper_ && tone_mapper_->IsActive()) {
@@ -1153,8 +1202,10 @@
close(layer_buffer->acquire_fence_fd);
layer_buffer->acquire_fence_fd = -1;
}
+ layer->request.flags = {};
}
+ client_target_->GetSDMLayer()->request.flags = {};
*out_retire_fence = -1;
if (!flush_) {
// if swapinterval property is set to 0 then close and reset the list retire fence
@@ -1163,6 +1214,7 @@
layer_stack_.retire_fence_fd = -1;
}
*out_retire_fence = layer_stack_.retire_fence_fd;
+ layer_stack_.retire_fence_fd = -1;
if (dump_frame_count_) {
dump_frame_count_--;
@@ -1173,8 +1225,6 @@
geometry_changes_ = GeometryChanges::kNone;
flush_ = false;
- ClearRequestFlags();
-
return status;
}
@@ -1187,6 +1237,7 @@
if (display_intf_) {
error = display_intf_->SetMaxMixerStages(max_mixer_stages);
+ validated_.reset();
}
return error;
@@ -1336,7 +1387,8 @@
return;
}
- snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
+ snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
+ GetDisplayString());
if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
@@ -1385,7 +1437,8 @@
void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
char dir_path[PATH_MAX];
- snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
+ snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
+ GetDisplayString());
if (mkdir(dir_path, 777) != 0 && errno != EEXIST) {
DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
@@ -1470,10 +1523,13 @@
int aligned_height;
uint32_t usage = GRALLOC_USAGE_HW_FB;
int format = HAL_PIXEL_FORMAT_RGBA_8888;
- int ubwc_enabled = 0;
+ int ubwc_disabled = 0;
int flags = 0;
- HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
- if (ubwc_enabled == 1) {
+
+ // By default UBWC is enabled and below property is global enable/disable for all
+ // buffers allocated through gralloc , including framebuffer targets.
+ HWCDebugHandler::Get()->GetProperty("debug.gralloc.gfx_ubwc_disable", &ubwc_disabled);
+ if (!ubwc_disabled) {
usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
}
@@ -1523,7 +1579,7 @@
*y_pixels = display_config.y_pixels;
}
-int HWCDisplay::SetDisplayStatus(uint32_t display_status) {
+int HWCDisplay::SetDisplayStatus(DisplayStatus display_status) {
int status = 0;
switch (display_status) {
@@ -1544,6 +1600,7 @@
if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ validated_.reset();
}
return status;
@@ -1554,9 +1611,18 @@
return HWC2::Error::None;
}
- if (GetHWCLayer(layer) == nullptr) {
+ HWCLayer *hwc_layer = GetHWCLayer(layer);
+ if (hwc_layer == nullptr) {
return HWC2::Error::BadLayer;
}
+ if (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Cursor) {
+ return HWC2::Error::None;
+ }
+ if (!skip_validate_ && validated_.test(type_)) {
+ // the device is currently in the middle of the validate/present sequence,
+ // cannot set the Position(as per HWC2 spec)
+ return HWC2::Error::NotValidated;
+ }
DisplayState state;
if (display_intf_->GetDisplayState(&state) == kErrorNone) {
@@ -1565,9 +1631,9 @@
}
}
- if (!validated_) {
- return HWC2::Error::NotValidated;
- }
+ // TODO(user): HWC1.5 was not letting SetCursorPosition before validateDisplay,
+ // but HWC2.0 doesn't let setting cursor position after validate before present.
+ // Need to revisit.
auto error = display_intf_->SetCursorPosition(x, y);
if (error != kErrorNone) {
@@ -1590,6 +1656,7 @@
return -1;
}
+ validated_.reset();
return 0;
}
@@ -1598,6 +1665,7 @@
auto layer = hwc_layer->GetSDMLayer();
layer->composition = kCompositionSDE;
}
+ validated_.set(type_);
}
void HWCDisplay::MarkLayersForClientComposition() {
@@ -1615,10 +1683,12 @@
int HWCDisplay::SetPanelBrightness(int level) {
int ret = 0;
- if (display_intf_)
+ if (display_intf_) {
ret = display_intf_->SetPanelBrightness(level);
- else
+ validated_.reset();
+ } else {
ret = -EINVAL;
+ }
return ret;
}
@@ -1630,6 +1700,7 @@
int HWCDisplay::ToggleScreenUpdates(bool enable) {
display_paused_ = enable ? false : true;
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ validated_.reset();
return 0;
}
@@ -1726,8 +1797,10 @@
return;
}
-int HWCDisplay::SetActiveDisplayConfig(int config) {
- return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1;
+int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
+ int status = (display_intf_->SetActiveConfig(config) == kErrorNone) ? 0 : -1;
+ validated_.reset();
+ return status;
}
int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
@@ -1811,12 +1884,6 @@
}
}
-void HWCDisplay::ClearRequestFlags() {
- for (Layer *layer : layer_stack_.layers) {
- layer->request.flags = {};
- }
-}
-
std::string HWCDisplay::Dump() {
std::ostringstream os;
os << "-------------------------------" << std::endl;
@@ -1845,4 +1912,25 @@
os << "-------------------------------" << std::endl;
return os.str();
}
+
+bool HWCDisplay::CanSkipValidate() {
+ // Layer Stack checks
+ if (layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) {
+ return false;
+ }
+
+ for (auto hwc_layer : layer_set_) {
+ if (hwc_layer->NeedsValidation()) {
+ return false;
+ }
+
+ // Do not allow Skip Validate, if any layer needs GPU Composition.
+ if (hwc_layer->GetDeviceSelectedCompositionType() == HWC2::Composition::Client) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_display.h b/msm8909w_3100/sdm/libs/hwc2/hwc_display.h
similarity index 93%
rename from sdm845/sdm/libs/hwc2/hwc_display.h
rename to msm8909w_3100/sdm/libs/hwc2/hwc_display.h
index 1b04c84..2df25c5 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display.h
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_display.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -20,6 +20,7 @@
#ifndef __HWC_DISPLAY_H__
#define __HWC_DISPLAY_H__
+#include <sys/stat.h>
#include <QService.h>
#include <core/core_interface.h>
#include <hardware/hwcomposer.h>
@@ -60,7 +61,6 @@
uint32_t GetColorModeCount();
HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
HWC2::Error SetColorMode(android_color_mode_t mode);
- HWC2::Error SetColorModeById(int32_t color_mode_id);
HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
private:
@@ -92,6 +92,14 @@
class HWCDisplay : public DisplayEventHandler {
public:
+ enum DisplayStatus {
+ kDisplayStatusInvalid = -1,
+ kDisplayStatusOffline,
+ kDisplayStatusOnline,
+ kDisplayStatusPause,
+ kDisplayStatusResume,
+ };
+
virtual ~HWCDisplay() {}
virtual int Init();
virtual int Deinit();
@@ -106,7 +114,7 @@
virtual HWC2::PowerMode GetLastPowerMode();
virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
- virtual int SetDisplayStatus(uint32_t display_status);
+ virtual int SetDisplayStatus(DisplayStatus display_status);
virtual int OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
virtual int Perform(uint32_t operation, ...);
virtual void SetSecureDisplay(bool secure_display_active);
@@ -132,24 +140,17 @@
}
// Display Configurations
- virtual int SetActiveDisplayConfig(int config);
+ virtual int SetActiveDisplayConfig(uint32_t config);
virtual int GetActiveDisplayConfig(uint32_t *config);
virtual int GetDisplayConfigCount(uint32_t *count);
virtual int GetDisplayAttributesForConfig(int config,
DisplayConfigVariableInfo *display_attributes);
- template <typename... Args>
- int32_t CallLayerFunction(hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args... ),
- Args... args) {
- auto status = HWC2::Error::BadLayer;
- validated_ = false;
- auto hwc_layer = GetHWCLayer(layer);
- if (hwc_layer != nullptr) {
- status = (hwc_layer->*member)(std::forward<Args>(args)...);
- }
-
- return INT32(status);
+ virtual int SetState(bool connected) {
+ return kErrorNotSupported;
}
-
+ virtual DisplayError SetStandByMode(bool enable) {
+ return kErrorNotSupported;
+ }
int SetPanelBrightness(int level);
int GetPanelBrightness(int *level);
int ToggleScreenUpdates(bool enable);
@@ -162,6 +163,8 @@
void BuildLayerStack(void);
void BuildSolidFillStack(void);
HWCLayer *GetHWCLayer(hwc2_layer_t layer);
+ void ResetValidation() { validated_.reset(); }
+ uint32_t GetGeometryChanges() { return geometry_changes_; }
// HWC2 APIs
virtual HWC2::Error AcceptDisplayChanges(void);
@@ -172,9 +175,6 @@
virtual HWC2::Error SetColorMode(android_color_mode_t mode) {
return HWC2::Error::Unsupported;
}
- virtual HWC2::Error SetColorModeById(int32_t color_mode_id) {
- return HWC2::Error::Unsupported;
- }
virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint) {
return HWC2::Error::Unsupported;
}
@@ -211,13 +211,6 @@
float* out_min_luminance);
protected:
- enum DisplayStatus {
- kDisplayStatusOffline = 0,
- kDisplayStatusOnline,
- kDisplayStatusPause,
- kDisplayStatusResume,
- };
-
// Maximum number of layers supported by display manager.
static const uint32_t kMaxLayerCount = 32;
@@ -229,6 +222,7 @@
virtual DisplayError VSync(const DisplayEventVSync &vsync);
virtual DisplayError Refresh();
virtual DisplayError CECMessage(char *message);
+ virtual DisplayError HandleEvent(DisplayEvent event);
virtual void DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence);
virtual HWC2::Error PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests);
virtual HWC2::Error CommitLayerStack(void);
@@ -246,13 +240,14 @@
bool IsLayerUpdating(const Layer *layer);
uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
virtual void CloseAcquireFds();
- virtual void ClearRequestFlags();
+ virtual void GetUnderScanConfig() { }
enum {
INPUT_LAYER_DUMP,
OUTPUT_LAYER_DUMP,
};
+ static std::bitset<kDisplayMax> validated_;
CoreInterface *core_intf_ = nullptr;
HWCCallbacks *callbacks_ = nullptr;
HWCBufferAllocator *buffer_allocator_ = NULL;
@@ -290,17 +285,19 @@
LayerRect solid_fill_rect_ = {};
uint32_t solid_fill_color_ = 0;
LayerRect display_rect_;
- bool validated_ = false;
bool color_tranform_failed_ = false;
HWCColorMode *color_mode_ = NULL;
HWCToneMapper *tone_mapper_ = nullptr;
+ uint32_t num_configs_ = 0;
int disable_hdr_handling_ = 0; // disables HDR handling.
private:
void DumpInputBuffers(void);
+ bool CanSkipValidate();
qService::QService *qservice_ = NULL;
DisplayClass display_class_;
uint32_t geometry_changes_ = GeometryChanges::kNone;
+ bool skip_validate_ = false;
};
inline int HWCDisplay::Perform(uint32_t operation, ...) {
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_external.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_display_external.cpp
similarity index 73%
rename from sdm845/sdm/libs/hwc2/hwc_display_external.cpp
rename to msm8909w_3100/sdm/libs/hwc2/hwc_display_external.cpp
index a8f8480..830e955 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_external.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_display_external.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -64,6 +64,7 @@
error = hwc_display_external->GetMixerResolution(&external_width, &external_height);
if (error != kErrorNone) {
+ Destroy(hwc_display_external);
return -EINVAL;
}
@@ -121,8 +122,6 @@
return status;
}
- // TODO(user): SetRefreshRate need to follow new interface when added.
-
status = PrepareLayerStack(out_num_types, out_num_requests);
return status;
}
@@ -141,20 +140,12 @@
}
void HWCDisplayExternal::ApplyScanAdjustment(hwc_rect_t *display_frame) {
- if (display_intf_->IsUnderscanSupported()) {
+ if ((underscan_width_ <= 0) || (underscan_height_ <= 0)) {
return;
}
- // Read user defined width and height ratio
- int width = 0, height = 0;
- HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_width", &width);
- float width_ratio = FLOAT(width) / 100.0f;
- HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_height", &height);
- float height_ratio = FLOAT(height) / 100.0f;
-
- if (width_ratio == 0.0f || height_ratio == 0.0f) {
- return;
- }
+ float width_ratio = FLOAT(underscan_width_) / 100.0f;
+ float height_ratio = FLOAT(underscan_height_) / 100.0f;
uint32_t mixer_width = 0;
uint32_t mixer_height = 0;
@@ -187,6 +178,7 @@
if (secure_display_active_) {
DisplayError error = display_intf_->Flush();
+ validated_.reset();
if (error != kErrorNone) {
DLOGE("Flush failed. Error = %d", error);
}
@@ -215,4 +207,74 @@
}
}
+int HWCDisplayExternal::SetState(bool connected) {
+ DisplayError error = kErrorNone;
+ DisplayState state = kStateOff;
+ DisplayConfigVariableInfo fb_config = {};
+
+ if (connected) {
+ if (display_null_.IsActive()) {
+ error = core_intf_->CreateDisplay(type_, this, &display_intf_);
+ if (error != kErrorNone) {
+ DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p",
+ error, type_, this, &display_intf_);
+ return -EINVAL;
+ }
+
+ // Restore HDMI attributes when display is reconnected.
+ // This is to ensure that surfaceflinger & sdm are in sync.
+ display_null_.GetFrameBufferConfig(&fb_config);
+ int status = SetFrameBufferResolution(fb_config.x_pixels, fb_config.y_pixels);
+ if (status) {
+ DLOGW("Set frame buffer config failed. Error = %d", error);
+ return -1;
+ }
+
+ display_null_.GetDisplayState(&state);
+ display_intf_->SetDisplayState(state);
+ validated_.reset();
+
+ SetVsyncEnabled(HWC2::Vsync::Enable);
+
+ display_null_.SetActive(false);
+ DLOGI("Display is connected successfully.");
+ } else {
+ DLOGI("Display is already connected.");
+ }
+ } else {
+ if (!display_null_.IsActive()) {
+ // Preserve required attributes of HDMI display that surfaceflinger sees.
+ // Restore HDMI attributes when display is reconnected.
+ display_intf_->GetDisplayState(&state);
+ display_null_.SetDisplayState(state);
+
+ error = display_intf_->GetFrameBufferConfig(&fb_config);
+ if (error != kErrorNone) {
+ DLOGW("Get frame buffer config failed. Error = %d", error);
+ return -1;
+ }
+ display_null_.SetFrameBufferConfig(fb_config);
+
+ SetVsyncEnabled(HWC2::Vsync::Disable);
+ core_intf_->DestroyDisplay(display_intf_);
+ display_intf_ = &display_null_;
+
+ display_null_.SetActive(true);
+ DLOGI("Display is disconnected successfully.");
+ } else {
+ DLOGI("Display is already disconnected.");
+ }
+ }
+
+ return 0;
+}
+
+void HWCDisplayExternal::GetUnderScanConfig() {
+ if (!display_intf_->IsUnderscanSupported()) {
+ // Read user defined underscan width and height
+ HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_width", &underscan_width_);
+ HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_height", &underscan_height_);
+ }
+}
+
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_external.h b/msm8909w_3100/sdm/libs/hwc2/hwc_display_external.h
similarity index 91%
copy from sdm845/sdm/libs/hwc2/hwc_display_external.h
copy to msm8909w_3100/sdm/libs/hwc2/hwc_display_external.h
index 802a77c..fbee6a3 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_external.h
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_display_external.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,6 +31,7 @@
#define __HWC_DISPLAY_EXTERNAL_H__
#include "hwc_display.h"
+#include "display_null.h"
namespace sdm {
@@ -47,13 +48,19 @@
virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
virtual HWC2::Error Present(int32_t *out_retire_fence);
virtual void SetSecureDisplay(bool secure_display_active);
+ virtual int SetState(bool connected);
private:
HWCDisplayExternal(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
HWCCallbacks *callbacks, qService::QService *qservice);
void ApplyScanAdjustment(hwc_rect_t *display_frame);
+ void GetUnderScanConfig();
static void GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height,
uint32_t *virtual_width, uint32_t *virtual_height);
+
+ DisplayNull display_null_;
+ int underscan_width_ = 0;
+ int underscan_height_ = 0;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_primary.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_display_primary.cpp
similarity index 89%
rename from sdm845/sdm/libs/hwc2/hwc_display_primary.cpp
rename to msm8909w_3100/sdm/libs/hwc2/hwc_display_primary.cpp
index 2fcf2a9..df068b2 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -113,6 +113,8 @@
}
color_mode_ = new HWCColorMode(display_intf_);
color_mode_->Init();
+ HWCDebugHandler::Get()->GetProperty("vendor.display.enable_default_color_mode",
+ &default_mode_status_);
return status;
}
@@ -160,6 +162,10 @@
auto status = HWC2::Error::None;
DisplayError error = kErrorNone;
+ if (default_mode_status_ && !boot_animation_completed_) {
+ ProcessBootAnimCompleted();
+ }
+
if (display_paused_) {
MarkLayersForGPUBypass();
return status;
@@ -188,13 +194,19 @@
ToggleCPUHint(one_updating_layer);
uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
- bool final_rate = force_refresh_rate_ ? true : false;
- error = display_intf_->SetRefreshRate(refresh_rate, final_rate);
+ if (current_refresh_rate_ != refresh_rate) {
+ error = display_intf_->SetRefreshRate(refresh_rate);
+ }
+
if (error == kErrorNone) {
// On success, set current refresh rate to new refresh rate
current_refresh_rate_ = refresh_rate;
}
+ if (handle_idle_timeout_) {
+ handle_idle_timeout_ = false;
+ }
+
if (layer_set_.empty()) {
flush_ = true;
return status;
@@ -211,6 +223,7 @@
// If we do not handle the frame set retireFenceFd to outbufAcquireFenceFd
// Revisit this when validating display_paused
DisplayError error = display_intf_->Flush();
+ validated_.reset();
if (error != kErrorNone) {
DLOGE("Flush failed. Error = %d", error);
}
@@ -246,18 +259,7 @@
}
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
-
- return status;
-}
-
-HWC2::Error HWCDisplayPrimary::SetColorModeById(int32_t color_mode_id) {
- auto status = color_mode_->SetColorModeById(color_mode_id);
- if (status != HWC2::Error::None) {
- DLOGE("failed for mode = %d", color_mode_id);
- return status;
- }
-
- callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ validated_.reset();
return status;
}
@@ -277,6 +279,7 @@
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
color_tranform_failed_ = false;
+ validated_.reset();
return status;
}
@@ -318,6 +321,7 @@
return -EINVAL;
}
va_end(args);
+ validated_.reset();
return 0;
}
@@ -387,6 +391,8 @@
uint32_t HWCDisplayPrimary::GetOptimalRefreshRate(bool one_updating_layer) {
if (force_refresh_rate_) {
return force_refresh_rate_;
+ } else if (handle_idle_timeout_) {
+ return min_refresh_rate_;
} else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
return metadata_refresh_rate_;
}
@@ -398,12 +404,14 @@
DisplayError error = kErrorNone;
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ handle_idle_timeout_ = true;
return error;
}
void HWCDisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
display_intf_->SetIdleTimeoutMs(timeout_ms);
+ validated_.reset();
}
static void SetLayerBuffer(const BufferInfo &output_buffer_info, LayerBuffer *output_buffer) {
@@ -503,6 +511,7 @@
output_buffer_base_ = buffer;
post_processed_output_ = true;
DisablePartialUpdateOneFrame();
+ validated_.reset();
}
int HWCDisplayPrimary::FrameCaptureAsync(const BufferInfo &output_buffer_info,
@@ -521,12 +530,12 @@
GetPanelResolution(&panel_width, &panel_height);
GetFrameBufferResolution(&fb_width, &fb_height);
- if (post_processed_output && (output_buffer_info_.buffer_config.width < panel_width ||
- output_buffer_info_.buffer_config.height < panel_height)) {
+ if (post_processed_output && (output_buffer_info.buffer_config.width < panel_width ||
+ output_buffer_info.buffer_config.height < panel_height)) {
DLOGE("Buffer dimensions should not be less than panel resolution");
return -1;
- } else if (!post_processed_output && (output_buffer_info_.buffer_config.width < fb_width ||
- output_buffer_info_.buffer_config.height < fb_height)) {
+ } else if (!post_processed_output && (output_buffer_info.buffer_config.width < fb_width ||
+ output_buffer_info.buffer_config.height < fb_height)) {
DLOGE("Buffer dimensions should not be less than FB resolution");
return -1;
}
@@ -547,6 +556,7 @@
if (display_intf_) {
error = display_intf_->SetDetailEnhancerData(de_data);
+ validated_.reset();
}
return error;
}
@@ -556,6 +566,7 @@
if (display_intf_) {
error = display_intf_->ControlPartialUpdate(enable, pending);
+ validated_.reset();
}
return error;
@@ -566,6 +577,7 @@
if (display_intf_) {
error = display_intf_->DisablePartialUpdateOneFrame();
+ validated_.reset();
}
return error;
@@ -573,11 +585,37 @@
DisplayError HWCDisplayPrimary::SetMixerResolution(uint32_t width, uint32_t height) {
- return display_intf_->SetMixerResolution(width, height);
+ DisplayError error = display_intf_->SetMixerResolution(width, height);
+ validated_.reset();
+ return error;
}
DisplayError HWCDisplayPrimary::GetMixerResolution(uint32_t *width, uint32_t *height) {
return display_intf_->GetMixerResolution(width, height);
}
+DisplayError HWCDisplayPrimary::SetStandByMode(bool enable) {
+ if (enable) {
+ if (!display_null_.IsActive()) {
+ stored_display_intf_ = display_intf_;
+ display_intf_ = &display_null_;
+ display_null_.SetActive(true);
+ DLOGD("Null display is connected successfully");
+ } else {
+ DLOGD("Null display is already connected.");
+ }
+ } else {
+ if (display_null_.IsActive()) {
+ display_intf_ = stored_display_intf_;
+ validated_.reset();
+ display_null_.SetActive(false);
+ DLOGD("Display is connected successfully");
+ } else {
+ DLOGD("Display is already connected.");
+ }
+ }
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_primary.h b/msm8909w_3100/sdm/libs/hwc2/hwc_display_primary.h
similarity index 93%
copy from sdm845/sdm/libs/hwc2/hwc_display_primary.h
copy to msm8909w_3100/sdm/libs/hwc2/hwc_display_primary.h
index 4df65b3..bd880a5 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_primary.h
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_display_primary.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016, 2018 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -34,6 +34,7 @@
#include "cpuhint.h"
#include "hwc_display.h"
+#include "display_null.h"
namespace sdm {
@@ -57,7 +58,6 @@
virtual HWC2::Error Present(int32_t *out_retire_fence);
virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
virtual HWC2::Error SetColorMode(android_color_mode_t mode);
- virtual HWC2::Error SetColorModeById(int32_t color_mode_id);
virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
virtual int Perform(uint32_t operation, ...);
virtual void SetSecureDisplay(bool secure_display_active);
@@ -68,6 +68,7 @@
virtual int GetFrameCaptureStatus() { return frame_capture_status_; }
virtual DisplayError SetDetailEnhancerConfig(const DisplayDetailEnhancerData &de_data);
virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
+ virtual DisplayError SetStandByMode(bool enable);
private:
HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
@@ -88,6 +89,7 @@
BufferAllocator *buffer_allocator_ = nullptr;
CPUHint *cpu_hint_ = nullptr;
+ bool handle_idle_timeout_ = false;
// Primary output buffer configuration
LayerBuffer output_buffer_ = {};
@@ -101,6 +103,12 @@
bool dump_output_to_file_ = false;
BufferInfo output_buffer_info_ = {};
void *output_buffer_base_ = nullptr;
+ int default_mode_status_ = 0;
+
+ //Null display
+ DisplayNull display_null_;
+ DisplayInterface *stored_display_intf_ = NULL;
+
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_virtual.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_display_virtual.cpp
similarity index 99%
rename from sdm845/sdm/libs/hwc2/hwc_display_virtual.cpp
rename to msm8909w_3100/sdm/libs/hwc2/hwc_display_virtual.cpp
index f77e9c9..f53b2c2 100644
--- a/sdm845/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -131,6 +131,7 @@
auto status = HWC2::Error::None;
if (display_paused_) {
DisplayError error = display_intf_->Flush();
+ validated_.reset();
if (error != kErrorNone) {
DLOGE("Flush failed. Error = %d", error);
}
diff --git a/sdm845/sdm/libs/hwc2/hwc_display_virtual.h b/msm8909w_3100/sdm/libs/hwc2/hwc_display_virtual.h
similarity index 100%
copy from sdm845/sdm/libs/hwc2/hwc_display_virtual.h
copy to msm8909w_3100/sdm/libs/hwc2/hwc_display_virtual.h
diff --git a/sdm845/sdm/libs/hwc2/hwc_layers.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_layers.cpp
similarity index 87%
rename from sdm845/sdm/libs/hwc2/hwc_layers.cpp
rename to msm8909w_3100/sdm/libs/hwc2/hwc_layers.cpp
index 7fcd56b..d4b71bd 100644
--- a/sdm845/sdm/libs/hwc2/hwc_layers.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_layers.cpp
@@ -119,34 +119,38 @@
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(handle, aligned_width, aligned_height);
#endif
+ LayerBufferFormat format = GetSDMFormat(handle->format, handle->flags);
+ if ((format != layer_buffer->format) || (UINT32(aligned_width) != layer_buffer->width) ||
+ (UINT32(aligned_height) != layer_buffer->height)) {
+ // Layer buffer geometry has changed.
+ geometry_changes_ |= kBufferGeometry;
+ }
+
+ layer_buffer->format = format;
layer_buffer->width = UINT32(aligned_width);
layer_buffer->height = UINT32(aligned_height);
layer_buffer->unaligned_width = UINT32(handle->unaligned_width);
layer_buffer->unaligned_height = UINT32(handle->unaligned_height);
- layer_buffer->format = GetSDMFormat(handle->format, handle->flags);
if (SetMetaData(const_cast<private_handle_t *>(handle), layer_) != kErrorNone) {
return HWC2::Error::BadLayer;
}
-#ifdef USE_GRALLOC1
- // TODO(user): Clean this up
- if (handle->buffer_type == BUFFER_TYPE_VIDEO) {
-#else
- if (handle->bufferType == BUFFER_TYPE_VIDEO) {
-#endif
- layer_buffer->flags.video = true;
- }
+ layer_buffer->flags.video = (handle->buffer_type == BUFFER_TYPE_VIDEO) ? true : false;
+
// TZ Protected Buffer - L1
- if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
- layer_buffer->flags.secure = true;
- if (handle->flags & private_handle_t::PRIV_FLAGS_CAMERA_WRITE) {
- layer_buffer->flags.secure_camera = true;
- }
+ bool secure = (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER);
+ bool secure_camera = secure && (handle->flags & private_handle_t::PRIV_FLAGS_CAMERA_WRITE);
+ bool secure_display = (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY);
+ if (secure != layer_buffer->flags.secure || secure_camera != layer_buffer->flags.secure_camera ||
+ secure_display != layer_buffer->flags.secure_display) {
+ // Secure attribute of layer buffer has changed.
+ needs_validate_ = true;
}
- if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
- layer_buffer->flags.secure_display = true;
- }
+
+ layer_buffer->flags.secure = secure;
+ layer_buffer->flags.secure_camera = secure_camera;
+ layer_buffer->flags.secure_display = secure_display;
layer_buffer->planes[0].fd = ion_fd_;
layer_buffer->planes[0].offset = handle->offset;
@@ -159,6 +163,20 @@
}
HWC2::Error HWCLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
+ // Check if there is an update in SurfaceDamage rects
+ if (layer_->dirty_regions.size() != damage.numRects) {
+ needs_validate_ = true;
+ } else {
+ for (uint32_t j = 0; j < damage.numRects; j++) {
+ LayerRect damage_rect;
+ SetRect(damage.rects[j], &damage_rect);
+ if (damage_rect != layer_->dirty_regions.at(j)) {
+ needs_validate_ = true;
+ break;
+ }
+ }
+ }
+
layer_->dirty_regions.clear();
for (uint32_t i = 0; i < damage.numRects; i++) {
LayerRect rect;
@@ -192,6 +210,9 @@
}
HWC2::Error HWCLayer::SetLayerColor(hwc_color_t color) {
+ if (client_requested_ != HWC2::Composition::SolidColor) {
+ return HWC2::Error::None;
+ }
layer_->solid_fill_color = GetUint32Color(color);
layer_->input_buffer.format = kFormatARGB8888;
DLOGV_IF(kTagCompManager, "[%" PRIu64 "][%" PRIu64 "] Layer color set to %x", display_id_, id_,
@@ -258,19 +279,23 @@
HWC2::Error HWCLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
LayerRect dst_rect = {};
-
SetRect(frame, &dst_rect);
- if (dst_rect_ != dst_rect) {
+ if (layer_->dst_rect != dst_rect) {
geometry_changes_ |= kDisplayFrame;
- dst_rect_ = dst_rect;
+ layer_->dst_rect = dst_rect;
}
-
return HWC2::Error::None;
}
-void HWCLayer::ResetPerFrameData() {
- layer_->dst_rect = dst_rect_;
- layer_->transform = layer_transform_;
+HWC2::Error HWCLayer::SetCursorPosition(int32_t x, int32_t y) {
+ hwc_rect_t frame = {};
+ frame.left = x;
+ frame.top = y;
+ frame.right = x + INT(layer_->dst_rect.right - layer_->dst_rect.left);
+ frame.bottom = y + INT(layer_->dst_rect.bottom - layer_->dst_rect.top);
+ SetLayerDisplayFrame(frame);
+
+ return HWC2::Error::None;
}
HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) {
@@ -329,11 +354,10 @@
break;
}
- if (layer_transform_ != layer_transform) {
+ if (layer_->transform != layer_transform) {
geometry_changes_ |= kTransform;
- layer_transform_ = layer_transform;
+ layer_->transform = layer_transform;
}
-
return HWC2::Error::None;
}
@@ -550,20 +574,23 @@
private_handle_t *handle = const_cast<private_handle_t *>(pvt_handle);
IGC_t igc = {};
+ LayerIGC layer_igc = layer_buffer->igc;
if (getMetaData(handle, GET_IGC, &igc) == 0) {
- if (SetIGC(igc, &layer_buffer->igc) != kErrorNone) {
+ if (SetIGC(igc, &layer_igc) != kErrorNone) {
return kErrorNotSupported;
}
}
- uint32_t fps = 0;
- if (getMetaData(handle, GET_REFRESH_RATE , &fps) == 0) {
- layer->frame_rate = RoundToStandardFPS(fps);
+ float fps = 0;
+ uint32_t frame_rate = layer->frame_rate;
+ if (getMetaData(handle, GET_REFRESH_RATE, &fps) == 0) {
+ frame_rate = RoundToStandardFPS(fps);
}
int32_t interlaced = 0;
+ bool interlace = layer_buffer->flags.interlace;
if (getMetaData(handle, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
- layer_buffer->flags.interlace = interlaced ? true : false;
+ interlace = interlaced ? true : false;
}
uint32_t linear_format = 0;
@@ -572,8 +599,19 @@
}
uint32_t s3d = 0;
+ LayerBufferS3DFormat s3d_format = layer_buffer->s3d_format;
if (getMetaData(handle, GET_S3D_FORMAT, &s3d) == 0) {
- layer_buffer->s3d_format = GetS3DFormat(s3d);
+ s3d_format = GetS3DFormat(s3d);
+ }
+
+ if ((layer_igc != layer_buffer->igc) || (interlace != layer_buffer->flags.interlace) ||
+ (frame_rate != layer->frame_rate) || (s3d_format != layer_buffer->s3d_format)) {
+ // Layer buffer metadata has changed.
+ needs_validate_ = true;
+ layer_buffer->igc = layer_igc;
+ layer->frame_rate = frame_rate;
+ layer_buffer->s3d_format = s3d_format;
+ layer_buffer->flags.interlace = interlace;
}
return kErrorNone;
@@ -709,7 +747,7 @@
case kCompositionGPU:
hwc_composition = HWC2::Composition::Client;
break;
- case kCompositionCursor:
+ case kCompositionHWCursor:
hwc_composition = HWC2::Composition::Cursor;
break;
default:
diff --git a/sdm845/sdm/libs/hwc2/hwc_layers.h b/msm8909w_3100/sdm/libs/hwc2/hwc_layers.h
similarity index 94%
rename from sdm845/sdm/libs/hwc2/hwc_layers.h
rename to msm8909w_3100/sdm/libs/hwc2/hwc_layers.h
index f536cb7..9f71917 100644
--- a/sdm845/sdm/libs/hwc2/hwc_layers.h
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_layers.h
@@ -52,6 +52,7 @@
kZOrder = 0x040,
kAdded = 0x080,
kRemoved = 0x100,
+ kBufferGeometry = 0x200,
};
class HWCLayer {
@@ -61,7 +62,6 @@
uint32_t GetZ() const { return z_; }
hwc2_layer_t GetId() const { return id_; }
Layer *GetSDMLayer() { return layer_; }
- void ResetPerFrameData();
HWC2::Error SetLayerBlendMode(HWC2::BlendMode mode);
HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
@@ -69,6 +69,7 @@
HWC2::Error SetLayerCompositionType(HWC2::Composition type);
HWC2::Error SetLayerDataspace(int32_t dataspace);
HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
+ HWC2::Error SetCursorPosition(int32_t x, int32_t y);
HWC2::Error SetLayerPlaneAlpha(float alpha);
HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
@@ -86,6 +87,8 @@
int32_t PopReleaseFence(void);
bool SupportedDataspace();
bool SupportLocalConversion(ColorPrimaries working_primaries);
+ void ResetValidation() { needs_validate_ = false; }
+ bool NeedsValidation() { return (needs_validate_ || geometry_changes_); }
private:
Layer *layer_ = nullptr;
@@ -97,8 +100,7 @@
int ion_fd_ = -1;
HWCBufferAllocator *buffer_allocator_ = NULL;
int32_t dataspace_ = HAL_DATASPACE_UNKNOWN;
- LayerTransform layer_transform_ = {};
- LayerRect dst_rect_ = {};
+ bool needs_validate_ = true;
// Composition requested by client(SF)
HWC2::Composition client_requested_ = HWC2::Composition::Device;
diff --git a/sdm845/sdm/libs/hwc2/hwc_session.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_session.cpp
similarity index 73%
rename from sdm845/sdm/libs/hwc2/hwc_session.cpp
rename to msm8909w_3100/sdm/libs/hwc2/hwc_session.cpp
index 2bf7d4d..fdd647c 100644
--- a/sdm845/sdm/libs/hwc2/hwc_session.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_session.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -35,6 +35,8 @@
#include <algorithm>
#include <string>
#include <bitset>
+#include <thread>
+#include <memory>
#include "hwc_buffer_allocator.h"
#include "hwc_buffer_sync_handler.h"
@@ -65,8 +67,63 @@
};
namespace sdm {
+
+static HWCUEvent g_hwc_uevent_;
Locker HWCSession::locker_;
+void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
+ const char *uevent_thread_name = "HWC_UeventThread";
+
+ prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+ int status = uevent_init();
+ if (!status) {
+ std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
+ hwc_uevent->caller_cv_.notify_one();
+ DLOGE("Failed to init uevent with err %d", status);
+ return;
+ }
+
+ {
+ // Signal caller thread that worker thread is ready to listen to events.
+ std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
+ hwc_uevent->init_done_ = true;
+ hwc_uevent->caller_cv_.notify_one();
+ }
+
+ while (1) {
+ char uevent_data[PAGE_SIZE] = {};
+
+ // keep last 2 zeroes to ensure double 0 termination
+ int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
+
+ // scope of lock to this block only, so that caller is free to set event handler to nullptr;
+ {
+ std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
+ if (hwc_uevent->uevent_listener_) {
+ hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
+ } else {
+ DLOGW("UEvent dropped. No uevent listener.");
+ }
+ }
+ }
+}
+
+HWCUEvent::HWCUEvent() {
+ std::unique_lock<std::mutex> caller_lock(mutex_);
+ std::thread thread(HWCUEvent::UEventThread, this);
+ thread.detach();
+ caller_cv_.wait(caller_lock);
+}
+
+void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
+ DLOGI("Set uevent listener = %p", uevent_listener);
+
+ std::lock_guard<std::mutex> obj(mutex_);
+ uevent_listener_ = uevent_listener;
+}
+
HWCSession::HWCSession(const hw_module_t *module) {
hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
@@ -80,6 +137,10 @@
int status = -EINVAL;
const char *qservice_name = "display.qservice";
+ if (!g_hwc_uevent_.InitDone()) {
+ return status;
+ }
+
// Start QService and connect to it.
qService::QService::init();
android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
@@ -93,9 +154,9 @@
return -EINVAL;
}
- buffer_allocator_ = new HWCBufferAllocator();
+ StartServices();
- DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), buffer_allocator_,
+ DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
&buffer_sync_handler_, &socket_handler_,
&core_intf_);
if (error != kErrorNone) {
@@ -103,40 +164,42 @@
return -EINVAL;
}
- // Read which display is first, and create it and store it in primary slot
- // TODO(user): This will need to be redone for HWC2 - right now we validate only
- // the primary physical path
- HWDisplayInterfaceInfo hw_disp_info;
+ g_hwc_uevent_.Register(this);
+
+ // If HDMI display is primary display, defer display creation until hotplug event is received.
+ HWDisplayInterfaceInfo hw_disp_info = {};
error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
- if (error == kErrorNone && hw_disp_info.type == kHDMI && hw_disp_info.is_connected) {
- // HDMI is primary display. If already connected, then create it and store in
- // primary display slot. If not connected, create a NULL display for now.
- status = HWCDisplayExternal::Create(core_intf_, buffer_allocator_, &callbacks_, qservice_,
- &hwc_display_[HWC_DISPLAY_PRIMARY]);
+ if (error != kErrorNone) {
+ g_hwc_uevent_.Register(nullptr);
+ CoreInterface::DestroyCore();
+ DLOGE("Primary display type not recognized. Error = %d", error);
+ return -EINVAL;
+ }
+
+ if (hw_disp_info.type == kHDMI) {
+ status = 0;
+ hdmi_is_primary_ = true;
+ // Create display if it is connected, else wait for hotplug connect event.
+ if (hw_disp_info.is_connected) {
+ status = HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
+ &hwc_display_[HWC_DISPLAY_PRIMARY]);
+ }
} else {
// Create and power on primary display
- status = HWCDisplayPrimary::Create(core_intf_, buffer_allocator_, &callbacks_, qservice_,
+ status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
&hwc_display_[HWC_DISPLAY_PRIMARY]);
+ color_mgr_ = HWCColorManager::CreateColorManager(&buffer_allocator_);
+ if (!color_mgr_) {
+ DLOGW("Failed to load HWCColorManager.");
+ }
}
if (status) {
+ g_hwc_uevent_.Register(nullptr);
CoreInterface::DestroyCore();
return status;
}
- color_mgr_ = HWCColorManager::CreateColorManager(buffer_allocator_);
- if (!color_mgr_) {
- DLOGW("Failed to load HWCColorManager.");
- }
-
- if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
- DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno));
- HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
- hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
- CoreInterface::DestroyCore();
- return -errno;
- }
-
struct rlimit fd_limit = {};
getrlimit(RLIMIT_NOFILE, &fd_limit);
fd_limit.rlim_cur = fd_limit.rlim_cur * 2;
@@ -146,36 +209,37 @@
DLOGW("Unable to increase fd limit - err:%d, %s", errno, strerror(errno));
}
}
+
return 0;
}
int HWCSession::Deinit() {
- HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
- hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
+ HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+ if (primary_display) {
+ if (hdmi_is_primary_) {
+ HWCDisplayExternal::Destroy(primary_display);
+ } else {
+ HWCDisplayPrimary::Destroy(primary_display);
+ }
+ }
+ hwc_display_[HWC_DISPLAY_PRIMARY] = nullptr;
+
if (color_mgr_) {
color_mgr_->DestroyColorManager();
}
- uevent_thread_exit_ = true;
- DLOGD("Terminating uevent thread");
- // TODO(user): on restarting HWC in the same process, the uevent thread does not restart
- // cleanly.
- Sys::pthread_cancel_(uevent_thread_);
+
+ g_hwc_uevent_.Register(nullptr);
DisplayError error = CoreInterface::DestroyCore();
if (error != kErrorNone) {
DLOGE("Display core de-initialization failed. Error = %d", error);
}
- if (buffer_allocator_ != nullptr) {
- delete buffer_allocator_;
- }
- buffer_allocator_ = nullptr;
-
return 0;
}
int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_);
if (!module || !name || !device) {
DLOGE("Invalid parameters.");
@@ -201,7 +265,7 @@
}
int HWCSession::Close(hw_device_t *device) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_);
if (!device) {
return -EINVAL;
@@ -217,10 +281,24 @@
void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
int32_t *outCapabilities) {
- if (outCapabilities != nullptr && *outCount >= 1) {
- outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
+ if (!outCount) {
+ return;
}
- *outCount = 1;
+
+ int value = 0;
+ bool disable_skip_validate = false;
+ if (Debug::Get()->GetProperty("sdm.debug.disable_skip_validate", &value) == kErrorNone) {
+ disable_skip_validate = (value == 1);
+ }
+ uint32_t count = 1 + (disable_skip_validate ? 0 : 1);
+
+ if (outCapabilities != nullptr && (*outCount >= count)) {
+ outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
+ if (!disable_skip_validate) {
+ outCapabilities[1] = HWC2_CAPABILITY_SKIP_VALIDATE;
+ }
+ }
+ *outCount = count;
}
template <typename PFN, typename T>
@@ -233,12 +311,22 @@
// Defined in the same order as in the HWC2 header
int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
SCOPE_LOCK(locker_);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
}
int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t *out_layer_id) {
+ if (!out_layer_id) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
SCOPE_LOCK(locker_);
return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
}
@@ -251,6 +339,10 @@
return HWC2_ERROR_BAD_DISPLAY;
}
+ if (!out_display_id || !width || !height || !format) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
HWCSession *hwc_session = static_cast<HWCSession *>(device);
auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
if (status == HWC2::Error::None) {
@@ -265,13 +357,16 @@
int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t layer) {
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
SCOPE_LOCK(locker_);
return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
}
int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
SCOPE_LOCK(locker_);
- if (!device) {
+ if (!device || display != HWC_DISPLAY_VIRTUAL) {
return HWC2_ERROR_BAD_DISPLAY;
}
@@ -288,9 +383,9 @@
}
void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_);
- if (!device) {
+ if (!device || !out_size) {
return;
}
auto *hwc_session = static_cast<HWCSession *>(device);
@@ -321,6 +416,10 @@
static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
uint32_t *out_num_elements, hwc2_layer_t *out_layers,
int32_t *out_types) {
+ // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
+ if (!out_num_elements) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
out_num_elements, out_layers, out_types);
}
@@ -392,7 +491,9 @@
}
static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {
- return 1;
+ char property[PROPERTY_VALUE_MAX];
+ property_get("debug.sdm.support_writeback", property, "1");
+ return (uint32_t) atoi(property);
}
static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
@@ -406,7 +507,6 @@
int32_t *out_retire_fence) {
HWCSession *hwc_session = static_cast<HWCSession *>(device);
DTRACE_SCOPED();
- SEQUENCE_EXIT_SCOPE_LOCK(locker_);
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
}
@@ -430,11 +530,16 @@
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
}
+ SCOPE_LOCK(hwc_session->callbacks_lock_);
auto desc = static_cast<HWC2::Callback>(descriptor);
auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
DLOGD("Registering callback: %s", to_string(desc).c_str());
- if (descriptor == HWC2_CALLBACK_HOTPLUG)
- hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
+ if (descriptor == HWC2_CALLBACK_HOTPLUG) {
+ if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY] && !hwc_session->hdmi_is_primary_) {
+ hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
+ }
+ }
+ hwc_session->callbacks_lock_.Broadcast();
return INT32(error);
}
@@ -453,14 +558,14 @@
int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
int32_t /*android_color_mode_t*/ int_mode) {
auto mode = static_cast<android_color_mode_t>(int_mode);
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
}
int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
const float *matrix,
int32_t /*android_color_transform_t*/ hint) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_);
android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
transform_hint);
@@ -468,8 +573,14 @@
static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
int32_t x, int32_t y) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition, layer, x,
- y);
+ auto status = INT32(HWC2::Error::None);
+ status = HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition,
+ layer, x, y);
+ if (status == INT32(HWC2::Error::None)) {
+ // Update cursor position
+ HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetCursorPosition, x, y);
+ }
+ return status;
}
static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
@@ -550,8 +661,12 @@
return HWC2_ERROR_BAD_DISPLAY;
}
+ if (display != HWC_DISPLAY_VIRTUAL) {
+ return HWC2_ERROR_UNSUPPORTED;
+ }
+
auto *hwc_session = static_cast<HWCSession *>(device);
- if (display == HWC_DISPLAY_VIRTUAL && hwc_session->hwc_display_[display]) {
+ if (hwc_session->hwc_display_[display]) {
auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
auto status = vds->SetOutputBuffer(buffer, releaseFence);
return INT32(status);
@@ -562,7 +677,7 @@
int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
auto mode = static_cast<HWC2::PowerMode>(int_mode);
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_);
return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
}
@@ -574,6 +689,7 @@
int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
uint32_t *out_num_types, uint32_t *out_num_requests) {
DTRACE_SCOPED();
+ SCOPE_LOCK(locker_);
HWCSession *hwc_session = static_cast<HWCSession *>(device);
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
@@ -583,7 +699,6 @@
// Handle external_pending_connect_ in CreateVirtualDisplay
auto status = HWC2::Error::BadDisplay;
if (hwc_session->hwc_display_[display]) {
- SEQUENCE_ENTRY_SCOPE_LOCK(locker_);
if (display == HWC_DISPLAY_PRIMARY) {
// TODO(user): This can be moved to HWCDisplayPrimary
if (hwc_session->reset_panel_) {
@@ -592,7 +707,7 @@
}
if (hwc_session->need_invalidate_) {
- hwc_session->callbacks_.Refresh(display);
+ hwc_session->Refresh(display);
}
if (hwc_session->color_mgr_) {
@@ -602,11 +717,6 @@
status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
}
- // If validate fails, cancel the sequence lock so that other operations
- // (such as Dump or SetPowerMode) may succeed without blocking on the condition
- if (status == HWC2::Error::BadDisplay) {
- SEQUENCE_CANCEL_SCOPE_LOCK(locker_);
- }
return INT32(status);
}
@@ -716,7 +826,7 @@
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
return HWC2::Error::NoResources;
}
- auto status = HWCDisplayVirtual::Create(core_intf_, buffer_allocator_, &callbacks_, width,
+ auto status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, width,
height, format, &hwc_display_[HWC_DISPLAY_VIRTUAL]);
// TODO(user): validate width and height support
if (status)
@@ -735,7 +845,7 @@
hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
if (disp == HWC_DISPLAY_EXTERNAL) {
- status = HWCDisplayExternal::Create(core_intf_, buffer_allocator_, &callbacks_, primary_width,
+ status = HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_, primary_width,
primary_height, qservice_, false, &hwc_display_[disp]);
} else {
DLOGE("Invalid display type");
@@ -769,8 +879,6 @@
// Qclient methods
android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
-
android::status_t status = 0;
switch (command) {
@@ -779,14 +887,11 @@
break;
case qService::IQService::SCREEN_REFRESH:
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ refreshScreen();
break;
case qService::IQService::SET_IDLE_TIMEOUT:
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- uint32_t timeout = UINT32(input_parcel->readInt32());
- hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(timeout);
- }
+ setIdleTimeout(UINT32(input_parcel->readInt32()));
break;
case qService::IQService::SET_FRAME_DUMP_CONFIG:
@@ -801,8 +906,13 @@
status = SetDisplayMode(input_parcel);
break;
- case qService::IQService::SET_SECONDARY_DISPLAY_STATUS:
- status = SetSecondaryDisplayStatus(input_parcel, output_parcel);
+ case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
+ int disp_id = INT(input_parcel->readInt32());
+ HWCDisplay::DisplayStatus disp_status =
+ static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
+ status = SetSecondaryDisplayStatus(disp_id, disp_status);
+ output_parcel->writeInt32(status);
+ }
break;
case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
@@ -812,56 +922,89 @@
case qService::IQService::SET_VIEW_FRAME:
break;
- case qService::IQService::TOGGLE_SCREEN_UPDATES:
- status = ToggleScreenUpdates(input_parcel, output_parcel);
+ case qService::IQService::TOGGLE_SCREEN_UPDATES: {
+ int32_t input = input_parcel->readInt32();
+ status = toggleScreenUpdate(input == 1);
+ output_parcel->writeInt32(status);
+ }
break;
case qService::IQService::QDCM_SVC_CMDS:
status = QdcmCMDHandler(input_parcel, output_parcel);
break;
- case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED:
- status = OnMinHdcpEncryptionLevelChange(input_parcel, output_parcel);
+ case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
+ int disp_id = input_parcel->readInt32();
+ uint32_t min_enc_level = UINT32(input_parcel->readInt32());
+ status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
+ output_parcel->writeInt32(status);
+ }
break;
- case qService::IQService::CONTROL_PARTIAL_UPDATE:
- status = ControlPartialUpdate(input_parcel, output_parcel);
+ case qService::IQService::CONTROL_PARTIAL_UPDATE: {
+ int disp_id = input_parcel->readInt32();
+ uint32_t enable = UINT32(input_parcel->readInt32());
+ status = ControlPartialUpdate(disp_id, enable == 1);
+ output_parcel->writeInt32(status);
+ }
break;
- case qService::IQService::SET_ACTIVE_CONFIG:
- status = HandleSetActiveDisplayConfig(input_parcel, output_parcel);
+ case qService::IQService::SET_ACTIVE_CONFIG: {
+ uint32_t config = UINT32(input_parcel->readInt32());
+ int disp_id = input_parcel->readInt32();
+ status = SetActiveConfigIndex(disp_id, config);
+ }
break;
- case qService::IQService::GET_ACTIVE_CONFIG:
- status = HandleGetActiveDisplayConfig(input_parcel, output_parcel);
+ case qService::IQService::GET_ACTIVE_CONFIG: {
+ int disp_id = input_parcel->readInt32();
+ uint32_t config = 0;
+ status = GetActiveConfigIndex(disp_id, &config);
+ output_parcel->writeInt32(INT(config));
+ }
break;
- case qService::IQService::GET_CONFIG_COUNT:
- status = HandleGetDisplayConfigCount(input_parcel, output_parcel);
+ case qService::IQService::GET_CONFIG_COUNT: {
+ int disp_id = input_parcel->readInt32();
+ uint32_t count = 0;
+ status = GetConfigCount(disp_id, &count);
+ output_parcel->writeInt32(INT(count));
+ }
break;
case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
break;
- case qService::IQService::GET_PANEL_BRIGHTNESS:
- status = GetPanelBrightness(input_parcel, output_parcel);
+ case qService::IQService::GET_PANEL_BRIGHTNESS: {
+ int level = 0;
+ status = GetPanelBrightness(&level);
+ output_parcel->writeInt32(level);
+ }
break;
- case qService::IQService::SET_PANEL_BRIGHTNESS:
- status = SetPanelBrightness(input_parcel, output_parcel);
+ case qService::IQService::SET_PANEL_BRIGHTNESS: {
+ uint32_t level = UINT32(input_parcel->readInt32());
+ status = setPanelBrightness(level);
+ output_parcel->writeInt32(status);
+ }
break;
case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
status = GetVisibleDisplayRect(input_parcel, output_parcel);
break;
- case qService::IQService::SET_CAMERA_STATUS:
- status = SetDynamicBWForCamera(input_parcel, output_parcel);
+ case qService::IQService::SET_CAMERA_STATUS: {
+ uint32_t camera_status = UINT32(input_parcel->readInt32());
+ status = setCameraLaunchStatus(camera_status);
+ }
break;
- case qService::IQService::GET_BW_TRANSACTION_STATUS:
- status = GetBWTransactionStatus(input_parcel, output_parcel);
+ case qService::IQService::GET_BW_TRANSACTION_STATUS: {
+ bool state = true;
+ status = DisplayBWTransactionPending(&state);
+ output_parcel->writeInt32(state);
+ }
break;
case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
@@ -872,8 +1015,8 @@
status = SetColorModeOverride(input_parcel);
break;
- case qService::IQService::SET_COLOR_MODE_BY_ID:
- status = SetColorModeById(input_parcel);
+ case qService::IQService::SET_STAND_BY_MODE:
+ status = SetStandByMode(input_parcel);
break;
default:
@@ -884,173 +1027,17 @@
return status;
}
-android::status_t HWCSession::ToggleScreenUpdates(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int input = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (hwc_display_[HWC_DISPLAY_PRIMARY] && (input <= 1) && (input >= 0)) {
- error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(input == 1);
- if (error != 0) {
- DLOGE("Failed to toggle screen updates = %d. Error = %d", input, error);
- }
- }
- output_parcel->writeInt32(error);
-
- return error;
-}
-
-android::status_t HWCSession::SetPanelBrightness(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int level = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(level);
- if (error != 0) {
- DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error);
- }
- }
- output_parcel->writeInt32(error);
-
- return error;
-}
-
-android::status_t HWCSession::GetPanelBrightness(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int error = android::BAD_VALUE;
- int ret = error;
-
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(&ret);
- if (error != 0) {
- ret = error;
- DLOGE("Failed to get the panel brightness. Error = %d", error);
- }
- }
- output_parcel->writeInt32(ret);
-
- return error;
-}
-
-android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
- android::Parcel *out) {
- DisplayError error = kErrorNone;
- int ret = 0;
- uint32_t disp_id = UINT32(input_parcel->readInt32());
- uint32_t enable = UINT32(input_parcel->readInt32());
-
- if (disp_id != HWC_DISPLAY_PRIMARY) {
- DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
- ret = -EINVAL;
- out->writeInt32(ret);
- return ret;
- }
-
- if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
- DLOGE("primary display object is not instantiated");
- ret = -EINVAL;
- out->writeInt32(ret);
- return ret;
- }
-
- uint32_t pending = 0;
- error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlPartialUpdate(enable, &pending);
-
- if (error == kErrorNone) {
- if (!pending) {
- out->writeInt32(ret);
- return ret;
- }
- } else if (error == kErrorNotSupported) {
- out->writeInt32(ret);
- return ret;
- } else {
- ret = -EINVAL;
- out->writeInt32(ret);
- return ret;
- }
-
- // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
-
- // Wait until partial update control is complete
- ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
-
- out->writeInt32(ret);
-
- return ret;
-}
-
-android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int config = input_parcel->readInt32();
- int dpy = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (dpy > HWC_DISPLAY_VIRTUAL) {
- return android::BAD_VALUE;
- }
-
- if (hwc_display_[dpy]) {
- error = hwc_display_[dpy]->SetActiveDisplayConfig(config);
- if (error == 0) {
- callbacks_.Refresh(0);
- }
- }
-
- return error;
-}
-
-android::status_t HWCSession::HandleGetActiveDisplayConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int dpy = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (dpy > HWC_DISPLAY_VIRTUAL) {
- return android::BAD_VALUE;
- }
-
- if (hwc_display_[dpy]) {
- uint32_t config = 0;
- error = hwc_display_[dpy]->GetActiveDisplayConfig(&config);
- if (error == 0) {
- output_parcel->writeInt32(INT(config));
- }
- }
-
- return error;
-}
-
-android::status_t HWCSession::HandleGetDisplayConfigCount(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int dpy = input_parcel->readInt32();
- int error = android::BAD_VALUE;
-
- if (dpy > HWC_DISPLAY_VIRTUAL) {
- return android::BAD_VALUE;
- }
-
- uint32_t count = 0;
- if (hwc_display_[dpy]) {
- error = hwc_display_[dpy]->GetDisplayConfigCount(&count);
- if (error == 0) {
- output_parcel->writeInt32(INT(count));
- }
- }
-
- return error;
-}
-
android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
*input_parcel,
android::Parcel *output_parcel) {
+ SCOPE_LOCK(locker_);
+
int config = input_parcel->readInt32();
int dpy = input_parcel->readInt32();
int error = android::BAD_VALUE;
DisplayConfigVariableInfo display_attributes;
- if (dpy > HWC_DISPLAY_VIRTUAL) {
+ if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
return android::BAD_VALUE;
}
@@ -1069,44 +1056,24 @@
return error;
}
-android::status_t HWCSession::SetSecondaryDisplayStatus(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int ret = -EINVAL;
-
- uint32_t display_id = UINT32(input_parcel->readInt32());
- uint32_t display_status = UINT32(input_parcel->readInt32());
-
- DLOGI("Display = %d, Status = %d", display_id, display_status);
-
- if (display_id >= HWC_NUM_DISPLAY_TYPES) {
- DLOGE("Invalid display_id");
- } else if (display_id == HWC_DISPLAY_PRIMARY) {
- DLOGE("Not supported for this display");
- } else if (!hwc_display_[display_id]) {
- DLOGW("Display is not connected");
- } else {
- ret = hwc_display_[display_id]->SetDisplayStatus(display_status);
- }
-
- output_parcel->writeInt32(ret);
-
- return ret;
-}
-
android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
+ SCOPE_LOCK(locker_);
+
uint32_t operation = UINT32(input_parcel->readInt32());
+ HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+
switch (operation) {
case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
- return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
- HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
+ return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
+
case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
- return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
- HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
+ return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
+
case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
uint32_t refresh_rate = UINT32(input_parcel->readInt32());
- return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
- HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
+ return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
}
+
default:
DLOGW("Invalid operation %d", operation);
return -EINVAL;
@@ -1116,11 +1083,15 @@
}
android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
+ SCOPE_LOCK(locker_);
+
uint32_t mode = UINT32(input_parcel->readInt32());
return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
}
android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
+ SCOPE_LOCK(locker_);
+
DisplayError error = kErrorNone;
std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
@@ -1155,42 +1126,9 @@
return 0;
}
-android::status_t HWCSession::SetDynamicBWForCamera(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- DisplayError error = kErrorNone;
- uint32_t camera_status = UINT32(input_parcel->readInt32());
- HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault;
-
- // trigger invalidate to apply new bw caps.
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
-
- error = core_intf_->SetMaxBandwidthMode(mode);
- if (error != kErrorNone) {
- return -EINVAL;
- }
-
- new_bw_mode_ = true;
- need_invalidate_ = true;
-
- return 0;
-}
-
-android::status_t HWCSession::GetBWTransactionStatus(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- bool state = true;
-
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- if (sync_wait(bw_mode_release_fd_, 0) < 0) {
- DLOGI("bw_transaction_release_fd is not yet signalled: err= %s", strerror(errno));
- state = false;
- }
- output_parcel->writeInt32(state);
- }
-
- return 0;
-}
-
void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
+ SCOPE_LOCK(locker_);
+
uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
@@ -1215,6 +1153,8 @@
}
android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
+ SCOPE_LOCK(locker_);
+
DisplayError error = kErrorNone;
uint32_t dpy = UINT32(input_parcel->readInt32());
@@ -1243,23 +1183,20 @@
auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
auto device = static_cast<hwc2_device_t *>(this);
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return -EINVAL;
+ }
+
auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
return 0;
}
-android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
- auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
- auto mode = input_parcel->readInt32();
- auto device = static_cast<hwc2_device_t *>(this);
- auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorModeById, mode);
- if (err != HWC2_ERROR_NONE)
- return -EINVAL;
- return 0;
-}
-
void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
+ SCOPE_LOCK(locker_);
+
int type = input_parcel->readInt32();
bool enable = (input_parcel->readInt32() > 0);
DLOGI("type = %d enable = %d", type, enable);
@@ -1334,7 +1271,7 @@
switch (pending_action.action) {
case kInvalidating:
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kEnterQDCMMode:
ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
@@ -1345,12 +1282,12 @@
case kApplySolidFill:
ret =
color_mgr_->SetSolidFill(pending_action.params, true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kDisableSolidFill:
ret =
color_mgr_->SetSolidFill(pending_action.params, false, hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kSetPanelBrightness:
brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
@@ -1364,7 +1301,7 @@
case kEnableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params, true,
hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kDisableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params, false,
@@ -1373,7 +1310,7 @@
case kConfigureDetailedEnhancer:
ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kNoAction:
break;
@@ -1387,77 +1324,29 @@
HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
req_payload.DestroyPayload();
resp_payload.DestroyPayload();
+ hwc_display_[display_id]->ResetValidation();
return (ret ? -EINVAL : 0);
}
-android::status_t HWCSession::OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
- int ret = -EINVAL;
- uint32_t display_id = UINT32(input_parcel->readInt32());
- uint32_t min_enc_level = UINT32(input_parcel->readInt32());
-
- DLOGI("Display %d", display_id);
-
- if (display_id >= HWC_NUM_DISPLAY_TYPES) {
- DLOGE("Invalid display_id");
- } else if (display_id != HWC_DISPLAY_EXTERNAL) {
- DLOGE("Not supported for display");
- } else if (!hwc_display_[display_id]) {
- DLOGW("Display is not connected");
- } else {
- ret = hwc_display_[display_id]->OnMinHdcpEncryptionLevelChange(min_enc_level);
- }
-
- output_parcel->writeInt32(ret);
-
- return ret;
-}
-
-void *HWCSession::HWCUeventThread(void *context) {
- if (context) {
- return reinterpret_cast<HWCSession *>(context)->HWCUeventThreadHandler();
- }
-
- return NULL;
-}
-
-void *HWCSession::HWCUeventThreadHandler() {
- static char uevent_data[PAGE_SIZE];
- int length = 0;
- prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0);
- setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
- if (!uevent_init()) {
- DLOGE("Failed to init uevent");
- pthread_exit(0);
- return NULL;
- }
-
- while (!uevent_thread_exit_) {
- // keep last 2 zeroes to ensure double 0 termination
- length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
-
- if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) {
- DLOGI("Uevent HDMI = %s", uevent_data);
- int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
- if (connected >= 0) {
- DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
- if (HotPlugHandler(connected) == -1) {
- DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
- }
- }
- } else if (strcasestr(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) {
- DLOGI("Uevent FB0 = %s", uevent_data);
- int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
- if (panel_reset == 0) {
- callbacks_.Refresh(0);
- reset_panel_ = true;
+void HWCSession::UEventHandler(const char *uevent_data, int length) {
+ if (strcasestr(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
+ DLOGI("Uevent HDMI = %s", uevent_data);
+ int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
+ if (connected >= 0) {
+ DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
+ if (HotPlugHandler(connected) == -1) {
+ DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
}
}
+ } else if (strcasestr(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
+ DLOGI("Uevent FB0 = %s", uevent_data);
+ int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
+ if (panel_reset == 0) {
+ Refresh(0);
+ reset_panel_ = true;
+ }
}
- pthread_exit(0);
-
- return NULL;
}
int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
@@ -1500,34 +1389,35 @@
int HWCSession::HotPlugHandler(bool connected) {
int status = 0;
bool notify_hotplug = false;
- bool hdmi_primary = false;
// To prevent sending events to client while a lock is held, acquire scope locks only within
// below scope so that those get automatically unlocked after the scope ends.
- {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ do {
+ SCOPE_LOCK(locker_);
+ // If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
+ // if it is already created, but got disconnected/connected again,
+ // just toggle display status and do not notify surfaceflinger.
+ // If HDMI is not primary, create/destroy external display normally.
+ if (hdmi_is_primary_) {
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
+ } else {
+ status = HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
+ qservice_, &hwc_display_[HWC_DISPLAY_PRIMARY]);
+ notify_hotplug = true;
+ }
+
+ break;
+ }
+
+ // Primary display must be connected for HDMI as secondary cases.
if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
DLOGE("Primary display is not connected.");
return -1;
}
- HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
- HWCDisplay *external_display = NULL;
-
- if (primary_display->GetDisplayClass() == DISPLAY_CLASS_EXTERNAL) {
- external_display = static_cast<HWCDisplayExternal *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
- hdmi_primary = true;
- }
-
- // If primary display connected is a NULL display, then replace it with the external display
if (connected) {
- // If we are in HDMI as primary and the primary display just got plugged in
- if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
- DLOGE("HDMI is already connected");
- return -1;
- }
-
// Connect external display if virtual display is not connected.
// Else, defer external display connection and process it when virtual display
// tears down; Do not notify SurfaceFlinger since connection is deferred now.
@@ -1545,40 +1435,29 @@
// Do not return error if external display is not in connected status.
// Due to virtual display concurrency, external display connection might be still pending
// but hdmi got disconnected before pending connection could be processed.
-
- if (hdmi_primary) {
- assert(external_display != NULL);
- uint32_t x_res, y_res;
- external_display->GetFrameBufferResolution(&x_res, &y_res);
- // Need to manually disable VSYNC as SF is not aware of connect/disconnect cases
- // for HDMI as primary
- external_display->SetVsyncEnabled(HWC2::Vsync::Disable);
- HWCDisplayExternal::Destroy(external_display);
-
- // In HWC2, primary displays can be hotplugged out
+ if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+ status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
notify_hotplug = true;
- } else {
- if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
- status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
- notify_hotplug = true;
- }
- external_pending_connect_ = false;
}
+ external_pending_connect_ = false;
+ }
+ } while (0);
+
+ if (connected) {
+ Refresh(0);
+
+ if (!hdmi_is_primary_) {
+ // wait for sufficient time to ensure sufficient resources are available to process new
+ // new display connection.
+ uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
+ usleep(vsync_period * 2 / 1000);
}
}
- if (connected && notify_hotplug) {
- // trigger screen refresh to ensure sufficient resources are available to process new
- // new display connection.
- callbacks_.Refresh(0);
- uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
- usleep(vsync_period * 2 / 1000);
- }
// notify client
- // Handle HDMI as primary here
if (notify_hotplug) {
- callbacks_.Hotplug(HWC_DISPLAY_EXTERNAL,
- connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
+ HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
+ connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
}
qservice_->onHdmiHotplug(INT(connected));
@@ -1601,9 +1480,10 @@
android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
- int dpy = input_parcel->readInt32();
+ SCOPE_LOCK(locker_);
- if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) {
+ int dpy = input_parcel->readInt32();
+ if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
return android::BAD_VALUE;
}
@@ -1625,4 +1505,37 @@
return android::NO_ERROR;
}
+android::status_t HWCSession::SetStandByMode(const android::Parcel *input_parcel) {
+ SCOPE_LOCK(locker_);
+
+ bool enable = (input_parcel->readInt32() > 0);
+
+ if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ DLOGI("Primary display is not initialized");
+ return -EINVAL;
+ }
+
+ hwc_display_[HWC_DISPLAY_PRIMARY]->SetStandByMode(enable);
+
+ return android::NO_ERROR;
+}
+
+void HWCSession::Refresh(hwc2_display_t display) {
+ SCOPE_LOCK(callbacks_lock_);
+ HWC2::Error err = callbacks_.Refresh(display);
+ while (err != HWC2::Error::None) {
+ callbacks_lock_.Wait();
+ err = callbacks_.Refresh(display);
+ }
+}
+
+void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
+ SCOPE_LOCK(callbacks_lock_);
+ HWC2::Error err = callbacks_.Hotplug(display, state);
+ while (err != HWC2::Error::None) {
+ callbacks_lock_.Wait();
+ err = callbacks_.Hotplug(display, state);
+ }
+}
+
} // namespace sdm
diff --git a/msm8909w_3100/sdm/libs/hwc2/hwc_session.h b/msm8909w_3100/sdm/libs/hwc2/hwc_session.h
new file mode 100644
index 0000000..e5131d8
--- /dev/null
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_session.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright 2015 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.
+ */
+
+#ifndef __HWC_SESSION_H__
+#define __HWC_SESSION_H__
+
+#include <vendor/display/config/1.0/IDisplayConfig.h>
+#include <core/core_interface.h>
+#include <utils/locker.h>
+
+#include "hwc_callbacks.h"
+#include "hwc_layers.h"
+#include "hwc_display.h"
+#include "hwc_display_primary.h"
+#include "hwc_display_external.h"
+#include "hwc_display_virtual.h"
+#include "hwc_color_manager.h"
+#include "hwc_socket_handler.h"
+
+namespace sdm {
+
+using ::vendor::display::config::V1_0::IDisplayConfig;
+using ::android::hardware::Return;
+
+// Create a singleton uevent listener thread valid for life of hardware composer process.
+// This thread blocks on uevents poll inside uevent library implementation. This poll exits
+// only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle
+// of this thread with HWC session cause HWC deinitialization to wait infinitely for the
+// thread to exit.
+class HWCUEventListener {
+ public:
+ virtual ~HWCUEventListener() {}
+ virtual void UEventHandler(const char *uevent_data, int length) = 0;
+};
+
+class HWCUEvent {
+ public:
+ HWCUEvent();
+ static void UEventThread(HWCUEvent *hwc_event);
+ void Register(HWCUEventListener *uevent_listener);
+ inline bool InitDone() { return init_done_; }
+
+ private:
+ std::mutex mutex_;
+ std::condition_variable caller_cv_;
+ HWCUEventListener *uevent_listener_ = nullptr;
+ bool init_done_ = false;
+};
+
+class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qClient::BnQClient {
+ public:
+ struct HWCModuleMethods : public hw_module_methods_t {
+ HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; }
+ };
+
+ explicit HWCSession(const hw_module_t *module);
+ int Init();
+ int Deinit();
+ HWC2::Error CreateVirtualDisplayObject(uint32_t width, uint32_t height, int32_t *format);
+
+ template <typename... Args>
+ static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display,
+ HWC2::Error (HWCDisplay::*member)(Args...), Args... args) {
+ if (!device) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ auto status = HWC2::Error::BadDisplay;
+ if (hwc_session->hwc_display_[display]) {
+ auto hwc_display = hwc_session->hwc_display_[display];
+ status = (hwc_display->*member)(std::forward<Args>(args)...);
+ }
+ return INT32(status);
+ }
+
+ template <typename... Args>
+ static int32_t CallLayerFunction(hwc2_device_t *device, hwc2_display_t display,
+ hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args...),
+ Args... args) {
+ if (!device) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ auto status = HWC2::Error::BadDisplay;
+ if (hwc_session->hwc_display_[display]) {
+ status = HWC2::Error::BadLayer;
+ auto hwc_layer = hwc_session->hwc_display_[display]->GetHWCLayer(layer);
+ if (hwc_layer != nullptr) {
+ status = (hwc_layer->*member)(std::forward<Args>(args)...);
+ if (hwc_session->hwc_display_[display]->GetGeometryChanges()) {
+ hwc_session->hwc_display_[display]->ResetValidation();
+ }
+ }
+ }
+ return INT32(status);
+ }
+
+ // HWC2 Functions that require a concrete implementation in hwc session
+ // and hence need to be member functions
+ static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display);
+ static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
+ hwc2_layer_t *out_layer_id);
+ static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
+ int32_t *format, hwc2_display_t *out_display_id);
+ static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer);
+ static int32_t DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display);
+ static void Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer);
+ static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
+ int32_t *out_retire_fence);
+ static int32_t RegisterCallback(hwc2_device_t *device, int32_t descriptor,
+ hwc2_callback_data_t callback_data,
+ hwc2_function_pointer_t pointer);
+ static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
+ buffer_handle_t buffer, int32_t releaseFence);
+ static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+ uint32_t z);
+ static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode);
+ static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
+ uint32_t *out_num_types, uint32_t *out_num_requests);
+ static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display,
+ int32_t /*android_color_mode_t*/ int_mode);
+ static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
+ const float *matrix, int32_t /*android_color_transform_t*/ hint);
+
+ private:
+ static const int kExternalConnectionTimeoutMs = 500;
+ static const int kPartialUpdateControlTimeoutMs = 100;
+
+ // hwc methods
+ static int Open(const hw_module_t *module, const char *name, hw_device_t **device);
+ static int Close(hw_device_t *device);
+ static void GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
+ int32_t *outCapabilities);
+ static hwc2_function_pointer_t GetFunction(struct hwc2_device *device, int32_t descriptor);
+
+ // Uevent handler
+ virtual void UEventHandler(const char *uevent_data, int length);
+ int GetEventValue(const char *uevent_data, int length, const char *event_info);
+ int HotPlugHandler(bool connected);
+ void ResetPanel();
+ int32_t ConnectDisplay(int disp);
+ int DisconnectDisplay(int disp);
+ int GetVsyncPeriod(int disp);
+ int32_t GetConfigCount(int disp_id, uint32_t *count);
+ int32_t GetActiveConfigIndex(int disp_id, uint32_t *config);
+ int32_t SetActiveConfigIndex(int disp_id, uint32_t config);
+ int32_t ControlPartialUpdate(int dpy, bool enable);
+ int32_t DisplayBWTransactionPending(bool *status);
+ int32_t SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status);
+ int32_t GetPanelBrightness(int *level);
+ int32_t MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level);
+
+ // service methods
+ void StartServices();
+
+ // Methods from ::android::hardware::display::config::V1_0::IDisplayConfig follow.
+ Return<void> isDisplayConnected(IDisplayConfig::DisplayType dpy,
+ isDisplayConnected_cb _hidl_cb) override;
+ Return<int32_t> setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy,
+ IDisplayConfig::DisplayExternalStatus status) override;
+ Return<int32_t> configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op,
+ uint32_t refreshRate) override;
+ Return<void> getConfigCount(IDisplayConfig::DisplayType dpy,
+ getConfigCount_cb _hidl_cb) override;
+ Return<void> getActiveConfig(IDisplayConfig::DisplayType dpy,
+ getActiveConfig_cb _hidl_cb) override;
+ Return<int32_t> setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) override;
+ Return<void> getDisplayAttributes(uint32_t configIndex, IDisplayConfig::DisplayType dpy,
+ getDisplayAttributes_cb _hidl_cb) override;
+ Return<int32_t> setPanelBrightness(uint32_t level) override;
+ Return<void> getPanelBrightness(getPanelBrightness_cb _hidl_cb) override;
+ Return<int32_t> minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy,
+ uint32_t min_enc_level) override;
+ Return<int32_t> refreshScreen() override;
+ Return<int32_t> controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) override;
+ Return<int32_t> toggleScreenUpdate(bool on) override;
+ Return<int32_t> setIdleTimeout(uint32_t value) override;
+ Return<void> getHDRCapabilities(IDisplayConfig::DisplayType dpy,
+ getHDRCapabilities_cb _hidl_cb) override;
+ Return<int32_t> setCameraLaunchStatus(uint32_t on) override;
+ Return<void> displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) override;
+
+ // QClient methods
+ virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
+ android::Parcel *output_parcel);
+ void DynamicDebug(const android::Parcel *input_parcel);
+ void SetFrameDumpConfig(const android::Parcel *input_parcel);
+ android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
+ android::status_t SetDisplayMode(const android::Parcel *input_parcel);
+ android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
+ android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
+ android::Parcel *output_parcel);
+ android::status_t HandleGetDisplayAttributesForConfig(const android::Parcel *input_parcel,
+ android::Parcel *output_parcel);
+ android::status_t GetVisibleDisplayRect(const android::Parcel *input_parcel,
+ android::Parcel *output_parcel);
+ android::status_t SetMixerResolution(const android::Parcel *input_parcel);
+ android::status_t SetColorModeOverride(const android::Parcel *input_parcel);
+ android::status_t SetStandByMode(const android::Parcel *input_parcel);
+
+ void Refresh(hwc2_display_t display);
+ void HotPlug(hwc2_display_t display, HWC2::Connection state);
+
+ static Locker locker_;
+ CoreInterface *core_intf_ = nullptr;
+ HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr};
+ HWCCallbacks callbacks_;
+ HWCBufferAllocator buffer_allocator_;
+ HWCBufferSyncHandler buffer_sync_handler_;
+ HWCColorManager *color_mgr_ = nullptr;
+ bool reset_panel_ = false;
+ bool secure_display_active_ = false;
+ bool external_pending_connect_ = false;
+ bool new_bw_mode_ = false;
+ bool need_invalidate_ = false;
+ int bw_mode_release_fd_ = -1;
+ qService::QService *qservice_ = nullptr;
+ HWCSocketHandler socket_handler_;
+ bool hdmi_is_primary_ = false;
+ Locker callbacks_lock_;
+};
+
+} // namespace sdm
+
+#endif // __HWC_SESSION_H__
diff --git a/msm8909w_3100/sdm/libs/hwc2/hwc_session_services.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_session_services.cpp
new file mode 100644
index 0000000..425ffbe
--- /dev/null
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_session_services.cpp
@@ -0,0 +1,484 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <core/buffer_allocator.h>
+#include <utils/debug.h>
+#include <sync/sync.h>
+#include <profiler.h>
+
+#include "hwc_buffer_sync_handler.h"
+#include "hwc_session.h"
+
+#define __CLASS__ "HWCSession"
+
+namespace sdm {
+
+using ::android::hardware::Void;
+
+void HWCSession::StartServices() {
+ status_t status = IDisplayConfig::registerAsService();
+ if (status != OK) {
+ DLOGW("Could not register IDisplayConfig as service (%d).", status);
+ } else {
+ DLOGI("IDisplayConfig service registration completed.");
+ }
+}
+
+int MapDisplayType(IDisplayConfig::DisplayType dpy) {
+ switch (dpy) {
+ case IDisplayConfig::DisplayType::DISPLAY_PRIMARY:
+ return HWC_DISPLAY_PRIMARY;
+
+ case IDisplayConfig::DisplayType::DISPLAY_EXTERNAL:
+ return HWC_DISPLAY_EXTERNAL;
+
+ case IDisplayConfig::DisplayType::DISPLAY_VIRTUAL:
+ return HWC_DISPLAY_VIRTUAL;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+HWCDisplay::DisplayStatus MapExternalStatus(IDisplayConfig::DisplayExternalStatus status) {
+ switch (status) {
+ case IDisplayConfig::DisplayExternalStatus::EXTERNAL_OFFLINE:
+ return HWCDisplay::kDisplayStatusOffline;
+
+ case IDisplayConfig::DisplayExternalStatus::EXTERNAL_ONLINE:
+ return HWCDisplay::kDisplayStatusOnline;
+
+ case IDisplayConfig::DisplayExternalStatus::EXTERNAL_PAUSE:
+ return HWCDisplay::kDisplayStatusPause;
+
+ case IDisplayConfig::DisplayExternalStatus::EXTERNAL_RESUME:
+ return HWCDisplay::kDisplayStatusResume;
+
+ default:
+ break;
+ }
+
+ return HWCDisplay::kDisplayStatusInvalid;
+}
+
+// Methods from ::vendor::hardware::display::config::V1_0::IDisplayConfig follow.
+Return<void> HWCSession::isDisplayConnected(IDisplayConfig::DisplayType dpy,
+ isDisplayConnected_cb _hidl_cb) {
+ SCOPE_LOCK(locker_);
+
+ int32_t error = -EINVAL;
+ bool connected = false;
+
+ int disp_id = MapDisplayType(dpy);
+ if (disp_id >= 0) {
+ connected = hwc_display_[disp_id];
+ error = 0;
+ }
+
+ _hidl_cb(error, connected);
+
+ return Void();
+}
+
+int32_t HWCSession::SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status) {
+ SCOPE_LOCK(locker_);
+
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ DLOGI("Display = %d, Status = %d", disp_id, status);
+
+ if (disp_id == HWC_DISPLAY_PRIMARY) {
+ DLOGE("Not supported for this display");
+ } else if (!hwc_display_[disp_id]) {
+ DLOGW("Display is not connected");
+ } else {
+ return hwc_display_[disp_id]->SetDisplayStatus(status);
+ }
+
+ return -EINVAL;
+}
+
+Return<int32_t> HWCSession::setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy,
+ IDisplayConfig::DisplayExternalStatus status) {
+ return SetSecondaryDisplayStatus(MapDisplayType(dpy), MapExternalStatus(status));
+}
+
+Return<int32_t> HWCSession::configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op,
+ uint32_t refreshRate) {
+ SCOPE_LOCK(locker_);
+
+ HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+
+ switch (op) {
+ case IDisplayConfig::DisplayDynRefreshRateOp::DISABLE_METADATA_DYN_REFRESH_RATE:
+ return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
+
+ case IDisplayConfig::DisplayDynRefreshRateOp::ENABLE_METADATA_DYN_REFRESH_RATE:
+ return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
+
+ case IDisplayConfig::DisplayDynRefreshRateOp::SET_BINDER_DYN_REFRESH_RATE:
+ return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refreshRate);
+
+ default:
+ DLOGW("Invalid operation %d", op);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int32_t HWCSession::GetConfigCount(int disp_id, uint32_t *count) {
+ SCOPE_LOCK(locker_);
+
+ if (disp_id >= 0 && hwc_display_[disp_id]) {
+ return hwc_display_[disp_id]->GetDisplayConfigCount(count);
+ }
+
+ return -EINVAL;
+}
+
+Return<void> HWCSession::getConfigCount(IDisplayConfig::DisplayType dpy,
+ getConfigCount_cb _hidl_cb) {
+ uint32_t count = 0;
+ int32_t error = GetConfigCount(MapDisplayType(dpy), &count);
+
+ _hidl_cb(error, count);
+
+ return Void();
+}
+
+int32_t HWCSession::GetActiveConfigIndex(int disp_id, uint32_t *config) {
+ SCOPE_LOCK(locker_);
+
+ if (disp_id >= 0 && hwc_display_[disp_id]) {
+ return hwc_display_[disp_id]->GetActiveDisplayConfig(config);
+ }
+
+ return -EINVAL;
+}
+
+Return<void> HWCSession::getActiveConfig(IDisplayConfig::DisplayType dpy,
+ getActiveConfig_cb _hidl_cb) {
+ uint32_t config = 0;
+ int32_t error = GetActiveConfigIndex(MapDisplayType(dpy), &config);
+
+ _hidl_cb(error, config);
+
+ return Void();
+}
+
+int32_t HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) {
+ SCOPE_LOCK(locker_);
+
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ int32_t error = -EINVAL;
+ if (hwc_display_[disp_id]) {
+ error = hwc_display_[disp_id]->SetActiveDisplayConfig(config);
+ if (!error) {
+ Refresh(0);
+ }
+ }
+
+ return error;
+}
+
+Return<int32_t> HWCSession::setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) {
+ return SetActiveConfigIndex(MapDisplayType(dpy), config);
+}
+
+Return<void> HWCSession::getDisplayAttributes(uint32_t configIndex,
+ IDisplayConfig::DisplayType dpy,
+ getDisplayAttributes_cb _hidl_cb) {
+ SCOPE_LOCK(locker_);
+
+ int32_t error = -EINVAL;
+ IDisplayConfig::DisplayAttributes display_attributes = {};
+
+ int disp_id = MapDisplayType(dpy);
+ if (disp_id >= 0 && hwc_display_[disp_id]) {
+ DisplayConfigVariableInfo hwc_display_attributes;
+ error = hwc_display_[disp_id]->GetDisplayAttributesForConfig(static_cast<int>(configIndex),
+ &hwc_display_attributes);
+ if (!error) {
+ display_attributes.vsyncPeriod = hwc_display_attributes.vsync_period_ns;
+ display_attributes.xRes = hwc_display_attributes.x_pixels;
+ display_attributes.yRes = hwc_display_attributes.y_pixels;
+ display_attributes.xDpi = hwc_display_attributes.x_dpi;
+ display_attributes.yDpi = hwc_display_attributes.y_dpi;
+ display_attributes.panelType = IDisplayConfig::DisplayPortType::DISPLAY_PORT_DEFAULT;
+ display_attributes.isYuv = hwc_display_attributes.is_yuv;
+ }
+ }
+
+ return Void();
+}
+
+Return<int32_t> HWCSession::setPanelBrightness(uint32_t level) {
+ SCOPE_LOCK(locker_);
+
+ int32_t error = -EINVAL;
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(static_cast<int>(level));
+ if (error) {
+ DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error);
+ }
+ }
+
+ return error;
+}
+
+int32_t HWCSession::GetPanelBrightness(int *level) {
+ SCOPE_LOCK(locker_);
+
+ int32_t error = -EINVAL;
+
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(level);
+ if (error) {
+ DLOGE("Failed to get the panel brightness. Error = %d", error);
+ }
+ }
+
+ return error;
+}
+
+Return<void> HWCSession::getPanelBrightness(getPanelBrightness_cb _hidl_cb) {
+ int level = 0;
+ int32_t error = GetPanelBrightness(&level);
+
+ _hidl_cb(error, static_cast<uint32_t>(level));
+
+ return Void();
+}
+
+int32_t HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level) {
+ SCOPE_LOCK(locker_);
+
+ DLOGI("Display %d", disp_id);
+
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ if (disp_id != HWC_DISPLAY_EXTERNAL) {
+ DLOGE("Not supported for display");
+ } else if (!hwc_display_[disp_id]) {
+ DLOGW("Display is not connected");
+ } else {
+ return hwc_display_[disp_id]->OnMinHdcpEncryptionLevelChange(min_enc_level);
+ }
+
+ return -EINVAL;
+}
+
+Return<int32_t> HWCSession::minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy,
+ uint32_t min_enc_level) {
+ return MinHdcpEncryptionLevelChanged(MapDisplayType(dpy), min_enc_level);
+}
+
+Return<int32_t> HWCSession::refreshScreen() {
+ SCOPE_LOCK(locker_);
+
+ Refresh(HWC_DISPLAY_PRIMARY);
+
+ return 0;
+}
+
+int32_t HWCSession::ControlPartialUpdate(int disp_id, bool enable) {
+ SCOPE_LOCK(locker_);
+
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
+
+ if (disp_id != HWC_DISPLAY_PRIMARY) {
+ DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
+ return -EINVAL;
+ }
+
+ HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+ if (!hwc_display) {
+ DLOGE("primary display object is not instantiated");
+ return -EINVAL;
+ }
+
+ uint32_t pending = 0;
+ DisplayError hwc_error = hwc_display->ControlPartialUpdate(enable, &pending);
+
+ if (hwc_error == kErrorNone) {
+ if (!pending) {
+ return 0;
+ }
+ } else if (hwc_error == kErrorNotSupported) {
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+
+ // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
+ Refresh(HWC_DISPLAY_PRIMARY);
+
+ // Wait until partial update control is complete
+ int32_t error = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
+
+ return error;
+}
+
+Return<int32_t> HWCSession::controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) {
+ return ControlPartialUpdate(MapDisplayType(dpy), enable);
+}
+
+Return<int32_t> HWCSession::toggleScreenUpdate(bool on) {
+ SCOPE_LOCK(locker_);
+
+ int32_t error = -EINVAL;
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(on);
+ if (error) {
+ DLOGE("Failed to toggle screen updates = %d. Error = %d", on, error);
+ }
+ }
+
+ return error;
+}
+
+Return<int32_t> HWCSession::setIdleTimeout(uint32_t value) {
+ SCOPE_LOCK(locker_);
+
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(value);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+Return<void> HWCSession::getHDRCapabilities(IDisplayConfig::DisplayType dpy,
+ getHDRCapabilities_cb _hidl_cb) {
+ SCOPE_LOCK(locker_);
+
+ int32_t error = -EINVAL;
+ IDisplayConfig::DisplayHDRCapabilities hdr_caps = {};
+
+ do {
+ int disp_id = MapDisplayType(dpy);
+ if (disp_id < 0) {
+ DLOGE("Invalid display id = %d", disp_id);
+ break;
+ }
+
+ HWCDisplay *hwc_display = hwc_display_[disp_id];
+ if (!hwc_display) {
+ DLOGE("Display = %d is not connected.", disp_id);
+ break;
+ }
+
+ // query number of hdr types
+ uint32_t out_num_types = 0;
+ if (hwc_display->GetHdrCapabilities(&out_num_types, nullptr, nullptr, nullptr, nullptr)
+ != HWC2::Error::None) {
+ break;
+ }
+
+ if (!out_num_types) {
+ error = 0;
+ break;
+ }
+
+ // query hdr caps
+ hdr_caps.supportedHdrTypes.resize(out_num_types);
+
+ float out_max_luminance = 0.0f;
+ float out_max_average_luminance = 0.0f;
+ float out_min_luminance = 0.0f;
+ if (hwc_display->GetHdrCapabilities(&out_num_types, hdr_caps.supportedHdrTypes.data(),
+ &out_max_luminance, &out_max_average_luminance,
+ &out_min_luminance)
+ == HWC2::Error::None) {
+ error = 0;
+ }
+ } while (false);
+
+ _hidl_cb(error, hdr_caps);
+
+ return Void();
+}
+
+Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) {
+ SCOPE_LOCK(locker_);
+
+ HWBwModes mode = on > 0 ? kBwCamera : kBwDefault;
+
+ // trigger invalidate to apply new bw caps.
+ Refresh(HWC_DISPLAY_PRIMARY);
+
+ if (core_intf_->SetMaxBandwidthMode(mode) != kErrorNone) {
+ return -EINVAL;
+ }
+
+ new_bw_mode_ = true;
+ need_invalidate_ = true;
+ hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
+
+ return 0;
+}
+
+int32_t HWCSession::DisplayBWTransactionPending(bool *status) {
+ SCOPE_LOCK(locker_);
+
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ if (sync_wait(bw_mode_release_fd_, 0) < 0) {
+ DLOGI("bw_transaction_release_fd is not yet signaled: err= %s", strerror(errno));
+ *status = false;
+ }
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+Return<void> HWCSession::displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) {
+ bool status = true;
+
+ int32_t error = DisplayBWTransactionPending(&status);
+
+ _hidl_cb(error, status);
+
+ return Void();
+}
+
+} // namespace sdm
diff --git a/sdm845/sdm/libs/hwc2/hwc_tonemapper.cpp b/msm8909w_3100/sdm/libs/hwc2/hwc_tonemapper.cpp
similarity index 75%
rename from sdm845/sdm/libs/hwc2/hwc_tonemapper.cpp
rename to msm8909w_3100/sdm/libs/hwc2/hwc_tonemapper.cpp
index 7bda725..a224e8d 100644
--- a/sdm845/sdm/libs/hwc2/hwc_tonemapper.cpp
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_tonemapper.cpp
@@ -49,18 +49,57 @@
namespace sdm {
-ToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator) :
- buffer_allocator_(buffer_allocator) {
+ToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator)
+ : tone_map_task_(*this), buffer_allocator_(buffer_allocator) {
buffer_info_.resize(kNumIntermediateBuffers);
}
ToneMapSession::~ToneMapSession() {
- delete gpu_tone_mapper_;
- gpu_tone_mapper_ = nullptr;
+ tone_map_task_.PerformTask(ToneMapTaskCode::kCodeDestroy, nullptr);
FreeIntermediateBuffers();
buffer_info_.clear();
}
+void ToneMapSession::OnTask(const ToneMapTaskCode &task_code,
+ SyncTask<ToneMapTaskCode>::TaskContext *task_context) {
+ switch (task_code) {
+ case ToneMapTaskCode::kCodeGetInstance: {
+ ToneMapGetInstanceContext *ctx = static_cast<ToneMapGetInstanceContext *>(task_context);
+ Lut3d &lut_3d = ctx->layer->lut_3d;
+ Color10Bit *grid_entries = NULL;
+ int grid_size = 0;
+ if (lut_3d.validGridEntries) {
+ grid_entries = lut_3d.gridEntries;
+ grid_size = INT(lut_3d.gridSize);
+ }
+ gpu_tone_mapper_ = TonemapperFactory_GetInstance(tone_map_config_.type,
+ lut_3d.lutEntries, lut_3d.dim,
+ grid_entries, grid_size,
+ tone_map_config_.secure);
+ }
+ break;
+
+ case ToneMapTaskCode::kCodeBlit: {
+ ToneMapBlitContext *ctx = static_cast<ToneMapBlitContext *>(task_context);
+ uint8_t buffer_index = current_buffer_index_;
+ const void *dst_hnd = reinterpret_cast<const void *>
+ (buffer_info_[buffer_index].private_data);
+ const void *src_hnd = reinterpret_cast<const void *>
+ (ctx->layer->input_buffer.buffer_id);
+ ctx->fence_fd = gpu_tone_mapper_->blit(dst_hnd, src_hnd, ctx->merged_fd);
+ }
+ break;
+
+ case ToneMapTaskCode::kCodeDestroy: {
+ delete gpu_tone_mapper_;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
DisplayError ToneMapSession::AllocateIntermediateBuffers(const Layer *layer) {
DisplayError error = kErrorNone;
for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) {
@@ -149,8 +188,8 @@
// then SDM marks them for SDE Composition because the cached FB layer gets displayed.
// GPU count will be 0 in this case. Try to use the existing tone-mapped frame buffer.
// No ToneMap/Blit is required. Just update the buffer & acquire fence fd of FB layer.
- if (!tone_map_sessions_.empty()) {
- ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(fb_session_index_);
+ if (!tone_map_sessions_.empty() && (fb_session_index_ >= 0)) {
+ ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(UINT32(fb_session_index_));
fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer);
fb_tone_map_session->layer_index_ = INT(i);
fb_tone_map_session->acquired_ = true;
@@ -158,7 +197,7 @@
}
}
error = AcquireToneMapSession(layer, &session_index);
- fb_session_index_ = session_index;
+ fb_session_index_ = INT(session_index);
break;
default:
error = AcquireToneMapSession(layer, &session_index);
@@ -180,35 +219,30 @@
}
void HWCToneMapper::ToneMap(Layer* layer, ToneMapSession *session) {
- int fence_fd = -1;
- int acquire_fd = -1;
- int merged_fd = -1;
+ ToneMapBlitContext ctx = {};
+ ctx.layer = layer;
uint8_t buffer_index = session->current_buffer_index_;
- const private_handle_t *dst_hnd = static_cast<private_handle_t *>
- (session->buffer_info_[buffer_index].private_data);
- const private_handle_t *src_hnd = reinterpret_cast<const private_handle_t *>
- (layer->input_buffer.buffer_id);
+ int &release_fence_fd = session->release_fence_fd_[buffer_index];
// use and close the layer->input_buffer acquire fence fd.
- acquire_fd = layer->input_buffer.acquire_fence_fd;
- buffer_sync_handler_.SyncMerge(session->release_fence_fd_[buffer_index], acquire_fd, &merged_fd);
+ int acquire_fd = layer->input_buffer.acquire_fence_fd;
+ buffer_sync_handler_.SyncMerge(release_fence_fd, acquire_fd, &ctx.merged_fd);
if (acquire_fd >= 0) {
CloseFd(&acquire_fd);
}
- if (session->release_fence_fd_[buffer_index] >= 0) {
- CloseFd(&session->release_fence_fd_[buffer_index]);
+ if (release_fence_fd >= 0) {
+ CloseFd(&release_fence_fd);
}
DTRACE_BEGIN("GPU_TM_BLIT");
- fence_fd = session->gpu_tone_mapper_->blit(reinterpret_cast<const void *>(dst_hnd),
- reinterpret_cast<const void *>(src_hnd), merged_fd);
+ session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeBlit, &ctx);
DTRACE_END();
- DumpToneMapOutput(session, &fence_fd);
- session->UpdateBuffer(fence_fd, &layer->input_buffer);
+ DumpToneMapOutput(session, &ctx.fence_fd);
+ session->UpdateBuffer(ctx.fence_fd, &layer->input_buffer);
}
void HWCToneMapper::PostCommit(LayerStack *layer_stack) {
@@ -227,6 +261,13 @@
} else {
delete session;
it = tone_map_sessions_.erase(it);
+ int deleted_session = INT(session_index);
+ // If FB tonemap session gets deleted, reset fb_session_index_, else update it.
+ if (deleted_session == fb_session_index_) {
+ fb_session_index_ = -1;
+ } else if (deleted_session < fb_session_index_) {
+ fb_session_index_--;
+ }
}
}
}
@@ -237,7 +278,7 @@
delete tone_map_sessions_.back();
tone_map_sessions_.pop_back();
}
- fb_session_index_ = 0;
+ fb_session_index_ = -1;
}
}
@@ -248,6 +289,7 @@
}
void HWCToneMapper::DumpToneMapOutput(ToneMapSession *session, int *acquire_fd) {
+ DisplayError error = kErrorNone;
if (!dump_frame_count_) {
return;
}
@@ -263,11 +305,17 @@
}
}
+ error = buffer_allocator_->MapBuffer(target_buffer, *acquire_fd);
+ if (error != kErrorNone) {
+ DLOGE("MapBuffer failed, base addr = %x", target_buffer->base);
+ return;
+ }
+
size_t result = 0;
char dump_file_name[PATH_MAX];
- snprintf(dump_file_name, sizeof(dump_file_name), "/data/misc/display/frame_dump_primary"
- "/tonemap_%dx%d_frame%d.raw", target_buffer->width, target_buffer->height,
- dump_frame_index_);
+ snprintf(dump_file_name, sizeof(dump_file_name), "%s/frame_dump_primary"
+ "/tonemap_%dx%d_frame%d.raw", HWCDebugHandler::DumpDir(), target_buffer->width,
+ target_buffer->height, dump_frame_index_);
FILE* fp = fopen(dump_file_name, "w+");
if (fp) {
@@ -281,14 +329,6 @@
}
DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index) {
- Color10Bit *grid_entries = NULL;
- int grid_size = 0;
-
- if (layer->lut_3d.validGridEntries) {
- grid_entries = layer->lut_3d.gridEntries;
- grid_size = INT(layer->lut_3d.gridSize);
- }
-
// When the property sdm.disable_hdr_lut_gen is set, the lutEntries and gridEntries in
// the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut
// for Tonemapping.
@@ -311,13 +351,15 @@
}
ToneMapSession *session = new ToneMapSession(buffer_allocator_);
+ if (!session) {
+ return kErrorMemory;
+ }
session->SetToneMapConfig(layer);
- session->gpu_tone_mapper_ = TonemapperFactory_GetInstance(session->tone_map_config_.type,
- layer->lut_3d.lutEntries,
- layer->lut_3d.dim,
- grid_entries, grid_size,
- session->tone_map_config_.secure);
+
+ ToneMapGetInstanceContext ctx;
+ ctx.layer = layer;
+ session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeGetInstance, &ctx);
if (session->gpu_tone_mapper_ == NULL) {
DLOGE("Get Tonemapper failed!");
diff --git a/sdm845/sdm/libs/hwc2/hwc_tonemapper.h b/msm8909w_3100/sdm/libs/hwc2/hwc_tonemapper.h
similarity index 83%
copy from sdm845/sdm/libs/hwc2/hwc_tonemapper.h
copy to msm8909w_3100/sdm/libs/hwc2/hwc_tonemapper.h
index 8367c3e..8bef3b1 100644
--- a/sdm845/sdm/libs/hwc2/hwc_tonemapper.h
+++ b/msm8909w_3100/sdm/libs/hwc2/hwc_tonemapper.h
@@ -37,6 +37,7 @@
#include <core/layer_stack.h>
#include <utils/sys.h>
+#include <utils/sync_task.h>
#include <vector>
#include "hwc_buffer_sync_handler.h"
#include "hwc_buffer_allocator.h"
@@ -45,6 +46,22 @@
namespace sdm {
+enum class ToneMapTaskCode : int32_t {
+ kCodeGetInstance,
+ kCodeBlit,
+ kCodeDestroy,
+};
+
+struct ToneMapGetInstanceContext : public SyncTask<ToneMapTaskCode>::TaskContext {
+ Layer *layer = nullptr;
+};
+
+struct ToneMapBlitContext : public SyncTask<ToneMapTaskCode>::TaskContext {
+ Layer *layer = nullptr;
+ int merged_fd = -1;
+ int fence_fd = -1;
+};
+
struct ToneMapConfig {
int type = 0;
ColorPrimaries colorPrimaries = ColorPrimaries_Max;
@@ -53,7 +70,7 @@
bool secure = false;
};
-class ToneMapSession {
+class ToneMapSession : public SyncTask<ToneMapTaskCode>::TaskHandler {
public:
explicit ToneMapSession(HWCBufferAllocator *buffer_allocator);
~ToneMapSession();
@@ -64,7 +81,12 @@
void SetToneMapConfig(Layer *layer);
bool IsSameToneMapConfig(Layer *layer);
+ // TaskHandler methods implementation.
+ virtual void OnTask(const ToneMapTaskCode &task_code,
+ SyncTask<ToneMapTaskCode>::TaskContext *task_context);
+
static const uint8_t kNumIntermediateBuffers = 2;
+ SyncTask<ToneMapTaskCode> tone_map_task_;
Tonemapper *gpu_tone_mapper_ = nullptr;
HWCBufferAllocator *buffer_allocator_ = nullptr;
ToneMapConfig tone_map_config_ = {};
@@ -96,7 +118,7 @@
HWCBufferAllocator *buffer_allocator_ = nullptr;
uint32_t dump_frame_count_ = 0;
uint32_t dump_frame_index_ = 0;
- uint32_t fb_session_index_ = 0;
+ int fb_session_index_ = -1;
};
} // namespace sdm
diff --git a/sdm845/sdm/libs/utils/Android.mk b/msm8909w_3100/sdm/libs/utils/Android.mk
similarity index 94%
copy from sdm845/sdm/libs/utils/Android.mk
copy to msm8909w_3100/sdm/libs/utils/Android.mk
index fe89104..09e1414 100644
--- a/sdm845/sdm/libs/utils/Android.mk
+++ b/msm8909w_3100/sdm/libs/utils/Android.mk
@@ -25,6 +25,7 @@
$(SDM_HEADER_PATH)/utils/locker.h \
$(SDM_HEADER_PATH)/utils/rect.h \
$(SDM_HEADER_PATH)/utils/sys.h \
+ $(SDM_HEADER_PATH)/utils/sync_task.h \
$(SDM_HEADER_PATH)/utils/utils.h \
$(SDM_HEADER_PATH)/utils/factory.h
diff --git a/sdm845/sdm/libs/utils/Makefile.am b/msm8909w_3100/sdm/libs/utils/Makefile.am
similarity index 100%
copy from sdm845/sdm/libs/utils/Makefile.am
copy to msm8909w_3100/sdm/libs/utils/Makefile.am
diff --git a/sdm845/sdm/libs/utils/debug.cpp b/msm8909w_3100/sdm/libs/utils/debug.cpp
similarity index 100%
rename from sdm845/sdm/libs/utils/debug.cpp
rename to msm8909w_3100/sdm/libs/utils/debug.cpp
diff --git a/sdm845/sdm/libs/utils/formats.cpp b/msm8909w_3100/sdm/libs/utils/formats.cpp
similarity index 100%
copy from sdm845/sdm/libs/utils/formats.cpp
copy to msm8909w_3100/sdm/libs/utils/formats.cpp
diff --git a/sdm845/sdm/libs/utils/rect.cpp b/msm8909w_3100/sdm/libs/utils/rect.cpp
similarity index 100%
rename from sdm845/sdm/libs/utils/rect.cpp
rename to msm8909w_3100/sdm/libs/utils/rect.cpp
diff --git a/sdm845/sdm/libs/utils/sys.cpp b/msm8909w_3100/sdm/libs/utils/sys.cpp
similarity index 100%
copy from sdm845/sdm/libs/utils/sys.cpp
copy to msm8909w_3100/sdm/libs/utils/sys.cpp
diff --git a/sdm845/sdm/libs/utils/utils.cpp b/msm8909w_3100/sdm/libs/utils/utils.cpp
similarity index 100%
copy from sdm845/sdm/libs/utils/utils.cpp
copy to msm8909w_3100/sdm/libs/utils/utils.cpp
diff --git a/msm8996/libgralloc1/Android.mk b/msm8996/libgralloc1/Android.mk
index 292ea47..0c2431a 100644
--- a/msm8996/libgralloc1/Android.mk
+++ b/msm8996/libgralloc1/Android.mk
@@ -5,6 +5,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := gralloc_headers
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+LOCAL_EXPORT_HEADER_LIBRARY_HEADERS := libhardware_headers liblog_headers
include $(BUILD_HEADER_LIBRARY)
include $(CLEAR_VARS)
@@ -15,6 +16,8 @@
LOCAL_C_INCLUDES := $(common_includes) \
external/libcxx/include/
+LOCAL_HEADER_LIBRARIES := libhardware_headers
+LOCAL_EXPORT_HEADER_LIBRARY_HEADERS := libhardware_headers liblog_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libsync
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -fPIC -Wall -std=c++11 -Werror
LOCAL_CFLAGS += -isystem $(kernel_includes)
diff --git a/msm8996/libgralloc1/gr_priv_handle.h b/msm8996/libgralloc1/gr_priv_handle.h
index b3184d1..5438491 100644
--- a/msm8996/libgralloc1/gr_priv_handle.h
+++ b/msm8996/libgralloc1/gr_priv_handle.h
@@ -22,7 +22,7 @@
#include <errno.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <hardware/gralloc1.h>
#include <hardware/gralloc.h>
#include <cinttypes>
diff --git a/msm8996/liblight/Android.mk b/msm8996/liblight/Android.mk
index 5d58311..4f84703 100644
--- a/msm8996/liblight/Android.mk
+++ b/msm8996/liblight/Android.mk
@@ -20,6 +20,7 @@
LOCAL_SRC_FILES := lights.c
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_PROPRIETARY_MODULE := true
+LOCAL_HEADER_LIBRARIES := libhardware_headers
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdlights\"
LOCAL_CLANG := true
diff --git a/msm8996/liblight/lights.c b/msm8996/liblight/lights.c
index 7a3775e..0ecfd03 100644
--- a/msm8996/liblight/lights.c
+++ b/msm8996/liblight/lights.c
@@ -18,7 +18,7 @@
// #define LOG_NDEBUG 0
-#include <cutils/log.h>
+#include <log/log.h>
#include <stdint.h>
#include <stdlib.h>
diff --git a/msm8996/libmemtrack/Android.mk b/msm8996/libmemtrack/Android.mk
index a73cfd7..4907b85 100644
--- a/msm8996/libmemtrack/Android.mk
+++ b/msm8996/libmemtrack/Android.mk
@@ -20,7 +20,7 @@
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_PROPRIETARY_MODULE := true
-LOCAL_C_INCLUDES += hardware/libhardware/include
+LOCAL_HEADER_LIBRARIES := libhardware_headers
LOCAL_CFLAGS := -Wconversion -Wall -Werror -Wno-sign-conversion
LOCAL_CLANG := true
LOCAL_SHARED_LIBRARIES := liblog
diff --git a/msm8996/libmemtrack/memtrack_msm.c b/msm8996/libmemtrack/memtrack_msm.c
index 4e4b78a..2f93017 100644
--- a/msm8996/libmemtrack/memtrack_msm.c
+++ b/msm8996/libmemtrack/memtrack_msm.c
@@ -17,7 +17,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
-#include <utils/Log.h>
+#include <log/log.h>
#include <hardware/memtrack.h>
diff --git a/msm8996/libqdutils/Android.mk b/msm8996/libqdutils/Android.mk
index 1f02c9e..c714ca0 100644
--- a/msm8996/libqdutils/Android.mk
+++ b/msm8996/libqdutils/Android.mk
@@ -5,6 +5,7 @@
LOCAL_MODULE := libqdutils
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_TAGS := optional
+LOCAL_HEADER_LIBRARIES := libhardware_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) libui libbinder libqservice
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdutils\" -Wno-sign-conversion
@@ -19,6 +20,7 @@
include $(CLEAR_VARS)
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+LOCAL_HEADER_LIBRARIES := libhardware_headers
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_C_INCLUDES := $(common_includes)
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
diff --git a/msm8996/libqservice/Android.mk b/msm8996/libqservice/Android.mk
index f635554..8b083e0 100644
--- a/msm8996/libqservice/Android.mk
+++ b/msm8996/libqservice/Android.mk
@@ -8,6 +8,7 @@
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SHARED_LIBRARIES := $(common_libs) libbinder
LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder
+LOCAL_HEADER_LIBRARIES := libcutils_headers
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdqservice\" -Wno-sign-conversion
LOCAL_CFLAGS += -Wno-error
LOCAL_CLANG := true
diff --git a/msm8996/sdm/libs/hwc2/hwc_display.cpp b/msm8996/sdm/libs/hwc2/hwc_display.cpp
index 10b2220..97652d1 100644
--- a/msm8996/sdm/libs/hwc2/hwc_display.cpp
+++ b/msm8996/sdm/libs/hwc2/hwc_display.cpp
@@ -135,7 +135,8 @@
// if the mode count is 1, then only native mode is supported, so just apply matrix w/o
// setting mode
- if (color_mode_transform_map_.size() > 1U) {
+ if ((color_mode_transform_map_.size() > 1U && current_color_mode_ != mode) ||
+ (current_color_transform_ != hint)) {
color_mode_transform = color_mode_transform_map_[mode][transform_hint];
DisplayError error = display_intf_->SetColorMode(color_mode_transform);
if (error != kErrorNone) {
@@ -143,7 +144,10 @@
// failure to force client composition
return HWC2::Error::Unsupported;
}
+ DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
}
+ current_color_mode_ = mode;
+ current_color_transform_ = hint;
if (use_matrix) {
DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, matrix);
@@ -154,10 +158,7 @@
}
}
- current_color_mode_ = mode;
- current_color_transform_ = hint;
CopyColorTransformMatrix(matrix, color_matrix_);
- DLOGV_IF(kTagQDCM, "Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
return HWC2::Error::None;
}
@@ -1673,6 +1674,10 @@
}
bool HWCDisplay::CanSkipValidate() {
+ if (solid_fill_enable_) {
+ return false;
+ }
+
for (auto hwc_layer : layer_set_) {
if (hwc_layer->NeedsValidation()) {
return false;
diff --git a/msm8996/sdm/libs/hwc2/hwc_display.h b/msm8996/sdm/libs/hwc2/hwc_display.h
index 9343209..b8fef4f 100644
--- a/msm8996/sdm/libs/hwc2/hwc_display.h
+++ b/msm8996/sdm/libs/hwc2/hwc_display.h
@@ -79,7 +79,10 @@
android_color_transform_t current_color_transform_ = HAL_COLOR_TRANSFORM_IDENTITY;
typedef std::map<android_color_transform_t, std::string> TransformMap;
std::map<android_color_mode_t, TransformMap> color_mode_transform_map_ = {};
- double color_matrix_[kColorTransformMatrixCount] = {0};
+ double color_matrix_[kColorTransformMatrixCount] = { 1.0, 0.0, 0.0, 0.0, \
+ 0.0, 1.0, 0.0, 0.0, \
+ 0.0, 0.0, 1.0, 0.0, \
+ 0.0, 0.0, 0.0, 1.0 };
};
class HWCDisplay : public DisplayEventHandler {
diff --git a/msm8996/sdm/libs/hwc2/hwc_layers.cpp b/msm8996/sdm/libs/hwc2/hwc_layers.cpp
index 580a59d..71e771b 100644
--- a/msm8996/sdm/libs/hwc2/hwc_layers.cpp
+++ b/msm8996/sdm/libs/hwc2/hwc_layers.cpp
@@ -165,6 +165,10 @@
}
HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
+ // Validation is required when the client changes the composition type
+ if (client_requested_ != type) {
+ needs_validate_ = true;
+ }
client_requested_ = type;
switch (type) {
case HWC2::Composition::Client:
diff --git a/msm8998/libgralloc1/gr_allocator.cpp b/msm8998/libgralloc1/gr_allocator.cpp
index 9adc24a..f82cb6c 100644
--- a/msm8998/libgralloc1/gr_allocator.cpp
+++ b/msm8998/libgralloc1/gr_allocator.cpp
@@ -524,14 +524,14 @@
}
// CPU read rarely
- if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) &&
- !(prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)) {
+ if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)
+ == GRALLOC1_PRODUCER_USAGE_CPU_READ) {
return true;
}
// CPU write rarely
- if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) &&
- !(prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) {
+ if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)
+ == GRALLOC1_PRODUCER_USAGE_CPU_WRITE) {
return true;
}
diff --git a/msm8998/libgralloc1/gr_buf_mgr.cpp b/msm8998/libgralloc1/gr_buf_mgr.cpp
index bd1ea22..b11b524 100644
--- a/msm8998/libgralloc1/gr_buf_mgr.cpp
+++ b/msm8998/libgralloc1/gr_buf_mgr.cpp
@@ -651,6 +651,7 @@
*color_space = HAL_CSC_ITU_R_709;
break;
case ColorPrimaries_BT601_6_525:
+ case ColorPrimaries_BT601_6_625:
*color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
break;
case ColorPrimaries_BT2020:
diff --git a/msm8998/sdm/libs/core/display_base.cpp b/msm8998/sdm/libs/core/display_base.cpp
index 51aea0d..9af8e80 100644
--- a/msm8998/sdm/libs/core/display_base.cpp
+++ b/msm8998/sdm/libs/core/display_base.cpp
@@ -557,13 +557,15 @@
for (uint32_t i = 0; i < layer_info.left_frame_roi.size(); i++) {
LayerRect &l_roi = layer_info.left_frame_roi.at(i);
- LayerRect &r_roi = layer_info.right_frame_roi.at(i);
DumpImpl::AppendString(buffer, length, "\nROI%d(L T R B) : LEFT(%d %d %d %d)", i,
INT(l_roi.left), INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom));
- if (IsValid(r_roi)) {
- DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left),
- INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
+ if (i < layer_info.right_frame_roi.size()) {
+ LayerRect &r_roi = layer_info.right_frame_roi.at(i);
+ if (IsValid(r_roi)) {
+ DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left),
+ INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
+ }
}
}
diff --git a/msm8998/sdm/libs/hwc2/hwc_display.cpp b/msm8998/sdm/libs/hwc2/hwc_display.cpp
index f0ea951..6b2e39d 100644
--- a/msm8998/sdm/libs/hwc2/hwc_display.cpp
+++ b/msm8998/sdm/libs/hwc2/hwc_display.cpp
@@ -452,6 +452,8 @@
metadata_refresh_rate_ = 0;
auto working_primaries = ColorPrimaries_BT709_5;
+ bool extended_range = false;
+
// Add one layer for fb target
// TODO(user): Add blit target layers
for (auto hwc_layer : layer_set_) {
@@ -469,6 +471,11 @@
#endif
}
+ auto range = hwc_layer->GetLayerDataspace() & HAL_DATASPACE_RANGE_MASK;
+ if(range == HAL_DATASPACE_RANGE_EXTENDED) {
+ extended_range = true;
+ }
+
working_primaries = WidestPrimaries(working_primaries,
layer->input_buffer.color_metadata.colorPrimaries);
@@ -573,7 +580,7 @@
// fall back frame composition to GPU when client target is 10bit
// TODO(user): clarify the behaviour from Client(SF) and SDM Extn -
// when handling 10bit FBT, as it would affect blending
- if (Is10BitFormat(sdm_client_target->input_buffer.format)) {
+ if (Is10BitFormat(sdm_client_target->input_buffer.format) || extended_range) {
// Must fall back to client composition
MarkLayersForClientComposition();
}
@@ -1090,8 +1097,8 @@
HWC2::Error HWCDisplay::CommitLayerStack(void) {
- if (shutdown_pending_ || layer_set_.empty()) {
- return HWC2::Error::None;
+ if (skip_validate_ && !CanSkipValidate()) {
+ validated_ = false;
}
if (!validated_) {
@@ -1099,10 +1106,9 @@
return HWC2::Error::NotValidated;
}
- if (skip_validate_ && !CanSkipValidate()) {
- DLOGV_IF(kTagCompManager, "Cannot skip validate on display: %d", id_);
- validated_ = false;
- return HWC2::Error::NotValidated;
+
+ if (shutdown_pending_ || layer_set_.empty()) {
+ return HWC2::Error::None;
}
DumpInputBuffers();
@@ -1189,8 +1195,11 @@
close(layer_buffer->acquire_fence_fd);
layer_buffer->acquire_fence_fd = -1;
}
+
+ layer->request.flags = {};
}
+ client_target_->GetSDMLayer()->request.flags = {};
*out_retire_fence = -1;
if (!flush_) {
// if swapinterval property is set to 0 then close and reset the list retire fence
@@ -1210,8 +1219,6 @@
geometry_changes_ = GeometryChanges::kNone;
flush_ = false;
- ClearRequestFlags();
-
return status;
}
@@ -1642,6 +1649,7 @@
Layer *layer = hwc_layer->GetSDMLayer();
layer->flags.skip = true;
}
+ layer_stack_.flags.skip_present = true;
}
void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
@@ -1845,12 +1853,6 @@
}
}
-void HWCDisplay::ClearRequestFlags() {
- for (Layer *layer : layer_stack_.layers) {
- layer->request.flags = {};
- }
-}
-
std::string HWCDisplay::Dump() {
std::ostringstream os;
os << "-------------------------------" << std::endl;
@@ -1881,6 +1883,10 @@
}
bool HWCDisplay::CanSkipValidate() {
+ if (solid_fill_enable_) {
+ return false;
+ }
+
// Layer Stack checks
if (layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) {
return false;
diff --git a/msm8998/sdm/libs/hwc2/hwc_display.h b/msm8998/sdm/libs/hwc2/hwc_display.h
index 20ab05a..a4ecced 100644
--- a/msm8998/sdm/libs/hwc2/hwc_display.h
+++ b/msm8998/sdm/libs/hwc2/hwc_display.h
@@ -238,7 +238,6 @@
bool IsLayerUpdating(const Layer *layer);
uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
virtual void CloseAcquireFds();
- virtual void ClearRequestFlags();
virtual void GetUnderScanConfig() { }
enum {
diff --git a/msm8998/sdm/libs/hwc2/hwc_layers.cpp b/msm8998/sdm/libs/hwc2/hwc_layers.cpp
index be1ac08..1365ee1 100644
--- a/msm8998/sdm/libs/hwc2/hwc_layers.cpp
+++ b/msm8998/sdm/libs/hwc2/hwc_layers.cpp
@@ -119,8 +119,11 @@
case HAL_DATASPACE_TRANSFER_GAMMA2_2:
*gamma_transfer = Transfer_Gamma2_2;
break;
+ case HAL_DATASPACE_TRANSFER_GAMMA2_8:
+ *gamma_transfer = Transfer_Gamma2_8;
+ break;
default:
- DLOGV_IF(kTagStrategy, "Unsupported Transfer Request = %d", transfer);
+ DLOGE("Unsupported Transfer Request = %d", transfer);
supported_transfer = false;
}
return supported_transfer;
@@ -256,10 +259,13 @@
layer_buffer->flags.secure_camera = secure_camera;
layer_buffer->flags.secure_display = secure_display;
+ if (layer_buffer->acquire_fence_fd >= 0) {
+ close(layer_buffer->acquire_fence_fd);
+ }
+ layer_buffer->acquire_fence_fd = acquire_fence;
layer_buffer->planes[0].fd = ion_fd_;
layer_buffer->planes[0].offset = handle->offset;
layer_buffer->planes[0].stride = UINT32(handle->width);
- layer_buffer->acquire_fence_fd = acquire_fence;
layer_buffer->size = handle->size;
layer_buffer->buffer_id = reinterpret_cast<uint64_t>(handle);
layer_buffer->fb_id = 0;
@@ -326,6 +332,10 @@
}
HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
+ // Validation is required when the client changes the composition type
+ if (client_requested_ != type) {
+ needs_validate_ = true;
+ }
client_requested_ = type;
switch (type) {
case HWC2::Composition::Client:
@@ -611,6 +621,9 @@
case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
format = kFormatYCbCr420TP10Ubwc;
break;
+ case HAL_PIXEL_FORMAT_RGBA_FP16:
+ format = kFormatInvalid;
+ break;
default:
DLOGW("Unsupported format type = %d", source);
return kFormatInvalid;
diff --git a/sdm845/Makefile.am b/sdm845/Makefile.am
deleted file mode 100644
index 781b836..0000000
--- a/sdm845/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-# Makefile.am - Automake script for sdm
-
-ACLOCAL_AMFLAGS = -I m4
-
-SUBDIRS = libqservice libqdutils libgralloc sdm/libs/utils sdm/libs/core
diff --git a/sdm845/configure.ac b/sdm845/configure.ac
deleted file mode 100644
index 6fe7d0a..0000000
--- a/sdm845/configure.ac
+++ /dev/null
@@ -1,57 +0,0 @@
-# -*- Autoconf -*-
-# configure.ac -- Autoconf script for sdm
-#
-
-# Process this file with autoconf to produce a configure script
-
-# Requires autoconf tool later than 2.61
-AC_PREREQ(2.61)
-# Initialize the display package version 1.0.0
-AC_INIT([display],1.0.0)
-# Does not strictly follow GNU Coding standards
-AM_INIT_AUTOMAKE([foreign])
-# Disables auto rebuilding of configure, Makefile.ins
-AM_MAINTAINER_MODE
-# defines some macros variable to be included by source
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_MACRO_DIR([m4])
-AC_SUBST([COMMON_CFLAGS], [-Wall -Werror -Wno-sign-conversion -Wconversion -DDEBUG_CALC_FPS])
-AC_SUBST([AM_CPPFLAGS], [--std=c++11])
-
-AC_ARG_WITH([core_includes],
- AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
- [Specify the location of the core headers]),
- [core_incdir=$withval],
- with_core_includes=no)
-
-if test "x$with_core_includes" != "xno"; then
- CFLAGS="${CFLAGS} -I${core_incdir}"
-fi
-
-AC_ARG_WITH(sanitized-headers,
- AS_HELP_STRING([--with-sanitized-headers=DIR],
- [Specify the location of the sanitized Linux headers]),
- [CPPFLAGS="$CPPFLAGS -idirafter $withval"])
-
-# Checks for programs.
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_CXX
-AC_PROG_LIBTOOL
-AC_PROG_AWK
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-
-AC_SUBST([CFLAGS])
-AC_SUBST([CC])
-AC_CONFIG_FILES([ \
- Makefile \
- libqservice/Makefile \
- libqdutils/Makefile \
- libgralloc/Makefile \
- sdm/libs/utils/Makefile \
- sdm/libs/core/Makefile
- ])
-AC_OUTPUT
\ No newline at end of file
diff --git a/sdm845/hdmi_cec/QHDMIClient.cpp b/sdm845/hdmi_cec/QHDMIClient.cpp
deleted file mode 100644
index 2b2b1e6..0000000
--- a/sdm845/hdmi_cec/QHDMIClient.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-* Copyright (c) 2014 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation. nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#define DEBUG 0
-#include <QServiceUtils.h>
-#include "QHDMIClient.h"
-
-using namespace android;
-using namespace qhdmicec;
-using namespace qService;
-
-namespace qClient {
-
-void QHDMIClient::binderDied(const wp<IBinder>& who __unused)
-{
- ALOGW("%s: Display QService died", __FUNCTION__);
-}
-
-void QHDMIClient::onHdmiHotplug(int connected)
-{
- ALOGD("%s: HDMI connected event connected: %d", __FUNCTION__, connected);
- cec_hdmi_hotplug(mCtx, connected);
-}
-
-void QHDMIClient::onCECMessageRecieved(char *msg, ssize_t len)
-{
- ALOGD_IF(DEBUG, "%s: CEC message received len: %zd", __FUNCTION__, len);
- cec_receive_message(mCtx, msg, len);
-}
-
-void QHDMIClient::registerClient(sp<QHDMIClient>& client)
-{
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("display.qservice"));
- binder->linkToDeath(client);
- mQService = interface_cast<IQService>(binder);
- mQService->connect(interface_cast<IQHDMIClient>(client));
-}
-
-};
diff --git a/sdm845/hdmi_cec/QHDMIClient.h b/sdm845/hdmi_cec/QHDMIClient.h
deleted file mode 100644
index 9e54f2f..0000000
--- a/sdm845/hdmi_cec/QHDMIClient.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-* Copyright (c) 2014 The Linux Foundation. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided
-* with the distribution.
-* * Neither the name of The Linux Foundation. nor the names of its
-* contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "IQHDMIClient.h"
-#include "qhdmi_cec.h"
-#include <IQService.h>
-
-namespace qClient {
-
-class QHDMIClient: public android::IBinder::DeathRecipient,
- public BnQHDMIClient
-{
-public:
- QHDMIClient() {}
-
- virtual void binderDied(const android::wp<android::IBinder>& who);
-
- virtual void onHdmiHotplug(int connected);
-
- virtual void onCECMessageRecieved(char *msg, ssize_t len);
-
- void setCECContext(qhdmicec::cec_context_t* ctx) { mCtx = ctx; }
-
- void registerClient(android::sp<QHDMIClient>& client);
-
-private:
- qhdmicec::cec_context_t* mCtx;
- android::sp<qService::IQService> mQService;
-
-};
-};
diff --git a/sdm845/sdm/libs/core/drm/hw_virtual_drm.cpp b/sdm845/sdm/libs/core/drm/hw_virtual_drm.cpp
deleted file mode 100644
index 5fe1d86..0000000
--- a/sdm845/sdm/libs/core/drm/hw_virtual_drm.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-Copyright (c) 2017, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <ctype.h>
-#include <drm_logger.h>
-#include <utils/debug.h>
-#include "hw_device_drm.h"
-#include "hw_virtual_drm.h"
-#include "hw_info_drm.h"
-
-#define __CLASS__ "HWVirtualDRM"
-
-using sde_drm::DRMDisplayType;
-using sde_drm::DRMConnectorInfo;
-using sde_drm::DRMRect;
-using sde_drm::DRMOps;
-
-namespace sdm {
-
-HWVirtualDRM::HWVirtualDRM(BufferSyncHandler *buffer_sync_handler,
- BufferAllocator *buffer_allocator,
- HWInfoInterface *hw_info_intf)
- : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
- HWDeviceDRM::deferred_initialize_ = true;
- HWDeviceDRM::device_name_ = "Virtual Display Device";
- HWDeviceDRM::hw_info_intf_ = hw_info_intf;
- HWDeviceDRM::disp_type_ = DRMDisplayType::VIRTUAL;
-}
-
-DisplayError HWVirtualDRM::Init() {
- return kErrorNone;
-}
-
-DisplayError HWVirtualDRM::DeferredInit() {
- if (HWDeviceDRM::Init() != kErrorNone)
- return kErrorResources;
-
- drm_mgr_intf_->SetScalerLUT(drm_lut_info_);
- DLOGI_IF(kTagDriverConfig, "Setup CRTC %d, Connector %d for %s",
- token_.crtc_id, token_.conn_id, device_name_);
-
- return kErrorNone;
-}
-
-void HWVirtualDRM::ConfigureWbConnectorFbId(uint32_t fb_id) {
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_OUTPUT_FB_ID, token_.conn_id, fb_id);
- return;
-}
-
-void HWVirtualDRM::ConfigureWbConnectorDestRect() {
- DRMRect dst = {};
- dst.left = 0;
- dst.bottom = height_;
- dst.top = 0;
- dst.right = width_;
- drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_OUTPUT_RECT, token_.conn_id, dst);
- return;
-}
-
-void HWVirtualDRM::InitializeConfigs() {
- current_mode_.hdisplay = current_mode_.hsync_start = current_mode_.hsync_end \
- = current_mode_.htotal = (uint16_t) width_;
- current_mode_.vdisplay = current_mode_.vsync_start = current_mode_.vsync_end \
- = current_mode_.vtotal = (uint16_t) height_;
- // Not sure SF has a way to configure refresh rate. Hardcoding to 60 fps for now.
- // TODO(user): Make this configurable.
- current_mode_.vrefresh = 60;
- current_mode_.clock = (current_mode_.htotal * current_mode_.vtotal \
- * current_mode_.vrefresh) / 1000;
- struct sde_drm_wb_cfg wb_cfg;
- wb_cfg.connector_id = token_.conn_id;
- wb_cfg.flags |= SDE_DRM_WB_CFG_FLAGS_CONNECTED;
- wb_cfg.count_modes = 1;
- wb_cfg.modes = (uint64_t)¤t_mode_;
- #ifdef DRM_IOCTL_SDE_WB_CONFIG
- int ret = drmIoctl(dev_fd_, DRM_IOCTL_SDE_WB_CONFIG, &wb_cfg);
- #endif
- if (ret) {
- DLOGE("WB config failed\n");
- } else {
- drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
- current_mode_ = connector_info_.modes[0];
- DumpConfigs();
- }
-}
-
-void HWVirtualDRM::DumpConfigs() {
- for (uint32_t i = 0; i < (uint32_t)connector_info_.num_modes; i++) {
- DLOGI(
- "Name: %s\tvref: %d\thdisp: %d\t hsync_s: %d\thsync_e:%d\thtotal: %d\t"
- "vdisp: %d\tvsync_s: %d\tvsync_e: %d\tvtotal: %d\n",
- connector_info_.modes[i].name, connector_info_.modes[i].vrefresh,
- connector_info_.modes[i].hdisplay,
- connector_info_.modes[i].hsync_start, connector_info_.modes[i].hsync_end,
- connector_info_.modes[i].htotal, connector_info_.modes[i].vdisplay,
- connector_info_.modes[i].vsync_start, connector_info_.modes[i].vsync_end,
- connector_info_.modes[i].vtotal);
- }
-}
-
-DisplayError HWVirtualDRM::Commit(HWLayers *hw_layers) {
- LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
- DisplayError err = kErrorNone;
-
- registry_.RegisterCurrent(hw_layers);
- registry_.MapBufferToFbId(output_buffer);
- uint32_t fb_id = registry_.GetFbId(output_buffer->planes[0].fd);
-
- ConfigureWbConnectorFbId(fb_id);
- ConfigureWbConnectorDestRect();
-
- err = HWDeviceDRM::AtomicCommit(hw_layers);
- registry_.UnregisterNext();
- return(err);
-}
-
-DisplayError HWVirtualDRM::Validate(HWLayers *hw_layers) {
- // TODO(user) : Add validate support
- return kErrorNone;
-}
-
-
-DisplayError HWVirtualDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
- if (display_attributes.x_pixels == 0 || display_attributes.y_pixels == 0) {
- return kErrorParameters;
- }
-
- display_attributes_ = display_attributes;
-
- if (display_attributes_.x_pixels > hw_resource_.max_mixer_width) {
- display_attributes_.is_device_split = true;
- }
-
- width_ = display_attributes_.x_pixels;
- height_ = display_attributes_.y_pixels;
- DeferredInit();
-
- return kErrorNone;
-}
-
-DisplayError HWVirtualDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
- return kErrorNone;
-}
-
-DisplayError HWVirtualDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
- drm_lut_info_.cir_lut = lut_info->cir_lut;
- drm_lut_info_.dir_lut = lut_info->dir_lut;
- drm_lut_info_.sep_lut = lut_info->sep_lut;
- drm_lut_info_.cir_lut_size = lut_info->cir_lut_size;
- drm_lut_info_.dir_lut_size = lut_info->dir_lut_size;
- drm_lut_info_.sep_lut_size = lut_info->sep_lut_size;
-
- // Due to differed Init in WB case, we cannot set scaler config immediately as we
- // won't have SDE DRM initialized at this point. Hence have to cache LUT info here
- // and set it in ::DeferredInit
-
- return kErrorNone;
-}
-
-} // namespace sdm
-
diff --git a/sdm845/sdm/libs/core/drm/hw_virtual_drm.h b/sdm845/sdm/libs/core/drm/hw_virtual_drm.h
deleted file mode 100644
index b63519a..0000000
--- a/sdm845/sdm/libs/core/drm/hw_virtual_drm.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-Copyright (c) 2017, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __HW_VIRTUAL_DRM_H__
-#define __HW_VIRTUAL_DRM_H__
-
-#include "hw_device_drm.h"
-#include <drm/msm_drm.h>
-#include <drm/sde_drm.h>
-
-namespace sdm {
-
-class HWVirtualDRM : public HWDeviceDRM {
- public:
- HWVirtualDRM(BufferSyncHandler *buffer_sync_handler,
- BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf);
- virtual ~HWVirtualDRM() {}
- virtual DisplayError SetVSyncState(bool enable) { return kErrorNotSupported; }
- virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
- return kErrorNotSupported;
- }
- virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
-
- protected:
- virtual DisplayError Init();
- virtual DisplayError Validate(HWLayers *hw_layers);
- virtual DisplayError DeferredInit();
- virtual void InitializeConfigs();
- virtual DisplayError Commit(HWLayers *hw_layers);
- virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
- virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
- void ConfigureWbConnectorFbId(uint32_t fb_id);
- void ConfigureWbConnectorDestRect();
- void DumpConfigs();
-
- private:
- uint32_t width_ = 0;
- uint32_t height_ = 0;
- sde_drm::DRMScalerLUTInfo drm_lut_info_ = {};
-};
-
-} // namespace sdm
-
-#endif // __HW_VIRTUAL_DRM_H__
-
diff --git a/sdm845/sdm/libs/hwc2/hwc_session.h b/sdm845/sdm/libs/hwc2/hwc_session.h
deleted file mode 100644
index 7d31a3a..0000000
--- a/sdm845/sdm/libs/hwc2/hwc_session.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright 2015 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.
- */
-
-#ifndef __HWC_SESSION_H__
-#define __HWC_SESSION_H__
-
-#include <core/core_interface.h>
-#include <utils/locker.h>
-
-#include "hwc_callbacks.h"
-#include "hwc_layers.h"
-#include "hwc_display.h"
-#include "hwc_display_primary.h"
-#include "hwc_display_external.h"
-#include "hwc_display_virtual.h"
-#include "hwc_color_manager.h"
-#include "hwc_socket_handler.h"
-
-namespace sdm {
-
-class HWCSession : hwc2_device_t, public qClient::BnQClient {
- public:
- struct HWCModuleMethods : public hw_module_methods_t {
- HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; }
- };
-
- explicit HWCSession(const hw_module_t *module);
- int Init();
- int Deinit();
- HWC2::Error CreateVirtualDisplayObject(uint32_t width, uint32_t height, int32_t *format);
-
- template <typename... Args>
- static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display,
- HWC2::Error (HWCDisplay::*member)(Args...), Args... args) {
- if (!device) {
- return HWC2_ERROR_BAD_DISPLAY;
- }
-
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- auto status = HWC2::Error::BadDisplay;
- if (hwc_session->hwc_display_[display]) {
- auto hwc_display = hwc_session->hwc_display_[display];
- status = (hwc_display->*member)(std::forward<Args>(args)...);
- }
- return INT32(status);
- }
-
- template <typename... Args>
- static int32_t CallLayerFunction(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args...),
- Args... args) {
- if (!device) {
- return HWC2_ERROR_BAD_DISPLAY;
- }
-
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- int32_t status = INT32(HWC2::Error::BadDisplay);
- if (hwc_session->hwc_display_[display]) {
- status = hwc_session->hwc_display_[display]->CallLayerFunction(layer, member, args...);
- }
- return status;
- }
-
- // HWC2 Functions that require a concrete implementation in hwc session
- // and hence need to be member functions
- static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display);
- static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t *out_layer_id);
- static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
- int32_t *format, hwc2_display_t *out_display_id);
- static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer);
- static int32_t DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display);
- static void Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer);
- static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
- int32_t *out_retire_fence);
- static int32_t RegisterCallback(hwc2_device_t *device, int32_t descriptor,
- hwc2_callback_data_t callback_data,
- hwc2_function_pointer_t pointer);
- static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
- buffer_handle_t buffer, int32_t releaseFence);
- static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- uint32_t z);
- static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode);
- static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
- uint32_t *out_num_types, uint32_t *out_num_requests);
- static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display,
- int32_t /*android_color_mode_t*/ int_mode);
- static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
- const float *matrix, int32_t /*android_color_transform_t*/ hint);
-
- private:
- static const int kExternalConnectionTimeoutMs = 500;
- static const int kPartialUpdateControlTimeoutMs = 100;
-
- // hwc methods
- static int Open(const hw_module_t *module, const char *name, hw_device_t **device);
- static int Close(hw_device_t *device);
- static void GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
- int32_t *outCapabilities);
- static hwc2_function_pointer_t GetFunction(struct hwc2_device *device, int32_t descriptor);
-
- // Uevent thread
- static void *HWCUeventThread(void *context);
- void *HWCUeventThreadHandler();
- int GetEventValue(const char *uevent_data, int length, const char *event_info);
- int HotPlugHandler(bool connected);
- void ResetPanel();
- int32_t ConnectDisplay(int disp);
- int DisconnectDisplay(int disp);
- int GetVsyncPeriod(int disp);
-
- // QClient methods
- virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- void DynamicDebug(const android::Parcel *input_parcel);
- void SetFrameDumpConfig(const android::Parcel *input_parcel);
- android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
- android::status_t SetDisplayMode(const android::Parcel *input_parcel);
- android::status_t SetSecondaryDisplayStatus(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t ToggleScreenUpdates(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
- android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t ControlPartialUpdate(const android::Parcel *input_parcel, android::Parcel *out);
- android::status_t OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t SetPanelBrightness(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t GetPanelBrightness(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- // These functions return the actual display config info as opposed to FB
- android::status_t HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t HandleGetActiveDisplayConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t HandleGetDisplayConfigCount(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t HandleGetDisplayAttributesForConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t GetVisibleDisplayRect(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
-
- android::status_t SetDynamicBWForCamera(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t GetBWTransactionStatus(const android::Parcel *input_parcel,
- android::Parcel *output_parcel);
- android::status_t SetMixerResolution(const android::Parcel *input_parcel);
-
- android::status_t SetColorModeOverride(const android::Parcel *input_parcel);
-
- android::status_t SetColorModeById(const android::Parcel *input_parcel);
-
- static Locker locker_;
- CoreInterface *core_intf_ = NULL;
- HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {NULL};
- HWCCallbacks callbacks_;
- pthread_t uevent_thread_;
- bool uevent_thread_exit_ = false;
- const char *uevent_thread_name_ = "HWC_UeventThread";
- HWCBufferAllocator *buffer_allocator_;
- HWCBufferSyncHandler buffer_sync_handler_;
- HWCColorManager *color_mgr_ = NULL;
- bool reset_panel_ = false;
- bool secure_display_active_ = false;
- bool external_pending_connect_ = false;
- bool new_bw_mode_ = false;
- bool need_invalidate_ = false;
- int bw_mode_release_fd_ = -1;
- qService::QService *qservice_ = NULL;
- HWCSocketHandler socket_handler_;
-};
-
-} // namespace sdm
-
-#endif // __HWC_SESSION_H__