Merge "sdm: Add virtual pipe listing support"
diff --git a/common.mk b/common.mk
index 941b0a4..88d1aee 100644
--- a/common.mk
+++ b/common.mk
@@ -4,9 +4,7 @@
#Common C flags
common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
common_flags += -Wconversion -Wall -Werror -std=c++11
-ifneq ($(TARGET_IS_HEADLESS), true)
- common_flags += -DCOMPILE_DRM
-else
+ifeq ($(TARGET_IS_HEADLESS), true)
common_flags += -DTARGET_HEADLESS
LOCAL_CLANG := false
endif
@@ -50,7 +48,6 @@
common_includes += $(display_top)/gpu_tonemapper
ifneq ($(TARGET_IS_HEADLESS), true)
common_includes += $(display_top)/libcopybit
- common_includes += $(display_top)/libdrmutils
endif
common_includes += $(display_top)/include
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 6e87b71..8c97215 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -116,6 +116,12 @@
*/
PLANE_SET_INPUT_FENCE,
/*
+ * Op: Sets scaler config on this plane.
+ * Arg: uint32_t - Plane ID
+ * uint64_t - Address of the scaler config object (version based)
+ */
+ PLANE_SET_SCALER_CONFIG,
+ /*
* Op: Activate or deactivate a CRTC
* Arg: uint32_t - CRTC ID
* uint32_t - 1 to enable, 0 to disable
@@ -308,6 +314,15 @@
void *payload;
};
+struct DRMScalerLUTInfo {
+ uint32_t dir_lut_size = 0;
+ uint32_t cir_lut_size = 0;
+ uint32_t sep_lut_size = 0;
+ uint64_t dir_lut = 0;
+ uint64_t cir_lut = 0;
+ uint64_t sep_lut = 0;
+};
+
/* DRM Atomic Request Property Set.
*
* Helper class to create and populate atomic properties of DRM components
@@ -416,6 +431,13 @@
* [return]: Error code if the API fails, 0 on success.
*/
virtual int DestroyAtomicReq(DRMAtomicReqInterface *intf) = 0;
+ /*
+ * Sets the global scaler LUT
+ * [input]: LUT Info
+ * [return]: Error code if the API fails, 0 on success.
+ */
+ virtual int SetScalerLUT(const DRMScalerLUTInfo &lut_info) = 0;
};
+
} // namespace sde_drm
#endif // __DRM_INTERFACE_H__
diff --git a/libdrmutils/drm_master.cpp b/libdrmutils/drm_master.cpp
index e12b933..09e0729 100644
--- a/libdrmutils/drm_master.cpp
+++ b/libdrmutils/drm_master.cpp
@@ -94,8 +94,9 @@
dev_fd_ = -1;
}
-int DRMMaster::CreateFbId(const DRMBuffer &drm_buffer, uint32_t *gem_handle, uint32_t *fb_id) {
- int ret = drmPrimeFDToHandle(dev_fd_, drm_buffer.fd, gem_handle);
+int DRMMaster::CreateFbId(const DRMBuffer &drm_buffer, uint32_t *fb_id) {
+ uint32_t gem_handle = 0;
+ int ret = drmPrimeFDToHandle(dev_fd_, drm_buffer.fd, &gem_handle);
if (ret) {
DRM_LOGE("drmPrimeFDToHandle failed with error %d", ret);
return ret;
@@ -106,7 +107,7 @@
cmd2.height = drm_buffer.height;
cmd2.pixel_format = drm_buffer.drm_format;
cmd2.flags = DRM_MODE_FB_MODIFIERS;
- fill(begin(cmd2.handles), begin(cmd2.handles) + drm_buffer.num_planes, *gem_handle);
+ fill(begin(cmd2.handles), begin(cmd2.handles) + drm_buffer.num_planes, gem_handle);
copy(begin(drm_buffer.stride), end(drm_buffer.stride), begin(cmd2.pitches));
copy(begin(drm_buffer.offset), end(drm_buffer.offset), begin(cmd2.offsets));
fill(begin(cmd2.modifier), begin(cmd2.modifier) + drm_buffer.num_planes,
@@ -114,28 +115,23 @@
if ((ret = drmIoctl(dev_fd_, DRM_IOCTL_MODE_ADDFB2, &cmd2))) {
DRM_LOGE("DRM_IOCTL_MODE_ADDFB2 failed with error %d", ret);
- struct drm_gem_close gem_close = {};
- gem_close.handle = *gem_handle;
- int ret1 = drmIoctl(dev_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
- if (ret1) {
- DRM_LOGE("drmIoctl::DRM_IOCTL_GEM_CLOSE failed with error %d", ret1);
- return ret1;
- }
- return ret;
+ } else {
+ *fb_id = cmd2.fb_id;
}
- *fb_id = cmd2.fb_id;
- return 0;
-}
-
-int DRMMaster::RemoveFbId(uint32_t gem_handle, uint32_t fb_id) {
struct drm_gem_close gem_close = {};
gem_close.handle = gem_handle;
- int ret = drmIoctl(dev_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
- if (ret) {
- DRM_LOGE("drmIoctl::DRM_IOCTL_GEM_CLOSE failed with error %d", errno);
+ int ret1 = drmIoctl(dev_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
+ if (ret1) {
+ DRM_LOGE("drmIoctl::DRM_IOCTL_GEM_CLOSE failed with error %d", ret1);
+ return ret1;
}
+ return ret;
+}
+
+int DRMMaster::RemoveFbId(uint32_t fb_id) {
+ int ret = 0;
#ifdef DRM_IOCTL_MSM_RMFB2
ret = drmIoctl(dev_fd_, DRM_IOCTL_MSM_RMFB2, &fb_id);
if (ret) {
diff --git a/libdrmutils/drm_master.h b/libdrmutils/drm_master.h
index 15fae68..52a8b02 100644
--- a/libdrmutils/drm_master.h
+++ b/libdrmutils/drm_master.h
@@ -58,14 +58,14 @@
* Returns:
* ioctl error code
*/
- int CreateFbId(const DRMBuffer &drm_buffer, uint32_t *gem_handle, uint32_t *fb_id);
+ int CreateFbId(const DRMBuffer &drm_buffer, uint32_t *fb_id);
/* Removes the fb_id from DRM
* Input:
* fb_id: DRM FB to be removed
* Returns:
* ioctl error code
*/
- int RemoveFbId(uint32_t gem_handle, uint32_t fb_id);
+ int RemoveFbId(uint32_t fb_id);
/* Poplulates master DRM fd
* Input:
* fd: Pointer to store master fd into
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
index b911999..76be57d 100644
--- a/libgralloc/Android.mk
+++ b/libgralloc/Android.mk
@@ -30,7 +30,7 @@
LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) libmemalloc libqdMetaData libqdutils
ifneq ($(TARGET_IS_HEADLESS), true)
-LOCAL_SHARED_LIBRARIES += libGLESv1_CM libdrmutils
+LOCAL_SHARED_LIBRARIES += libGLESv1_CM
endif
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 38e2050..1779312 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -27,9 +27,6 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef COMPILE_DRM
-#include <drm/drm_fourcc.h>
-#endif
#include <cutils/log.h>
#include <fcntl.h>
#include <dlfcn.h>
@@ -76,18 +73,6 @@
#define ION_SC_PREVIEW_FLAGS ION_SECURE
#endif
-#ifdef COMPILE_DRM
-#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
-#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
-#endif
-#ifndef DRM_FORMAT_MOD_QCOM_DX
-#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
-#endif
-#ifndef DRM_FORMAT_MOD_QCOM_TIGHT
-#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
-#endif
-#endif
-
#ifndef COLOR_FMT_P010_UBWC
#define COLOR_FMT_P010_UBWC 9
#endif
@@ -1140,9 +1125,8 @@
return err;
}
-#ifdef COMPILE_DRM
-int getPlaneStrideOffset(private_handle_t *hnd, uint32_t *stride,
- uint32_t *offset, uint32_t *num_planes) {
+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;
}
@@ -1231,110 +1215,3 @@
return 0;
}
-
-void getDRMFormat(int hal_format, int flags, uint32_t *drm_format,
- uint64_t *drm_format_modifier) {
-
- if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
- *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
- }
-
- switch (hal_format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- *drm_format = DRM_FORMAT_ABGR8888;
- break;
- case HAL_PIXEL_FORMAT_RGBA_5551:
- *drm_format = DRM_FORMAT_ABGR1555;
- break;
- case HAL_PIXEL_FORMAT_RGBA_4444:
- *drm_format = DRM_FORMAT_ABGR4444;
- break;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- *drm_format = DRM_FORMAT_ARGB8888;
- break;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- *drm_format = DRM_FORMAT_XBGR8888;
- break;
- case HAL_PIXEL_FORMAT_BGRX_8888:
- *drm_format = DRM_FORMAT_XRGB8888;
- break;
- case HAL_PIXEL_FORMAT_RGB_888:
- *drm_format = DRM_FORMAT_BGR888;
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- *drm_format = DRM_FORMAT_BGR565;
- break;
- case HAL_PIXEL_FORMAT_BGR_565:
- *drm_format = DRM_FORMAT_RGB565;
- break;
- case HAL_PIXEL_FORMAT_RGBA_1010102:
- *drm_format = DRM_FORMAT_ABGR2101010;
- break;
- case HAL_PIXEL_FORMAT_ARGB_2101010:
- *drm_format = DRM_FORMAT_BGRA1010102;
- break;
- case HAL_PIXEL_FORMAT_RGBX_1010102:
- *drm_format = DRM_FORMAT_XBGR2101010;
- break;
- case HAL_PIXEL_FORMAT_XRGB_2101010:
- *drm_format = DRM_FORMAT_BGRX1010102;
- break;
- case HAL_PIXEL_FORMAT_BGRA_1010102:
- *drm_format = DRM_FORMAT_ARGB2101010;
- break;
- case HAL_PIXEL_FORMAT_ABGR_2101010:
- *drm_format = DRM_FORMAT_RGBA1010102;
- break;
- case HAL_PIXEL_FORMAT_BGRX_1010102:
- *drm_format = DRM_FORMAT_XRGB2101010;
- break;
- case HAL_PIXEL_FORMAT_XBGR_2101010:
- *drm_format = DRM_FORMAT_RGBX1010102;
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- *drm_format = DRM_FORMAT_NV12;
- break;
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- *drm_format = DRM_FORMAT_NV12;
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
- *drm_format = DRM_FORMAT_NV12;
- *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
- break;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- *drm_format = DRM_FORMAT_NV21;
- break;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
- *drm_format = DRM_FORMAT_NV21;
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_P010:
- *drm_format = DRM_FORMAT_NV12;
- *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
- *drm_format = DRM_FORMAT_NV12;
- *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
- DRM_FORMAT_MOD_QCOM_DX;
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
- *drm_format = DRM_FORMAT_NV12;
- *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
- DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
- break;
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- *drm_format = DRM_FORMAT_NV16;
- break;
- case HAL_PIXEL_FORMAT_YCrCb_422_SP:
- *drm_format = DRM_FORMAT_NV61;
- break;
- case HAL_PIXEL_FORMAT_YV12:
- *drm_format = DRM_FORMAT_YVU420;
- break;
- default:
- ALOGW("%s: Unsupported format %s", __FUNCTION__,
- qdutils::GetHALPixelFormatString(hal_format));
- }
-}
-#endif
-
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 641712c..c57ff90 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -21,12 +21,7 @@
#include <cutils/properties.h>
#include <sys/mman.h>
#include <linux/msm_ion.h>
-#ifdef COMPILE_DRM
-#include <drm_master.h>
-#endif
#include <qdMetaData.h>
-#include <qd_utils.h>
-
#include <algorithm>
#include "gr.h"
@@ -34,10 +29,6 @@
#include "memalloc.h"
#include "alloc_controller.h"
-#ifdef COMPILE_DRM
-using namespace drm_utils;
-#endif
-
using namespace gralloc;
gpu_context_t::gpu_context_t(const private_module_t* module,
@@ -178,43 +169,6 @@
hnd->gpuaddr = 0;
ColorSpace_t colorSpace = ITU_R_601;
setMetaData(hnd, UPDATE_COLOR_SPACE, (void*) &colorSpace);
-
-#ifdef COMPILE_DRM
- if (qdutils::getDriverType() == qdutils::DriverType::DRM &&
- usage & GRALLOC_USAGE_HW_COMPOSER) {
- DRMBuffer buf = {};
- int ret = getPlaneStrideOffset(hnd, buf.stride, buf.offset,
- &buf.num_planes);
- if (ret < 0) {
- ALOGE("%s failed", __FUNCTION__);
- return ret;
- }
-
- buf.fd = hnd->fd;
- buf.width = hnd->width;
- buf.height = hnd->height;
- getDRMFormat(hnd->format, flags, &buf.drm_format,
- &buf.drm_format_modifier);
-
- DRMMaster *master = nullptr;
- ret = DRMMaster::GetInstance(&master);
- if (ret < 0) {
- ALOGE("%s Failed to acquire DRMMaster instance", __FUNCTION__);
- return ret;
- }
-
- ret = master->CreateFbId(buf, &hnd->gem_handle, &hnd->fb_id);
- if (ret < 0) {
- ALOGE("%s: CreateFbId failed. width %d, height %d, " \
- "format: %s, stride %u, error %d", __FUNCTION__,
- buf.width, buf.height,
- qdutils::GetHALPixelFormatString(hnd->format),
- buf.stride[0], errno);
- return ret;
- }
- }
-#endif
-
*pHandle = hnd;
}
@@ -415,22 +369,6 @@
return err;
}
-#ifdef COMPILE_DRM
- if (hnd->fb_id) {
- DRMMaster *master = nullptr;
- int ret = DRMMaster::GetInstance(&master);
- if (ret < 0) {
- ALOGE("%s Failed to acquire DRMMaster instance", __FUNCTION__);
- return ret;
- }
- ret = master->RemoveFbId(hnd->gem_handle, hnd->fb_id);
- if (ret < 0) {
- ALOGE("%s: Removing fb_id %d failed with error %d", __FUNCTION__,
- hnd->fb_id, errno);
- }
- }
-#endif
-
delete hnd;
return 0;
}
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index edeca3f..dad4a38 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -71,13 +71,9 @@
// Function to check if the format is an RGB format
bool isUncompressedRgbFormat(int format);
-#ifdef COMPILE_DRM
-int getPlaneStrideOffset(private_handle_t *hnd, uint32_t *stride,
- uint32_t *offset, uint32_t *num_planes);
-
-void getDRMFormat(int hal_format, int flags, uint32_t *drm_format,
- uint64_t *drm_format_modifier);
-#endif
+// 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 {
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 82fdcdb..0f1f97a 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -249,8 +249,6 @@
uint64_t base_metadata __attribute__((aligned(8)));
int unaligned_width; // holds width client asked to allocate
int unaligned_height; // holds height client asked to allocate
- unsigned int gem_handle;
- unsigned int fb_id;
#ifdef __cplusplus
static const int sNumFds = 2;
@@ -267,7 +265,7 @@
base(0), offset_metadata(0), gpuaddr(0),
format(format), width(width), height(height),
base_metadata(0), unaligned_width(width),
- unaligned_height(height), gem_handle(0), fb_id(0)
+ unaligned_height(height)
{
version = (int) sizeof(native_handle);
numInts = sNumInts();
diff --git a/libgralloc1/Android.mk b/libgralloc1/Android.mk
index 0afe5f9..d8ee429 100644
--- a/libgralloc1/Android.mk
+++ b/libgralloc1/Android.mk
@@ -16,20 +16,31 @@
external/libcxx/include/
LOCAL_HEADER_LIBRARIES := display_headers
-LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libsync libqdutils
-ifneq ($(TARGET_IS_HEADLESS), true)
-LOCAL_SHARED_LIBRARIES += libdrmutils
-endif
+LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libsync libgrallocutils
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wall -std=c++11 -Werror
LOCAL_CFLAGS += -isystem $(kernel_includes)
LOCAL_CLANG := true
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
-LOCAL_SRC_FILES := gr_utils.cpp \
- gr_ion_alloc.cpp \
- gr_adreno_info.cpp \
+LOCAL_SRC_FILES := gr_ion_alloc.cpp \
gr_allocator.cpp \
gr_buf_mgr.cpp \
gr_device_impl.cpp
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := gr_device_impl.h gralloc_priv.h gr_priv_handle.h
include $(BUILD_SHARED_LIBRARY)
+
+#libgrallocutils
+include $(CLEAR_VARS)
+LOCAL_MODULE := libgrallocutils
+ifneq ($(TARGET_IS_HEADLESS), true)
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
+endif
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
+LOCAL_HEADER_LIBRARIES := display_headers
+LOCAL_SHARED_LIBRARIES := $(common_libs) libqdutils libqdMetaData libdl
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"grallocutils\" -Wno-sign-conversion
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
+LOCAL_SRC_FILES := gr_utils.cpp gr_adreno_info.cpp
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libgralloc1/gr_adreno_info.cpp b/libgralloc1/gr_adreno_info.cpp
index f8b1af6..2736fad 100644
--- a/libgralloc1/gr_adreno_info.cpp
+++ b/libgralloc1/gr_adreno_info.cpp
@@ -30,14 +30,31 @@
#include <cutils/log.h>
#include <cutils/properties.h>
#include <dlfcn.h>
+#include <mutex>
#include "gralloc_priv.h"
#include "gr_adreno_info.h"
#include "gr_utils.h"
+using std::lock_guard;
+using std::mutex;
+
namespace gralloc1 {
-AdrenoMemInfo::AdrenoMemInfo() {
+AdrenoMemInfo *AdrenoMemInfo::s_instance = nullptr;
+
+AdrenoMemInfo *AdrenoMemInfo::GetInstance() {
+ static mutex s_lock;
+ 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() {
@@ -182,6 +199,12 @@
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;
diff --git a/libgralloc1/gr_adreno_info.h b/libgralloc1/gr_adreno_info.h
index 5a3b531..1c85c8c 100644
--- a/libgralloc1/gr_adreno_info.h
+++ b/libgralloc1/gr_adreno_info.h
@@ -37,6 +37,7 @@
// Adreno Pixel Formats
typedef enum {
ADRENO_PIXELFORMAT_UNKNOWN = 0,
+ ADRENO_PIXELFORMAT_R10G10B10A2_UNORM = 24, // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
ADRENO_PIXELFORMAT_R8G8B8A8 = 28,
ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
ADRENO_PIXELFORMAT_B5G6R5 = 85,
@@ -54,6 +55,10 @@
ADRENO_PIXELFORMAT_A1B5G5R5 = 519, // GL_RGB5_A1
ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520, // GL_SRGB8
ADRENO_PIXELFORMAT_R8G8B8_SRGB = 521, // GL_SRGB8
+ ADRENO_PIXELFORMAT_A2B10G10R10_UNORM = 532,
+ // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
+ ADRENO_PIXELFORMAT_R10G10B10X2_UNORM = 537,
+ // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
ADRENO_PIXELFORMAT_R5G6B5 = 610, // RGBA version of B5G6R5
ADRENO_PIXELFORMAT_R5G5B5A1 = 611, // RGBA version of B5G5R5A1
ADRENO_PIXELFORMAT_R4G4B4A4 = 612, // RGBA version of B4G4R4A4
@@ -61,15 +66,11 @@
ADRENO_PIXELFORMAT_NV21 = 619,
ADRENO_PIXELFORMAT_Y8U8V8A8 = 620, // YUV 4:4:4 packed (1 plane)
ADRENO_PIXELFORMAT_Y8 = 625, // Single 8-bit luma only channel YUV format
- ADRENO_PIXELFORMAT_TP10 = 654, // YUV 4:2:0 planar 10 bits/comp (2 planes)
+ ADRENO_PIXELFORMAT_TP10 = 648, // YUV 4:2:0 planar 10 bits/comp (2 planes)
} ADRENOPIXELFORMAT;
class AdrenoMemInfo {
public:
- AdrenoMemInfo();
-
- ~AdrenoMemInfo();
-
bool Init();
/*
@@ -119,7 +120,10 @@
*/
ADRENOPIXELFORMAT GetGpuPixelFormat(int hal_format);
+ static AdrenoMemInfo *GetInstance();
+
private:
+ ~AdrenoMemInfo();
// link(s)to adreno surface padding library.
int (*LINK_adreno_compute_padding)(int width, int bpp, int surface_tile_height,
int screen_tile_height, int padding_threshold) = NULL;
@@ -136,6 +140,8 @@
bool gfx_ubwc_disable_ = false;
bool map_fb_ = false;
void *libadreno_utils_ = NULL;
+
+ static AdrenoMemInfo *s_instance;
};
} // namespace gralloc1
diff --git a/libgralloc1/gr_allocator.cpp b/libgralloc1/gr_allocator.cpp
index ddcf41d..5e3ee9b 100644
--- a/libgralloc1/gr_allocator.cpp
+++ b/libgralloc1/gr_allocator.cpp
@@ -33,13 +33,9 @@
#include "gr_utils.h"
#include "gr_allocator.h"
-#include "gr_adreno_info.h"
#include "gralloc_priv.h"
#include "qd_utils.h"
-#include "qdMetaData.h"
-
-#define ASTC_BLOCK_SIZE 16
#ifndef ION_FLAG_CP_PIXEL
#define ION_FLAG_CP_PIXEL 0
@@ -69,16 +65,17 @@
#define ION_SC_PREVIEW_FLAGS ION_SECURE
#endif
-#ifndef COLOR_FMT_P010_UBWC
-#define COLOR_FMT_P010_UBWC 9
-#endif
-
using std::vector;
using std::shared_ptr;
namespace gralloc1 {
-Allocator::Allocator() : ion_allocator_(NULL), adreno_helper_(NULL) {
+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() {
@@ -87,11 +84,6 @@
return false;
}
- adreno_helper_ = new AdrenoMemInfo();
- if (!adreno_helper_->Init()) {
- return false;
- }
-
return true;
}
@@ -99,10 +91,6 @@
if (ion_allocator_) {
delete ion_allocator_;
}
-
- if (adreno_helper_) {
- delete adreno_helper_;
- }
}
int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage,
@@ -180,8 +168,8 @@
}
// For same format type, find the descriptor with bigger size
- GetAlignedWidthAndHeight(*descriptors[i], &alignedw, &alignedh);
- unsigned int size = GetSize(*descriptors[i], alignedw, alignedh);
+ 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;
@@ -196,261 +184,6 @@
return true;
}
-// helper function
-unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int alignedw,
- unsigned int alignedh) {
- unsigned int size = 0;
- int format = descriptor.GetFormat();
- int width = descriptor.GetWidth();
- int height = descriptor.GetHeight();
- gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
- gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
-
- if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
- return GetUBwcSize(width, height, format, alignedw, alignedh);
- }
-
- if (IsUncompressedRGBFormat(format)) {
- uint32_t bpp = GetBppForUncompressedRGB(format);
- size = alignedw * alignedh * bpp;
- return size;
- }
-
- if (IsCompressedRGBFormat(format)) {
- size = alignedw * alignedh * ASTC_BLOCK_SIZE;
- return size;
- }
-
- // Below switch should be for only YUV/custom formats
- switch (format) {
- case HAL_PIXEL_FORMAT_RAW16:
- size = alignedw * alignedh * 2;
- break;
- case HAL_PIXEL_FORMAT_RAW10:
- case HAL_PIXEL_FORMAT_RAW12:
- size = ALIGN(alignedw * alignedh, SIZE_4K);
- break;
- case HAL_PIXEL_FORMAT_RAW8:
- size = alignedw * alignedh * 1;
- break;
-
- // adreno formats
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
- size = ALIGN(alignedw * alignedh, SIZE_4K);
- size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
- // The chroma plane is subsampled,
- // but the pitch in bytes is unchanged
- // The GPU needs 4K alignment, but the video decoder needs 8K
- size = ALIGN(alignedw * alignedh, SIZE_8K);
- size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
- break;
- case HAL_PIXEL_FORMAT_YV12:
- if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
- ALOGE("w or h is odd for the YV12 format");
- return 0;
- }
- size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
- size = ALIGN(size, (unsigned int)SIZE_4K);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_P010:
- size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
- 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:
- if (width & 1) {
- ALOGE("width is odd for the YUV422_SP format");
- return 0;
- }
- size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- 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 HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
- return 0;
- }
- size = (unsigned int)width;
- break;
- case HAL_PIXEL_FORMAT_NV21_ZSL:
- size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
- break;
- default:
- ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
- return 0;
- }
-
- return size;
-}
-
-void Allocator::GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size,
- unsigned int *alignedw, unsigned int *alignedh) {
- BufferDescriptor descriptor = BufferDescriptor(width, height, format);
- GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
-
- *size = GetSize(descriptor, *alignedw, *alignedh);
-}
-
-void Allocator::GetBufferSizeAndDimensions(const BufferDescriptor &descriptor, unsigned int *size,
- unsigned int *alignedw, unsigned int *alignedh) {
- GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
-
- *size = GetSize(descriptor, *alignedw, *alignedh);
-}
-
-void Allocator::GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
- int color_format, struct android_ycbcr *ycbcr) {
- // 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;
-
- y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
- y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
- y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
-
- y_stride = VENUS_Y_STRIDE(color_format, INT(width));
- y_height = VENUS_Y_SCANLINES(color_format, INT(height));
- y_size = ALIGN((y_stride * y_height), alignment);
-
- c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
- c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
- c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
-
- ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
- ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
- ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
- ycbcr->ystride = y_stride;
- ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
-}
-
-void Allocator::GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
- struct android_ycbcr *ycbcr) {
- unsigned int ystride, cstride;
-
- ystride = cstride = UINT(width) * bpp;
- ycbcr->y = reinterpret_cast<void *>(base);
- ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
- ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
- ycbcr->ystride = ystride;
- ycbcr->cstride = cstride;
- ycbcr->chroma_step = 2 * bpp;
-}
-
-int Allocator::GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
- int err = 0;
- uint32_t width = UINT(hnd->width);
- uint32_t height = UINT(hnd->height);
- int format = hnd->format;
- gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
- gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
- unsigned int ystride, cstride;
-
- 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);
- }
-
- // 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 = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
- }
-
- BufferDescriptor descriptor =
- BufferDescriptor(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
- prod_usage, cons_usage);
- GetAlignedWidthAndHeight(descriptor, &width, &height);
- }
-
- // Get the chroma offsets from the handle width/height. We take advantage
- // of the fact the width _is_ the stride
- 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
- 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:
- case HAL_PIXEL_FORMAT_RAW16:
- case HAL_PIXEL_FORMAT_RAW10:
- case HAL_PIXEL_FORMAT_RAW8:
- GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
- std::swap(ycbcr->cb, ycbcr->cr);
- break;
-
- // Planar
- case HAL_PIXEL_FORMAT_YV12:
- ystride = width;
- cstride = ALIGN(width / 2, 16);
- ycbcr->y = reinterpret_cast<void *>(hnd->base);
- ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
- ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
- ycbcr->ystride = ystride;
- ycbcr->cstride = cstride;
- ycbcr->chroma_step = 1;
- 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__, format);
- err = -EINVAL;
- }
-
- return err;
-}
-
int Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
gralloc1_consumer_usage_t cons_usage, int format) {
int gr_format = format;
@@ -489,34 +222,6 @@
return gr_format;
}
-// Explicitly defined UBWC formats
-bool Allocator::IsUBwcFormat(int format) {
- 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;
- }
-}
-
-bool Allocator::IsUBwcSupported(int format) {
- // 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:
- return true;
- default:
- break;
- }
-
- return false;
-}
-
/* 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. */
@@ -598,258 +303,4 @@
return;
}
-bool Allocator::IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
- gralloc1_consumer_usage_t cons_usage) {
- // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
- if (IsUBwcFormat(format)) {
- return true;
- }
-
- // 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 ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
- bool enable = true;
- // 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 = adreno_helper_->IsUBWCSupportedByGPU(format);
- }
-
- // Allow UBWC, only if CPU usage flags are not set
- if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
- return true;
- }
- }
-
- return false;
-}
-
-void Allocator::GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
- unsigned 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;
- }
-}
-
-void Allocator::GetRgbUBwcBlockSize(uint32_t 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;
- }
-}
-
-unsigned int Allocator::GetRgbUBwcMetaBufferSize(int width, int height, uint32_t 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 = (unsigned int)ALIGN((meta_width * meta_height), 4096);
-
- return size;
-}
-
-unsigned int Allocator::GetUBwcSize(int width, int height, int format, unsigned int alignedw,
- unsigned int alignedh) {
- unsigned int size = 0;
- uint32_t bpp = 0;
- switch (format) {
- case HAL_PIXEL_FORMAT_BGR_565:
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGBX_8888:
- case HAL_PIXEL_FORMAT_RGBA_1010102:
- case HAL_PIXEL_FORMAT_RGBX_1010102:
- bpp = GetBppForUncompressedRGB(format);
- size = alignedw * alignedh * bpp;
- size += GetRgbUBwcMetaBufferSize(width, height, bpp);
- 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 Allocator::GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
- int err = 0;
-
- // This api is for RGB* formats
- if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
- return -EINVAL;
- }
-
- // linear buffer, nothing to do further
- if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
- *rgb_data = reinterpret_cast<void *>(hnd->base);
- return err;
- }
-
- unsigned int meta_size = 0;
- uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
- switch (hnd->format) {
- case HAL_PIXEL_FORMAT_BGR_565:
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGBX_8888:
- meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
- break;
- default:
- ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
- err = -EINVAL;
- break;
- }
- *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
-
- return err;
-}
-
-void Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, unsigned int *alignedw,
- unsigned int *alignedh) {
- int width = descriptor.GetWidth();
- int height = descriptor.GetHeight();
- int format = descriptor.GetFormat();
- gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
- gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
-
- // Currently surface padding is only computed for RGB* surfaces.
- bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
- int tile = ubwc_enabled;
-
- if (IsUncompressedRGBFormat(format)) {
- adreno_helper_->AlignUnCompressedRGB(width, height, format, tile, alignedw, alignedh);
- return;
- }
-
- if (ubwc_enabled) {
- GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
- return;
- }
-
- if (IsCompressedRGBFormat(format)) {
- adreno_helper_->AlignCompressedRGB(width, height, format, alignedw, alignedh);
- return;
- }
-
- int aligned_w = width;
- int aligned_h = height;
- unsigned int alignment = 32;
-
- // Below should be only YUV family
- switch (format) {
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- alignment = adreno_helper_->GetGpuPixelAlignment();
- 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:
- 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;
- case HAL_PIXEL_FORMAT_YV12:
- 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_YCbCr_420_P010:
- aligned_w = ALIGN(width, 16);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
- aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
- break;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
- aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
- aligned_h = INT(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);
- aligned_h = ALIGN(height, 64);
- break;
- default:
- break;
- }
-
- *alignedw = (unsigned int)aligned_w;
- *alignedh = (unsigned int)aligned_h;
-}
-
} // namespace gralloc1
diff --git a/libgralloc1/gr_allocator.h b/libgralloc1/gr_allocator.h
index df1a30c..6f9de30 100644
--- a/libgralloc1/gr_allocator.h
+++ b/libgralloc1/gr_allocator.h
@@ -40,7 +40,6 @@
#include "gralloc_priv.h"
#include "gr_buf_descriptor.h"
-#include "gr_adreno_info.h"
#include "gr_ion_alloc.h"
namespace gralloc1 {
@@ -62,37 +61,13 @@
ssize_t *max_index);
int GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
gralloc1_consumer_usage_t cons_usage, int format);
- unsigned int GetSize(const BufferDescriptor &d, unsigned int alignedw, unsigned int alignedh);
- void GetBufferSizeAndDimensions(const BufferDescriptor &d, unsigned int *size,
- unsigned int *alignedw, unsigned int *alignedh);
- void GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size,
- unsigned int *alignedw, unsigned int *alignedh);
- void GetAlignedWidthAndHeight(const BufferDescriptor &d, unsigned int *aligned_w,
- unsigned int *aligned_h);
- int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr);
- int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
bool UseUncached(gralloc1_producer_usage_t usage);
- bool IsUBwcFormat(int format);
- bool IsUBwcSupported(int format);
- bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
- gralloc1_consumer_usage_t cons_usage);
private:
- void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
- unsigned int *aligned_h);
- void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
- struct android_ycbcr *ycbcr);
- void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
- struct android_ycbcr *ycbcr);
- void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height);
- unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp);
- unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
- unsigned int alignedh);
void 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);
IonAlloc *ion_allocator_ = NULL;
- AdrenoMemInfo *adreno_helper_ = NULL;
};
} // namespace gralloc1
diff --git a/libgralloc1/gr_buf_descriptor.h b/libgralloc1/gr_buf_descriptor.h
index 1f86867..c909fa4 100644
--- a/libgralloc1/gr_buf_descriptor.h
+++ b/libgralloc1/gr_buf_descriptor.h
@@ -31,6 +31,7 @@
#define __GR_BUF_DESCRIPTOR_H__
#include <hardware/gralloc1.h>
+#include <atomic>
namespace gralloc1 {
class BufferDescriptor {
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index d3a307b..66a8e17 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -18,6 +18,7 @@
*/
#define DEBUG 0
+
#include <iomanip>
#include <utility>
#include <vector>
@@ -33,6 +34,11 @@
namespace gralloc1 {
std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
+static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
+ return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
+ descriptor.GetProducerUsage(), descriptor.GetConsumerUsage());
+}
+
BufferManager::BufferManager() : next_id_(0) {
char property[PROPERTY_VALUE_MAX];
@@ -160,7 +166,9 @@
// Get Buffer attributes or dimension
unsigned int alignedw = 0, alignedh = 0;
- allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+ BufferInfo info = GetBufferInfo(descriptor);
+
+ GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
// create new handle from input reference handle and given descriptor
int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
@@ -425,7 +433,7 @@
flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
}
- if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
+ if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
}
@@ -477,7 +485,8 @@
unsigned int size;
unsigned int alignedw, alignedh;
int buffer_type = GetBufferType(gralloc_format);
- allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
+ BufferInfo info = GetBufferInfo(descriptor);
+ GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
size = (bufferSize >= size) ? bufferSize : size;
size = size * layer_count;
@@ -566,8 +575,8 @@
hnd->offset = offset;
hnd->base = uint64_t(base) + offset;
hnd->gpuaddr = 0;
- BufferDescriptor descriptor(width, height, format);
- allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+ BufferInfo info(width, height, format);
+ GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
hnd->unaligned_width = width;
hnd->unaligned_height = height;
hnd->width = INT(alignedw);
@@ -582,8 +591,8 @@
int format = va_arg(args, int);
int *stride = va_arg(args, int *);
unsigned int alignedw = 0, alignedh = 0;
- BufferDescriptor descriptor(width, width, format);
- allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+ BufferInfo info(width, width, format);
+ GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
*stride = INT(alignedw);
} break;
@@ -636,10 +645,9 @@
int *aligned_height = va_arg(args, int *);
int *tile_enabled = va_arg(args, int *);
unsigned int alignedw, alignedh;
- BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
- *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage);
-
- allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+ BufferInfo info(width, height, format, prod_usage, cons_usage);
+ *tile_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
+ GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
*aligned_width = INT(alignedw);
*aligned_height = INT(alignedh);
} break;
@@ -681,7 +689,7 @@
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
- if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
+ if (GetYUVPlaneInfo(hnd, ycbcr)) {
return GRALLOC1_ERROR_UNDEFINED;
}
} break;
@@ -713,7 +721,7 @@
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
- if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
+ if (GetRgbDataAddress(hnd, rgb_data)) {
return GRALLOC1_ERROR_UNDEFINED;
}
} break;
@@ -729,8 +737,8 @@
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 *);
- auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage);
- allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height);
+ auto info = BufferInfo(width, height, format, producer_usage, consumer_usage);
+ GetBufferSizeAndDimensions(info, size, aligned_width, aligned_height);
// Align size
auto align = GetDataAlignment(format, producer_usage, consumer_usage);
*size = ALIGN(*size, align);
@@ -750,7 +758,7 @@
BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
unsigned int size;
unsigned int alignedw, alignedh;
- allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
+ GetBufferSizeAndDimensions(GetBufferInfo(descriptor), &size, &alignedw, &alignedh);
AllocateBuffer(descriptor, hnd, size);
} break;
@@ -798,7 +806,7 @@
}
android_ycbcr ycbcr;
- int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr);
+ int err = GetYUVPlaneInfo(hnd, &ycbcr);
if (err != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
diff --git a/libgralloc1/gr_priv_handle.h b/libgralloc1/gr_priv_handle.h
index 5948aab..49e09a5 100644
--- a/libgralloc1/gr_priv_handle.h
+++ b/libgralloc1/gr_priv_handle.h
@@ -76,7 +76,6 @@
unsigned int size;
unsigned int offset;
unsigned int offset_metadata;
- unsigned int fb_id;
uint64_t base __attribute__((aligned(8)));
uint64_t base_metadata __attribute__((aligned(8)));
uint64_t gpuaddr __attribute__((aligned(8)));
@@ -118,7 +117,6 @@
size(size),
offset(0),
offset_metadata(0),
- fb_id(0),
base(0),
base_metadata(0),
gpuaddr(0),
diff --git a/libgralloc1/gr_utils.cpp b/libgralloc1/gr_utils.cpp
index f3c4ba8..444de8c 100644
--- a/libgralloc1/gr_utils.cpp
+++ b/libgralloc1/gr_utils.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-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
@@ -27,7 +27,18 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <media/msm_media_info.h>
+#include <algorithm>
+
#include "gr_utils.h"
+#include "gr_adreno_info.h"
+#include "qdMetaData.h"
+
+#define ASTC_BLOCK_SIZE 16
+
+#ifndef COLOR_FMT_P010_UBWC
+#define COLOR_FMT_P010_UBWC 9
+#endif
namespace gralloc1 {
@@ -109,6 +120,14 @@
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_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:
bpp = 4;
break;
case HAL_PIXEL_FORMAT_RGB_888:
@@ -121,7 +140,7 @@
bpp = 2;
break;
default:
- ALOGE("Error : %s New format request", __FUNCTION__);
+ ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
break;
}
@@ -153,4 +172,620 @@
return false;
}
+unsigned int GetSize(const BufferInfo &info, unsigned int alignedw,
+ unsigned int alignedh) {
+ unsigned int size = 0;
+ int format = info.format;
+ int width = info.width;
+ int height = info.height;
+ gralloc1_producer_usage_t prod_usage = info.prod_usage;
+ gralloc1_consumer_usage_t cons_usage = info.cons_usage;
+
+ if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
+ return GetUBwcSize(width, height, format, alignedw, alignedh);
+ }
+
+ if (IsUncompressedRGBFormat(format)) {
+ uint32_t bpp = GetBppForUncompressedRGB(format);
+ size = alignedw * alignedh * bpp;
+ return size;
+ }
+
+ if (IsCompressedRGBFormat(format)) {
+ size = alignedw * alignedh * ASTC_BLOCK_SIZE;
+ return size;
+ }
+
+ // Below switch should be for only YUV/custom formats
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RAW16:
+ size = alignedw * alignedh * 2;
+ break;
+ case HAL_PIXEL_FORMAT_RAW10:
+ case HAL_PIXEL_FORMAT_RAW12:
+ size = ALIGN(alignedw * alignedh, SIZE_4K);
+ break;
+ case HAL_PIXEL_FORMAT_RAW8:
+ size = alignedw * alignedh * 1;
+ break;
+
+ // adreno formats
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
+ size = ALIGN(alignedw * alignedh, SIZE_4K);
+ size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
+ // The chroma plane is subsampled,
+ // but the pitch in bytes is unchanged
+ // The GPU needs 4K alignment, but the video decoder needs 8K
+ size = ALIGN(alignedw * alignedh, SIZE_8K);
+ size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
+ break;
+ case HAL_PIXEL_FORMAT_YV12:
+ if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
+ ALOGE("w or h is odd for the YV12 format");
+ return 0;
+ }
+ size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
+ size = ALIGN(size, (unsigned int)SIZE_4K);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
+ 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:
+ if (width & 1) {
+ ALOGE("width is odd for the YUV422_SP format");
+ return 0;
+ }
+ size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ 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 HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
+ return 0;
+ }
+ size = (unsigned int)width;
+ break;
+ case HAL_PIXEL_FORMAT_NV21_ZSL:
+ size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
+ break;
+ default:
+ ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
+ return 0;
+ }
+
+ return size;
+}
+
+void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size,
+ unsigned int *alignedw, unsigned int *alignedh) {
+ GetAlignedWidthAndHeight(info, alignedw, alignedh);
+ *size = GetSize(info, *alignedw, *alignedh);
+}
+
+void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
+ int color_format, struct android_ycbcr *ycbcr) {
+ // 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;
+
+ y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
+ y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
+ y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
+
+ y_stride = VENUS_Y_STRIDE(color_format, INT(width));
+ y_height = VENUS_Y_SCANLINES(color_format, INT(height));
+ y_size = ALIGN((y_stride * y_height), alignment);
+
+ c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
+ c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
+ c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
+
+ ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
+ ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
+ ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
+ ycbcr->ystride = y_stride;
+ ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
+}
+
+void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
+ struct android_ycbcr *ycbcr) {
+ unsigned int ystride, cstride;
+
+ ystride = cstride = UINT(width) * bpp;
+ ycbcr->y = reinterpret_cast<void *>(base);
+ ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
+ ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
+ ycbcr->ystride = ystride;
+ ycbcr->cstride = cstride;
+ ycbcr->chroma_step = 2 * bpp;
+}
+
+int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
+ int err = 0;
+ uint32_t width = UINT(hnd->width);
+ uint32_t height = UINT(hnd->height);
+ int format = hnd->format;
+ gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
+ gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
+ unsigned int ystride, cstride;
+
+ 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);
+ }
+
+ // 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 = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
+ }
+
+ BufferInfo info(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
+ prod_usage, cons_usage);
+ GetAlignedWidthAndHeight(info, &width, &height);
+ }
+
+ // Get the chroma offsets from the handle width/height. We take advantage
+ // of the fact the width _is_ the stride
+ 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
+ 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:
+ case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_RAW10:
+ case HAL_PIXEL_FORMAT_RAW8:
+ GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
+ std::swap(ycbcr->cb, ycbcr->cr);
+ break;
+
+ // Planar
+ case HAL_PIXEL_FORMAT_YV12:
+ ystride = width;
+ cstride = ALIGN(width / 2, 16);
+ ycbcr->y = reinterpret_cast<void *>(hnd->base);
+ ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
+ ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
+ ycbcr->ystride = ystride;
+ ycbcr->cstride = cstride;
+ ycbcr->chroma_step = 1;
+ 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__, format);
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+// Explicitly defined UBWC formats
+bool IsUBwcFormat(int format) {
+ 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;
+ }
+}
+
+bool IsUBwcSupported(int format) {
+ // 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, gralloc1_producer_usage_t prod_usage,
+ gralloc1_consumer_usage_t cons_usage) {
+ // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
+ if (IsUBwcFormat(format)) {
+ return true;
+ }
+
+ // 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 ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
+ bool enable = true;
+ // 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);
+ }
+
+ // Allow UBWC, only if CPU usage flags are not set
+ if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
+ unsigned 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;
+ }
+}
+
+void GetRgbUBwcBlockSize(uint32_t 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;
+ }
+}
+
+unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t 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 = (unsigned int)ALIGN((meta_width * meta_height), 4096);
+
+ return size;
+}
+
+unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
+ unsigned int alignedh) {
+ unsigned int size = 0;
+ uint32_t bpp = 0;
+ switch (format) {
+ case HAL_PIXEL_FORMAT_BGR_565:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ bpp = GetBppForUncompressedRGB(format);
+ size = alignedw * alignedh * bpp;
+ size += GetRgbUBwcMetaBufferSize(width, height, bpp);
+ 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 (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
+ return -EINVAL;
+ }
+
+ // linear buffer, nothing to do further
+ if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
+ *rgb_data = reinterpret_cast<void *>(hnd->base);
+ return err;
+ }
+
+ unsigned int meta_size = 0;
+ uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
+ switch (hnd->format) {
+ case HAL_PIXEL_FORMAT_BGR_565:
+ 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, bpp);
+ break;
+ default:
+ ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
+ err = -EINVAL;
+ break;
+ }
+ *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
+
+ return err;
+}
+
+void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
+ unsigned int *alignedh) {
+ int width = info.width;
+ int height = info.height;
+ int format = info.format;
+ gralloc1_producer_usage_t prod_usage = info.prod_usage;
+ gralloc1_consumer_usage_t cons_usage = info.cons_usage;
+
+ // Currently surface padding is only computed for RGB* surfaces.
+ bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
+ int tile = ubwc_enabled;
+
+ if (IsUncompressedRGBFormat(format)) {
+ AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
+ alignedh);
+ return;
+ }
+
+ if (ubwc_enabled) {
+ GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
+ return;
+ }
+
+ if (IsCompressedRGBFormat(format)) {
+ AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
+ return;
+ }
+
+ int aligned_w = width;
+ int aligned_h = height;
+ unsigned int alignment = 32;
+
+ // Below should be only YUV family
+ switch (format) {
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
+ 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:
+ 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;
+ case HAL_PIXEL_FORMAT_YV12:
+ 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_YCbCr_420_P010:
+ aligned_w = ALIGN(width, 16);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
+ aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
+ aligned_h = INT(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);
+ aligned_h = ALIGN(height, 64);
+ break;
+ default:
+ break;
+ }
+
+ *alignedw = (unsigned int)aligned_w;
+ *alignedh = (unsigned int)aligned_h;
+}
+
+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] = static_cast<uint32_t>(hnd->width * 2);
+ break;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ stride[0] = static_cast<uint32_t>(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] = static_cast<uint32_t>(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", __FUNCTION__);
+ ret = -EINVAL;
+ }
+
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+ std::fill(offset, offset + 4, 0);
+ }
+
+ return 0;
+}
+
} // namespace gralloc1
diff --git a/libgralloc1/gr_utils.h b/libgralloc1/gr_utils.h
index 20f0be5..aa66fd0 100644
--- a/libgralloc1/gr_utils.h
+++ b/libgralloc1/gr_utils.h
@@ -44,6 +44,17 @@
namespace gralloc1 {
+struct BufferInfo {
+ BufferInfo(int w, int h, int f, gralloc1_producer_usage_t prod = GRALLOC1_PRODUCER_USAGE_NONE,
+ gralloc1_consumer_usage_t cons = GRALLOC1_CONSUMER_USAGE_NONE) : width(w), height(h),
+ format(f), prod_usage(prod), cons_usage(cons) {}
+ int width;
+ int height;
+ int format;
+ gralloc1_producer_usage_t prod_usage;
+ gralloc1_consumer_usage_t cons_usage;
+};
+
template <class Type1, class Type2>
inline Type1 ALIGN(Type1 x, Type2 align) {
return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
@@ -55,7 +66,29 @@
bool CpuCanAccess(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage);
bool CpuCanRead(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage);
bool CpuCanWrite(gralloc1_producer_usage_t prod_usage);
-
+unsigned int GetSize(const BufferInfo &d, unsigned int alignedw, unsigned int alignedh);
+void GetBufferSizeAndDimensions(const BufferInfo &d, unsigned int *size,
+ unsigned int *alignedw, unsigned int *alignedh);
+void GetAlignedWidthAndHeight(const BufferInfo &d, unsigned int *aligned_w,
+ unsigned int *aligned_h);
+int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr);
+int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
+bool IsUBwcFormat(int format);
+bool IsUBwcSupported(int format);
+bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
+ gralloc1_consumer_usage_t cons_usage);
+void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
+ unsigned int *aligned_h);
+void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
+ struct android_ycbcr *ycbcr);
+void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
+ struct android_ycbcr *ycbcr);
+void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height);
+unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp);
+unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
+ unsigned int alignedh);
+int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4],
+ uint32_t offset[4], uint32_t *num_planes);
} // namespace gralloc1
#endif // __GR_UTILS_H__
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index f1eece9..ae23b53 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -35,6 +35,10 @@
#include <gralloc_priv.h>
#include "qdMetaData.h"
+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);
@@ -47,7 +51,7 @@
}
if (!handle->base_metadata) {
- unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ 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)) {
@@ -62,12 +66,18 @@
}
int setMetaData(private_handle_t *handle, DispParamType paramType,
- void *param) {
+ void *param) {
auto err = validateAndMap(handle);
if (err != 0)
return err;
+ return setMetaDataVa(reinterpret_cast<MetaData_t*>(handle->base_metadata),
+ paramType, param);
+}
- MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
+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) {
data->operation &= ~paramType;
@@ -126,8 +136,13 @@
auto err = validateAndMap(handle);
if (err != 0)
return err;
+ return clearMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+ paramType);
+}
- MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
+int clearMetaDataVa(MetaData_t *data, DispParamType paramType) {
+ if (data == nullptr)
+ return -EINVAL;
data->operation &= ~paramType;
switch (paramType) {
case SET_S3D_COMP:
@@ -146,9 +161,16 @@
int ret = validateAndMap(handle);
if (ret != 0)
return ret;
- MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
+ 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
- ret = -EINVAL;
+ int ret = -EINVAL;
+ if (data == nullptr)
+ return ret;
switch (paramType) {
case GET_PP_PARAM_INTERLACED:
@@ -241,9 +263,49 @@
if (err != 0)
return err;
- unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
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, size);
+ memcpy(src_data, dst_data, getMetaDataSize());
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);
+ memcpy(src_data, dst_data, getMetaDataSize());
+ 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);
+ memcpy(src_data, dst_data, getMetaDataSize());
+ 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;
+
+ memcpy(src_data, dst_data, getMetaDataSize());
+ return 0;
+}
+
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index a0ac324..e704f6c 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -38,6 +38,8 @@
extern "C" {
#endif
+#define MAX_UBWC_STATS_LENGTH 32
+
enum ColorSpace_t{
ITU_R_601,
ITU_R_601_FR,
@@ -63,6 +65,35 @@
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 */
@@ -99,6 +130,14 @@
/* Color Aspects + HDR info */
ColorMetaData color;
#endif
+ /* 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 {
@@ -108,7 +147,7 @@
UNUSED2 = 0x0008,
UNUSED3 = 0x0010,
UNUSED4 = 0x0020,
- UNUSED5 = 0x0040,
+ SET_UBWC_CR_STATS_INFO = 0x0040,
UPDATE_BUFFER_GEOMETRY = 0x0080,
UPDATE_REFRESH_RATE = 0x0100,
UPDATE_COLOR_SPACE = 0x0200,
@@ -124,6 +163,7 @@
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,
@@ -137,14 +177,25 @@
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 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/sdm/include/core/buffer_allocator.h b/sdm/include/core/buffer_allocator.h
index 3d805ae..ccb9a1b 100644
--- a/sdm/include/core/buffer_allocator.h
+++ b/sdm/include/core/buffer_allocator.h
@@ -67,9 +67,8 @@
uint32_t stride = 0; //!< Specifies allocated buffer stride in bytes.
uint32_t aligned_width = 0; //!< Specifies aligned allocated buffer width in pixels.
uint32_t aligned_height = 0; //!< Specifies aligned allocated buffer height in pixels.
+ LayerBufferFormat format = kFormatInvalid; // Specifies buffer format for allocated buffer.
uint32_t size = 0; //!< Specifies the size of the allocated buffer.
- uint32_t fb_id = 0; // Registered id with the DRM driver
- uint32_t gem_handle = 0; // GEM driver handle for correspoding import of ION buffer
};
/*! @brief Holds the information about the input/output configuration of an output buffer.
@@ -140,6 +139,15 @@
virtual DisplayError GetAllocatedBufferInfo(const BufferConfig &buffer_config,
AllocatedBufferInfo *allocated_buffer_info) = 0;
+ /*
+ * Retuns a buffer's layout in terms of number of planes, stride and offset of each plane
+ * Input: AllocatedBufferInfo with a valid aligned width, aligned height, SDM format
+ * Output: stride for each plane, offset of each plane from base, number of planes
+ */
+ virtual DisplayError GetBufferLayout(const AllocatedBufferInfo &buf_info,
+ uint32_t stride[4], uint32_t offset[4],
+ uint32_t *num_planes) { return kErrorNotSupported; }
+
protected:
virtual ~BufferAllocator() { }
};
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
index 9029c12..c86e020 100644
--- a/sdm/include/core/layer_buffer.h
+++ b/sdm/include/core/layer_buffer.h
@@ -268,7 +268,6 @@
//!< could be modified by both client and SDM.
uint64_t buffer_id __attribute__((aligned(8))) = 0;
//!< Specifies the buffer id.
- uint32_t fb_id = 0; // DRM f/w registered framebuffer id
};
// This enum represents buffer layout types.
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 1f8090b..4ab50a2 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -240,12 +240,12 @@
DisplayPort port = kPortDefault; // Display port
HWDisplayMode mode = kModeDefault; // Display mode
bool partial_update = false; // Partial update feature
- int left_align = 0; // ROI left alignment restriction
- int width_align = 0; // ROI width alignment restriction
- int top_align = 0; // ROI top alignment restriction
- int height_align = 0; // ROI height alignment restriction
- int min_roi_width = 0; // Min width needed for ROI
- int min_roi_height = 0; // Min height needed for ROI
+ int left_align = 1; // ROI left alignment restriction
+ int width_align = 1; // ROI width alignment restriction
+ int top_align = 1; // ROI top alignment restriction
+ int height_align = 1; // ROI height alignment restriction
+ int min_roi_width = 1; // Min width needed for ROI
+ int min_roi_height = 1; // Min height needed for ROI
bool needs_roi_merge = false; // Merge ROI's of both the DSI's
bool dynamic_fps = false; // Panel Supports dynamic fps
bool dfps_porch_mode = false; // dynamic fps VFP or HFP mode
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index 874b150..4ef9a22 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -21,7 +21,7 @@
LOCAL_SHARED_LIBRARIES := libdl libsdmutils
ifneq ($(TARGET_IS_HEADLESS), true)
- LOCAL_CFLAGS += -isystem external/libdrm
+ LOCAL_CFLAGS += -DCOMPILE_DRM -isystem external/libdrm
LOCAL_SHARED_LIBRARIES += libdrm libdrmutils
LOCAL_HW_INTF_PATH_2 := drm
endif
@@ -58,6 +58,7 @@
LOCAL_SRC_FILES += $(LOCAL_HW_INTF_PATH_2)/hw_info_drm.cpp \
$(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_color_manager_drm.cpp
endif
diff --git a/sdm/libs/core/core_impl.cpp b/sdm/libs/core/core_impl.cpp
index 369e2dd..661616e 100644
--- a/sdm/libs/core/core_impl.cpp
+++ b/sdm/libs/core/core_impl.cpp
@@ -125,15 +125,15 @@
switch (type) {
case kPrimary:
display_base = new DisplayPrimary(event_handler, hw_info_intf_, buffer_sync_handler_,
- &comp_mgr_);
+ buffer_allocator_, &comp_mgr_);
break;
case kHDMI:
display_base = new DisplayHDMI(event_handler, hw_info_intf_, buffer_sync_handler_,
- &comp_mgr_);
+ buffer_allocator_, &comp_mgr_);
break;
case kVirtual:
display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_,
- &comp_mgr_);
+ buffer_allocator_, &comp_mgr_);
break;
default:
DLOGE("Spurious display type %d", type);
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 631b24b..93970a4 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -41,10 +41,11 @@
// TODO(user): Have a single structure handle carries all the interface pointers and variables.
DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
- CompManager *comp_manager, HWInfoInterface *hw_info_intf)
+ BufferAllocator *buffer_allocator, CompManager *comp_manager,
+ HWInfoInterface *hw_info_intf)
: display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
- buffer_sync_handler_(buffer_sync_handler), comp_manager_(comp_manager),
- hw_info_intf_(hw_info_intf) {
+ buffer_sync_handler_(buffer_sync_handler), buffer_allocator_(buffer_allocator),
+ comp_manager_(comp_manager), hw_info_intf_(hw_info_intf) {
}
DisplayError DisplayBase::Init() {
@@ -1114,7 +1115,6 @@
hw_layer.input_buffer.planes[0].stride = sdm_layer->input_buffer.planes[0].stride;
hw_layer.input_buffer.size = sdm_layer->input_buffer.size;
hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd;
- hw_layer.input_buffer.fb_id = sdm_layer->input_buffer.fb_id;
}
return;
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 3507502..378026e 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -48,7 +48,8 @@
public:
DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
- CompManager *comp_manager, HWInfoInterface *hw_info_intf);
+ BufferAllocator *buffer_allocator, CompManager *comp_manager,
+ HWInfoInterface *hw_info_intf);
virtual ~DisplayBase() { }
virtual DisplayError Init();
virtual DisplayError Deinit();
@@ -138,6 +139,7 @@
HWInterface *hw_intf_ = NULL;
HWPanelInfo hw_panel_info_;
BufferSyncHandler *buffer_sync_handler_ = NULL;
+ BufferAllocator *buffer_allocator_ {};
CompManager *comp_manager_ = NULL;
DisplayState state_ = kStateOff;
bool active_ = false;
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
index 783cad9..2ee863c 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_hdmi.cpp
@@ -37,16 +37,17 @@
namespace sdm {
DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
- BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager)
- : DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, comp_manager,
- hw_info_intf) {
+ BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ CompManager *comp_manager)
+ : DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, buffer_allocator,
+ comp_manager, hw_info_intf) {
}
DisplayError DisplayHDMI::Init() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = HWInterface::Create(kHDMI, hw_info_intf_, buffer_sync_handler_,
- &hw_intf_);
+ buffer_allocator_, &hw_intf_);
if (error != kErrorNone) {
return error;
}
diff --git a/sdm/libs/core/display_hdmi.h b/sdm/libs/core/display_hdmi.h
index f3e64bc..a6c1f51 100644
--- a/sdm/libs/core/display_hdmi.h
+++ b/sdm/libs/core/display_hdmi.h
@@ -39,7 +39,8 @@
class DisplayHDMI : public DisplayBase, HWEventHandler {
public:
DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
- BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager);
+ BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ CompManager *comp_manager);
virtual DisplayError Init();
virtual DisplayError Prepare(LayerStack *layer_stack);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index f799b20..d89e9db 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -39,16 +39,17 @@
namespace sdm {
DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
- BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager)
- : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager,
- hw_info_intf) {
+ BufferSyncHandler *buffer_sync_handler,
+ BufferAllocator *buffer_allocator, CompManager *comp_manager)
+ : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, buffer_allocator,
+ comp_manager, hw_info_intf) {
}
DisplayError DisplayPrimary::Init() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = HWInterface::Create(kPrimary, hw_info_intf_, buffer_sync_handler_,
- &hw_intf_);
+ buffer_allocator_, &hw_intf_);
if (error != kErrorNone) {
return error;
}
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index 46feb37..5578f36 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -38,7 +38,8 @@
class DisplayPrimary : public DisplayBase, HWEventHandler {
public:
DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
- BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager);
+ BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ CompManager *comp_manager);
virtual DisplayError Init();
virtual DisplayError Prepare(LayerStack *layer_stack);
virtual DisplayError Commit(LayerStack *layer_stack);
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index 6baa3ed..fcdc152 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -34,16 +34,17 @@
namespace sdm {
DisplayVirtual::DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
- BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager)
- : DisplayBase(kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler, comp_manager,
- hw_info_intf) {
+ BufferSyncHandler *buffer_sync_handler,
+ BufferAllocator *buffer_allocator, CompManager *comp_manager)
+ : DisplayBase(kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler, buffer_allocator,
+ comp_manager, hw_info_intf) {
}
DisplayError DisplayVirtual::Init() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = HWInterface::Create(kVirtual, hw_info_intf_, buffer_sync_handler_,
- &hw_intf_);
+ buffer_allocator_, &hw_intf_);
if (error != kErrorNone) {
return error;
}
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index 3cc2e24..aaebf46 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -36,7 +36,8 @@
class DisplayVirtual : public DisplayBase {
public:
DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
- BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager);
+ BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ CompManager *comp_manager);
virtual DisplayError Init();
virtual DisplayError Prepare(LayerStack *layer_stack);
virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 7708c83..85dee22 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -30,6 +30,7 @@
#define __STDC_FORMAT_MACROS
#include <ctype.h>
+#include <drm/drm_fourcc.h>
#include <drm_lib_loader.h>
#include <drm_master.h>
#include <drm_res_mgr.h>
@@ -45,11 +46,13 @@
#include <unistd.h>
#include <utils/constants.h>
#include <utils/debug.h>
+#include <utils/formats.h>
#include <utils/sys.h>
#include <private/color_params.h>
#include <algorithm>
#include <string>
+#include <unordered_map>
#include <utility>
#include <vector>
@@ -59,12 +62,24 @@
#define __CLASS__ "HWDeviceDRM"
+#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
+#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
+#endif
+#ifndef DRM_FORMAT_MOD_QCOM_DX
+#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
+#endif
+#ifndef DRM_FORMAT_MOD_QCOM_TIGHT
+#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
+#endif
+
using std::string;
using std::to_string;
using std::fstream;
+using std::unordered_map;
using drm_utils::DRMMaster;
using drm_utils::DRMResMgr;
using drm_utils::DRMLibLoader;
+using drm_utils::DRMBuffer;
using sde_drm::GetDRMManager;
using sde_drm::DestroyDRMManager;
using sde_drm::DRMDisplayType;
@@ -79,8 +94,208 @@
namespace sdm {
-HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf)
- : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler) {
+static void GetDRMFormat(LayerBufferFormat format, uint32_t *drm_format,
+ uint64_t *drm_format_modifier) {
+ switch (format) {
+ case kFormatRGBA8888:
+ *drm_format = DRM_FORMAT_ABGR8888;
+ break;
+ case kFormatRGBA8888Ubwc:
+ *drm_format = DRM_FORMAT_ABGR8888;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case kFormatRGBA5551:
+ *drm_format = DRM_FORMAT_ABGR1555;
+ break;
+ case kFormatRGBA4444:
+ *drm_format = DRM_FORMAT_ABGR4444;
+ break;
+ case kFormatBGRA8888:
+ *drm_format = DRM_FORMAT_ARGB8888;
+ break;
+ case kFormatRGBX8888:
+ *drm_format = DRM_FORMAT_XBGR8888;
+ break;
+ case kFormatRGBX8888Ubwc:
+ *drm_format = DRM_FORMAT_XBGR8888;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case kFormatBGRX8888:
+ *drm_format = DRM_FORMAT_XRGB8888;
+ break;
+ case kFormatRGB888:
+ *drm_format = DRM_FORMAT_BGR888;
+ break;
+ case kFormatRGB565:
+ *drm_format = DRM_FORMAT_BGR565;
+ break;
+ case kFormatBGR565:
+ *drm_format = DRM_FORMAT_RGB565;
+ break;
+ case kFormatBGR565Ubwc:
+ *drm_format = DRM_FORMAT_BGR565;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case kFormatRGBA1010102:
+ *drm_format = DRM_FORMAT_ABGR2101010;
+ break;
+ case kFormatRGBA1010102Ubwc:
+ *drm_format = DRM_FORMAT_ABGR2101010;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case kFormatARGB2101010:
+ *drm_format = DRM_FORMAT_BGRA1010102;
+ break;
+ case kFormatRGBX1010102:
+ *drm_format = DRM_FORMAT_XBGR2101010;
+ break;
+ case kFormatRGBX1010102Ubwc:
+ *drm_format = DRM_FORMAT_XBGR2101010;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case kFormatXRGB2101010:
+ *drm_format = DRM_FORMAT_BGRX1010102;
+ break;
+ case kFormatBGRA1010102:
+ *drm_format = DRM_FORMAT_ARGB2101010;
+ break;
+ case kFormatABGR2101010:
+ *drm_format = DRM_FORMAT_RGBA1010102;
+ break;
+ case kFormatBGRX1010102:
+ *drm_format = DRM_FORMAT_XRGB2101010;
+ break;
+ case kFormatXBGR2101010:
+ *drm_format = DRM_FORMAT_RGBX1010102;
+ break;
+ case kFormatYCbCr420SemiPlanar:
+ *drm_format = DRM_FORMAT_NV12;
+ break;
+ case kFormatYCbCr420SemiPlanarVenus:
+ *drm_format = DRM_FORMAT_NV12;
+ break;
+ case kFormatYCbCr420SPVenusUbwc:
+ *drm_format = DRM_FORMAT_NV12;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case kFormatYCrCb420SemiPlanar:
+ *drm_format = DRM_FORMAT_NV21;
+ break;
+ case kFormatYCrCb420SemiPlanarVenus:
+ *drm_format = DRM_FORMAT_NV21;
+ break;
+ case kFormatYCbCr420P010:
+ *drm_format = DRM_FORMAT_NV12;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
+ break;
+ case kFormatYCbCr420P010Ubwc:
+ *drm_format = DRM_FORMAT_NV12;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
+ DRM_FORMAT_MOD_QCOM_DX;
+ break;
+ case kFormatYCbCr420TP10Ubwc:
+ *drm_format = DRM_FORMAT_NV12;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
+ DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
+ break;
+ case kFormatYCbCr422H2V1SemiPlanar:
+ *drm_format = DRM_FORMAT_NV16;
+ break;
+ case kFormatYCrCb422H2V1SemiPlanar:
+ *drm_format = DRM_FORMAT_NV61;
+ break;
+ case kFormatYCrCb420PlanarStride16:
+ *drm_format = DRM_FORMAT_YVU420;
+ break;
+ default:
+ DLOGW("Unsupported format %s", GetFormatString(format));
+ }
+}
+
+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());
+
+ 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;
+ HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
+ HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0];
+
+ if (hw_rotate_info->valid) {
+ input_buffer = &hw_rotator_session->output_buffer;
+ }
+
+ 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;
+ }
+ }
+ }
+}
+
+void HWDeviceDRM::Registry::UnregisterNext() {
+ DRMMaster *master = nullptr;
+ DRMMaster::GetInstance(&master);
+
+ if (!master) {
+ DLOGE("Failed to acquire DRM Master instance");
+ return;
+ }
+
+ current_index_ = (current_index_ + 1) % kCycleDelay;
+ auto &curr_map = hashmap_[current_index_];
+ for (auto &pair : curr_map) {
+ uint32_t fb_id = pair.second;
+ int ret = master->RemoveFbId(fb_id);
+ if (ret < 0) {
+ DLOGE("Removing fb_id %d failed with error %d", fb_id, errno);
+ }
+ }
+
+ curr_map.clear();
+}
+
+void HWDeviceDRM::Registry::Clear() {
+ for (int i = 0; i < kCycleDelay; i++) {
+ UnregisterNext();
+ }
+ current_index_ = 0;
+}
+
+uint32_t HWDeviceDRM::Registry::GetFbId(int fd) {
+ auto it = hashmap_[current_index_].find(fd);
+ return (it == hashmap_[current_index_].end()) ? 0 : it->second;
+}
+
+HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ HWInfoInterface *hw_info_intf)
+ : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
+ registry_(buffer_allocator) {
device_type_ = kDevicePrimary;
device_name_ = "Peripheral Display";
hw_info_intf_ = hw_info_intf;
@@ -126,10 +341,17 @@
UpdateMixerAttributes();
hw_info_intf_->GetHWResourceInfo(&hw_resource_);
+ // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
+ if (hw_resource_.has_qseed3) {
+ hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
+ }
+
return kErrorNone;
}
DisplayError HWDeviceDRM::Deinit() {
+ delete hw_scale_;
+ registry_.Clear();
drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
drm_atomic_intf_ = {};
drm_mgr_intf_->UnregisterDisplay(token_);
@@ -384,7 +606,8 @@
needs_rotation = true;
}
- if (pipe_info->valid && input_buffer->fb_id) {
+ uint32_t fb_id = registry_.GetFbId(input_buffer->planes[0].fd);
+ if (pipe_info->valid && fb_id) {
uint32_t pipe_id = pipe_info->pipe_id;
drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha);
drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ZORDER, pipe_id, pipe_info->z_order);
@@ -417,12 +640,21 @@
uint32_t config = 0;
SetSrcConfig(layer.input_buffer, &config);
drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_CONFIG, pipe_id, config);;
- drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, input_buffer->fb_id);
+ drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, fb_id);
drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id);
if (!validate && input_buffer->acquire_fence_fd >= 0) {
drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id,
input_buffer->acquire_fence_fd);
}
+ if (hw_scale_) {
+ SDEScaler scaler_output = {};
+ hw_scale_->SetPlaneScaler(pipe_info->scale_data, &scaler_output);
+ // TODO(user): Remove qseed3 and add version check, then send appropriate scaler object
+ if (hw_resource_.has_qseed3) {
+ drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SCALER_CONFIG, pipe_id,
+ reinterpret_cast<uint64_t>(&scaler_output.scaler_v2));
+ }
+ }
}
}
@@ -433,6 +665,8 @@
DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
DTRACE_SCOPED();
+
+ registry_.RegisterCurrent(hw_layers);
SetupAtomic(hw_layers, true /* validate */);
int ret = drm_atomic_intf_->Validate();
@@ -446,11 +680,19 @@
DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) {
DTRACE_SCOPED();
+
+ DisplayError err = kErrorNone;
+ registry_.RegisterCurrent(hw_layers);
+
if (default_mode_) {
- return DefaultCommit(hw_layers);
+ err = DefaultCommit(hw_layers);
+ } else {
+ err = AtomicCommit(hw_layers);
}
- return AtomicCommit(hw_layers);
+ registry_.UnregisterNext();
+
+ return err;
}
DisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) {
@@ -490,12 +732,12 @@
drmModeModeInfo mode;
res_mgr->GetMode(&mode);
- LayerBuffer &input_buffer = hw_layer_info.hw_layers.at(0).input_buffer;
- ret = drmModeSetCrtc(dev_fd, crtc_id, input_buffer.fb_id, 0 /* x */, 0 /* y */, &connector_id,
+ uint32_t fb_id = registry_.GetFbId(hw_layer_info.hw_layers.at(0).input_buffer.planes[0].fd);
+ ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id,
1 /* num_connectors */, &mode);
if (ret < 0) {
DLOGE("drmModeSetCrtc failed dev fd %d, fb_id %d, crtc id %d, connector id %d, %s", dev_fd,
- input_buffer.fb_id, crtc_id, connector_id, strerror(errno));
+ fb_id, crtc_id, connector_id, strerror(errno));
return kErrorHardware;
}
@@ -719,6 +961,15 @@
}
DisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
+ sde_drm::DRMScalerLUTInfo drm_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;
+ drm_mgr_intf_->SetScalerLUT(drm_lut_info);
+
return kErrorNone;
}
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 034826c..cc2ae7b 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -35,9 +35,11 @@
#include <pthread.h>
#include <xf86drmMode.h>
#include <string>
+#include <unordered_map>
#include <vector>
#include "hw_interface.h"
+#include "hw_scale_drm.h"
#define IOCTL_LOGE(ioctl, type) \
DLOGE("ioctl %s, device = %d errno = %d, desc = %s", #ioctl, type, errno, strerror(errno))
@@ -47,7 +49,8 @@
class HWDeviceDRM : public HWInterface {
public:
- explicit HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
+ explicit HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ HWInfoInterface *hw_info_intf);
virtual ~HWDeviceDRM() {}
virtual DisplayError Init();
virtual DisplayError Deinit();
@@ -98,6 +101,8 @@
static const int kMaxStringLength = 1024;
static const int kNumPhysicalDisplays = 2;
static const int kMaxSysfsCommandLength = 12;
+ static constexpr const char *kBrightnessNode =
+ "/sys/class/backlight/panel0-backlight/brightness";
DisplayError SetFormat(const LayerBufferFormat &source, uint32_t *target);
DisplayError SetStride(HWDeviceType device_type, LayerBufferFormat format, uint32_t width,
@@ -117,6 +122,27 @@
DisplayError AtomicCommit(HWLayers *hw_layers);
void SetupAtomic(HWLayers *hw_layers, bool validate);
+ class Registry {
+ public:
+ explicit Registry(BufferAllocator *buffer_allocator) : buffer_allocator_(buffer_allocator) {}
+ // Call on each validate and commit to register layer buffers
+ void RegisterCurrent(HWLayers *hw_layers);
+ // Call at the end of draw cycle to clear the next slot for business
+ void UnregisterNext();
+ // Call on display disconnect to release all gem handles and fb_ids
+ void Clear();
+ // Finds an fb_id corresponding to an fd in current map
+ uint32_t GetFbId(int fd);
+
+ private:
+ 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] {};
+ int current_index_ = 0;
+ BufferAllocator *buffer_allocator_ = {};
+ };
+
HWResourceInfo hw_resource_ = {};
HWPanelInfo hw_panel_info_ = {};
HWInfoInterface *hw_info_intf_ = {};
@@ -133,7 +159,8 @@
bool default_mode_ = false;
sde_drm::DRMConnectorInfo connector_info_ = {};
std::string interface_str_ = "DSI";
- const char *kBrightnessNode = "/sys/class/backlight/panel0-backlight/brightness";
+ HWScaleDRM *hw_scale_ = {};
+ Registry registry_;
};
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 48464e9..f7ce652 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -54,7 +54,6 @@
#include "hw_info_drm.h"
-#ifdef COMPILE_DRM
#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
#endif
@@ -64,7 +63,6 @@
#ifndef DRM_FORMAT_MOD_QCOM_TIGHT
#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
#endif
-#endif
#define __CLASS__ "HWInfoDRM"
diff --git a/sdm/libs/core/drm/hw_scale_drm.cpp b/sdm/libs/core/drm/hw_scale_drm.cpp
new file mode 100644
index 0000000..96f084e
--- /dev/null
+++ b/sdm/libs/core/drm/hw_scale_drm.cpp
@@ -0,0 +1,157 @@
+/*
+* 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_drm.h"
+
+#define __CLASS__ "HWScaleDRM"
+
+namespace sdm {
+
+static uint32_t GetScalingFilter(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;
+ }
+}
+
+static uint32_t GetAlphaInterpolation(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 HWScaleDRM::SetPlaneScaler(const HWScaleData &scale_data, SDEScaler *scaler) {
+ if (version_ == Version::V2) {
+ SetPlaneScalerV2(scale_data, &scaler->scaler_v2);
+ }
+}
+
+void HWScaleDRM::SetPlaneScalerV2(const HWScaleData &scale_data, sde_drm_scaler_v2 *scaler) {
+ if (!scale_data.enable.scale && !scale_data.enable.direction_detection &&
+ !scale_data.enable.detail_enhance) {
+ return;
+ }
+
+ scaler->enable = scale_data.enable.scale;
+ scaler->dir_en = scale_data.enable.direction_detection;
+ scaler->de.enable = scale_data.detail_enhance.enable;
+
+ for (int i = 0; i < SDE_MAX_PLANES; i++) {
+ const HWPlane &plane = scale_data.plane[i];
+ scaler->init_phase_x[i] = plane.init_phase_x;
+ scaler->phase_step_x[i] = plane.phase_step_x;
+ scaler->init_phase_y[i] = plane.init_phase_y;
+ scaler->phase_step_y[i] = plane.phase_step_y;
+
+ // TODO(user): Remove right, bottom from HWPlane and rename to LR, TB similar to qseed3
+ // Also remove roi_width which is unused.
+ scaler->pe.num_ext_pxls_lr[i] = plane.left.extension;
+ scaler->pe.num_ext_pxls_tb[i] = plane.top.extension;
+
+ scaler->pe.left_ftch[i] = plane.left.overfetch;
+ scaler->pe.top_ftch[i] = plane.top.overfetch;
+ scaler->pe.right_ftch[i] = plane.right.overfetch;
+ scaler->pe.btm_ftch[i] = plane.bottom.overfetch;
+
+ scaler->pe.left_rpt[i] = plane.left.repeat;
+ scaler->pe.top_rpt[i] = plane.top.repeat;
+ scaler->pe.right_rpt[i] = plane.right.repeat;
+ scaler->pe.btm_rpt[i] = plane.bottom.repeat;
+
+ scaler->preload_x[i] = UINT32(plane.preload_x);
+ scaler->preload_y[i] = UINT32(plane.preload_y);
+
+ scaler->src_width[i] = plane.src_width;
+ scaler->src_height[i] = plane.src_height;
+ }
+
+ scaler->dst_width = scale_data.dst_width;
+ scaler->dst_height = scale_data.dst_height;
+
+ scaler->y_rgb_filter_cfg = GetScalingFilter(scale_data.y_rgb_filter_cfg);
+ scaler->uv_filter_cfg = GetScalingFilter(scale_data.uv_filter_cfg);
+ scaler->alpha_filter_cfg = GetAlphaInterpolation(scale_data.alpha_filter_cfg);
+ scaler->blend_cfg = scale_data.blend_cfg;
+
+ scaler->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);
+
+ scaler->dir_lut_idx = scale_data.dir_lut_idx;
+ scaler->y_rgb_cir_lut_idx = scale_data.y_rgb_cir_lut_idx;
+ scaler->uv_cir_lut_idx = scale_data.uv_cir_lut_idx;
+ scaler->y_rgb_sep_lut_idx = scale_data.y_rgb_sep_lut_idx;
+ scaler->uv_sep_lut_idx = scale_data.uv_sep_lut_idx;
+
+ /* TODO(user): Uncomment when de support is added
+ if (scaler->de.enable) {
+ sde_drm_de_v1 *det_enhance = &scaler->de;
+ det_enhance->sharpen_level1 = scale_data.detail_enhance.sharpen_level1;
+ det_enhance->sharpen_level2 = scale_data.detail_enhance.sharpen_level2;
+ det_enhance->clip = scale_data.detail_enhance.clip;
+ det_enhance->limit = scale_data.detail_enhance.limit;
+ det_enhance->thr_quiet = scale_data.detail_enhance.thr_quiet;
+ det_enhance->thr_dieout = scale_data.detail_enhance.thr_dieout;
+ det_enhance->thr_low = scale_data.detail_enhance.thr_low;
+ det_enhance->thr_high = scale_data.detail_enhance.thr_high;
+ det_enhance->prec_shift = scale_data.detail_enhance.prec_shift;
+
+ for (int i = 0; i < SDE_MAX_DE_CURVES; i++) {
+ det_enhance->adjust_a[i] = scale_data.detail_enhance.adjust_a[i];
+ det_enhance->adjust_b[i] = scale_data.detail_enhance.adjust_b[i];
+ det_enhance->adjust_c[i] = scale_data.detail_enhance.adjust_c[i];
+ }
+ }
+ */
+
+ return;
+}
+
+} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_scale_drm.h b/sdm/libs/core/drm/hw_scale_drm.h
new file mode 100644
index 0000000..8a4be70
--- /dev/null
+++ b/sdm/libs/core/drm/hw_scale_drm.h
@@ -0,0 +1,63 @@
+/*
+* 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.
+*/
+
+#ifndef __HW_SCALE_DRM_H__
+#define __HW_SCALE_DRM_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <drm.h>
+// The 3 headers above are a workaround to prevent kernel drm.h from being used that has the
+// "virtual" keyword used for a variable. In future replace libdrm version drm.h with kernel
+// version drm/drm.h
+#include <drm/sde_drm.h>
+#include <private/hw_info_types.h>
+
+namespace sdm {
+
+struct SDEScaler {
+ struct sde_drm_scaler_v2 scaler_v2 = {};
+ // More here, maybe in a union
+};
+
+class HWScaleDRM {
+ public:
+ enum class Version { V2 };
+ explicit HWScaleDRM(Version v) : version_(v) {}
+ void SetPlaneScaler(const HWScaleData &scale, SDEScaler *scaler);
+
+ private:
+ void SetPlaneScalerV2(const HWScaleData &scale, sde_drm_scaler_v2 *scaler_v2);
+
+ Version version_ = Version::V2;
+};
+
+} // namespace sdm
+
+#endif // __HW_SCALE_DRM_H__
diff --git a/sdm/libs/core/hw_interface.cpp b/sdm/libs/core/hw_interface.cpp
index b328831..b5c9fe9 100644
--- a/sdm/libs/core/hw_interface.cpp
+++ b/sdm/libs/core/hw_interface.cpp
@@ -45,7 +45,7 @@
DisplayError HWInterface::Create(DisplayType type, HWInfoInterface *hw_info_intf,
BufferSyncHandler *buffer_sync_handler,
- HWInterface **intf) {
+ BufferAllocator *buffer_allocator, HWInterface **intf) {
DisplayError error = kErrorNone;
HWInterface *hw = nullptr;
DriverType driver_type = GetDriverType();
@@ -56,7 +56,7 @@
hw = new HWPrimary(buffer_sync_handler, hw_info_intf);
} else {
#ifdef COMPILE_DRM
- hw = new HWDeviceDRM(buffer_sync_handler, hw_info_intf);
+ hw = new HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
#endif
}
break;
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index 23c6114..5dbeb11 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -25,11 +25,12 @@
#ifndef __HW_INTERFACE_H__
#define __HW_INTERFACE_H__
+#include <core/buffer_allocator.h>
+#include <core/buffer_sync_handler.h>
#include <core/display_interface.h>
#include <private/hw_info_types.h>
#include <private/color_interface.h>
#include <utils/constants.h>
-#include <core/buffer_sync_handler.h>
#include "hw_info_interface.h"
@@ -68,7 +69,8 @@
class HWInterface {
public:
static DisplayError Create(DisplayType type, HWInfoInterface *hw_info_intf,
- BufferSyncHandler *buffer_sync_handler, HWInterface **intf);
+ BufferSyncHandler *buffer_sync_handler,
+ BufferAllocator *buffer_allocator, HWInterface **intf);
static DisplayError Destroy(HWInterface *intf);
virtual DisplayError Init() = 0;
diff --git a/sdm/libs/hwc/hwc_buffer_allocator.cpp b/sdm/libs/hwc/hwc_buffer_allocator.cpp
index 80d72f7..25f366f 100644
--- a/sdm/libs/hwc/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc/hwc_buffer_allocator.cpp
@@ -34,17 +34,12 @@
#include <utils/constants.h>
#include <utils/debug.h>
#include <core/buffer_allocator.h>
-#include <drm_master.h>
-#include <qd_utils.h>
#include "hwc_debugger.h"
#include "hwc_buffer_allocator.h"
#define __CLASS__ "HWCBufferAllocator"
-using drm_utils::DRMMaster;
-using drm_utils::DRMBuffer;
-
namespace sdm {
HWCBufferAllocator::HWCBufferAllocator() {
@@ -123,49 +118,6 @@
buffer_info->private_data = meta_buffer_info;
- if (qdutils::getDriverType() == qdutils::DriverType::DRM) {
- private_handle_t handle(-1, 0, 0, 0, 0, 0, 0);
- // Setup only the required stuff, skip rest
- handle.base = reinterpret_cast<uint64_t>(data.base);
- handle.format = format;
- handle.width = aligned_width;
- handle.height = aligned_height;
- if (alloc_flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
- handle.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
- }
- private_handle_t *hnd = &handle;
- DRMBuffer buf = {};
- int ret = getPlaneStrideOffset(hnd, buf.stride, buf.offset,
- &buf.num_planes);
- if (ret < 0) {
- DLOGE("getPlaneStrideOffset failed");
- return kErrorParameters;
- }
-
- buf.fd = data.fd;
- buf.width = UINT32(hnd->width);
- buf.height = UINT32(hnd->height);
- getDRMFormat(hnd->format, hnd->flags, &buf.drm_format,
- &buf.drm_format_modifier);
-
- DRMMaster *master = nullptr;
- ret = DRMMaster::GetInstance(&master);
- if (ret < 0) {
- DLOGE("Failed to acquire DRMMaster instance");
- return kErrorParameters;
- }
-
- ret = master->CreateFbId(buf, &alloc_buffer_info->gem_handle, &alloc_buffer_info->fb_id);
- if (ret < 0) {
- DLOGE("CreateFbId failed. width %d, height %d, " \
- "format: %s, stride %u, error %d",
- buf.width, buf.height,
- qdutils::GetHALPixelFormatString(hnd->format),
- buf.stride[0], errno);
- return kErrorParameters;
- }
- }
-
return kErrorNone;
}
@@ -201,25 +153,6 @@
delete meta_buffer_info;
meta_buffer_info = NULL;
-
- if (alloc_buffer_info->fb_id) {
- DRMMaster *master = nullptr;
- int ret = DRMMaster::GetInstance(&master);
- if (ret < 0) {
- DLOGE("Failed to acquire DRMMaster instance");
- return kErrorParameters;
- }
-
- ret = master->RemoveFbId(alloc_buffer_info->gem_handle, alloc_buffer_info->fb_id);
- if (ret < 0) {
- DLOGE("Removing fb_id %d failed with error %d",
- alloc_buffer_info->fb_id, errno);
- return kErrorParameters;
- }
-
- alloc_buffer_info->fb_id = 0;
- alloc_buffer_info->gem_handle = 0;
- }
}
return kErrorNone;
@@ -364,6 +297,32 @@
allocated_buffer_info->aligned_width = UINT32(width_aligned);
allocated_buffer_info->aligned_height = UINT32(height_aligned);
allocated_buffer_info->size = UINT32(buffer_size);
+ allocated_buffer_info->format = buffer_config.format;
+
+ return kErrorNone;
+}
+
+DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
+ uint32_t stride[4], uint32_t offset[4],
+ uint32_t *num_planes) {
+ private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
+ int format = HAL_PIXEL_FORMAT_RGBA_8888;
+ int flags = 0;
+
+ SetBufferInfo(buf_info.format, &format, &flags);
+ // Setup only the required stuff, skip rest
+ hnd.format = format;
+ hnd.width = buf_info.aligned_width;
+ hnd.height = buf_info.aligned_height;
+ if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
+ hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ }
+
+ int ret = getBufferLayout(&hnd, stride, offset, num_planes);
+ if (ret < 0) {
+ DLOGE("getBufferLayout failed");
+ return kErrorParameters;
+ }
return kErrorNone;
}
diff --git a/sdm/libs/hwc/hwc_buffer_allocator.h b/sdm/libs/hwc/hwc_buffer_allocator.h
index af8e9a3..a8cf462 100644
--- a/sdm/libs/hwc/hwc_buffer_allocator.h
+++ b/sdm/libs/hwc/hwc_buffer_allocator.h
@@ -51,7 +51,9 @@
uint32_t GetBufferSize(BufferInfo *buffer_info);
DisplayError GetAllocatedBufferInfo(const BufferConfig &buffer_config,
AllocatedBufferInfo *allocated_buffer_info);
-
+ DisplayError GetBufferLayout(const AllocatedBufferInfo &buf_info,
+ uint32_t stride[4], uint32_t offset[4],
+ uint32_t *num_planes);
int SetBufferInfo(LayerBufferFormat format, int *target, int *flags);
private:
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index bb062cd..770ced6 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -436,6 +436,7 @@
LayerBuffer &layer_buffer = layer->input_buffer;
if (pvt_handle) {
+ layer_buffer.planes[0].fd = pvt_handle->fd;
layer_buffer.format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
int aligned_width, aligned_height;
int unaligned_width, unaligned_height;
@@ -449,7 +450,6 @@
layer_buffer.height = UINT32(aligned_height);
layer_buffer.unaligned_width = UINT32(unaligned_width);
layer_buffer.unaligned_height = UINT32(unaligned_height);
- layer_buffer.fb_id = pvt_handle->fb_id;
if (SetMetaData(pvt_handle, layer) != kErrorNone) {
return -EINVAL;
@@ -521,7 +521,6 @@
layer_buffer.planes[0].offset = pvt_handle->offset;
layer_buffer.planes[0].stride = UINT32(pvt_handle->width);
layer_buffer.size = pvt_handle->size;
- layer_buffer.fb_id = pvt_handle->fb_id;
}
// if swapinterval property is set to 0 then close and reset the acquireFd
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index e6aa70f..8a5bd81 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -140,12 +140,18 @@
return -EINVAL;
}
+ SCOPE_LOCK(uevent_locker_);
+
if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno));
CoreInterface::DestroyCore();
return -errno;
}
+ // Wait for uevent_init() to happen and let the uevent thread wait for uevents, so that hdmi
+ // connect/disconnect events won't be missed
+ uevent_locker_.Wait();
+
// Read which display is first, and create it and store it in primary slot
HWDisplayInterfaceInfo hw_disp_info;
error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
@@ -465,6 +471,8 @@
}
int HWCSession::EventControl(hwc_composer_device_1 *device, int disp, int event, int enable) {
+ SCOPE_LOCK(locker_);
+
if (!device) {
return -EINVAL;
}
@@ -1418,14 +1426,21 @@
void* HWCSession::HWCUeventThreadHandler() {
static char uevent_data[PAGE_SIZE];
int length = 0;
+
+ uevent_locker_.Lock();
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);
+ uevent_locker_.Signal();
+ uevent_locker_.Unlock();
return NULL;
}
+ uevent_locker_.Signal();
+ uevent_locker_.Unlock();
+
while (!uevent_thread_exit_) {
// keep last 2 zeroes to ensure double 0 termination
length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index c3ffa98..1cd3e33 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -153,6 +153,7 @@
bool is_hdmi_yuv_ = false;
std::bitset<HWC_NUM_DISPLAY_TYPES> connected_displays_; // Bit mask of connected displays
HWCSocketHandler socket_handler_;
+ Locker uevent_locker_;
};
} // namespace sdm
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
index ca1ebae..0bc5acf 100644
--- a/sdm/libs/hwc2/Android.mk
+++ b/sdm/libs/hwc2/Android.mk
@@ -24,7 +24,7 @@
LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware libhardware_legacy \
libutils libcutils libsync libqdutils libqdMetaData libdl \
- libpowermanager libsdmutils libc++ liblog libdrmutils
+ libpowermanager libsdmutils libc++ liblog libgrallocutils
ifneq ($(TARGET_USES_GRALLOC1), true)
LOCAL_SHARED_LIBRARIES += libmemalloc
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index 3cfaf0a..b7fcac3 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -35,8 +35,10 @@
#include "hwc_buffer_allocator.h"
#include "hwc_debugger.h"
+#include "gr_utils.h"
#define __CLASS__ "HWCBufferAllocator"
+
namespace sdm {
HWCBufferAllocator::HWCBufferAllocator() {
@@ -64,7 +66,7 @@
uint32_t width = buffer_config.width;
uint32_t height = buffer_config.height;
int format;
- int alloc_flags = 0;
+ uint64_t alloc_flags = 0;
int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
if (error != 0) {
return kErrorParameters;
@@ -78,8 +80,8 @@
// Allocate uncached buffers
alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
}
- uint64_t producer_usage = UINT64(alloc_flags);
- uint64_t consumer_usage = UINT64(alloc_flags);
+ uint64_t producer_usage = alloc_flags;
+ uint64_t consumer_usage = alloc_flags;
// CreateBuffer
private_handle_t *hnd = nullptr;
Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format,
@@ -103,6 +105,7 @@
buffer_handle_t hnd = static_cast<private_handle_t *>(buffer_info->private_data);
ReleaseBuffer_(gralloc_device_, hnd);
AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
+
alloc_buffer_info->fd = -1;
alloc_buffer_info->stride = 0;
alloc_buffer_info->size = 0;
@@ -136,7 +139,7 @@
uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
const BufferConfig &buffer_config = buffer_info->buffer_config;
- int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
+ uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
int width = INT(buffer_config.width);
int height = INT(buffer_config.height);
@@ -156,17 +159,17 @@
}
uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
- uint64_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
- uint64_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
+ gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
+ gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
// TODO(user): Currently both flags are treated similarly in gralloc
- producer_usage = UINT64(alloc_flags);
- consumer_usage = producer_usage;
- Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS, width, height,
- format, producer_usage, consumer_usage, &aligned_width, &aligned_height, &buffer_size);
+ producer_usage = gralloc1_producer_usage_t(alloc_flags);
+ consumer_usage = gralloc1_consumer_usage_t(alloc_flags);
+ gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage);
+ GetBufferSizeAndDimensions(info, &aligned_width, &aligned_height, &buffer_size);
return buffer_size;
}
-int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int *flags) {
+int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags) {
switch (format) {
case kFormatRGBA8888:
*target = HAL_PIXEL_FORMAT_RGBA_8888;
@@ -209,6 +212,7 @@
break;
case kFormatYCbCr420SPVenusUbwc:
*target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+ *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
break;
case kFormatRGBA5551:
*target = HAL_PIXEL_FORMAT_RGBA_5551;
@@ -245,9 +249,11 @@
break;
case kFormatYCbCr420TP10Ubwc:
*target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
+ *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
break;
case kFormatYCbCr420P010Ubwc:
*target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
+ *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
break;
case kFormatRGBA8888Ubwc:
*target = HAL_PIXEL_FORMAT_RGBA_8888;
@@ -280,7 +286,7 @@
const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
// TODO(user): This API should pass the buffer_info of the already allocated buffer
// The private_data can then be typecast to the private_handle and used directly.
- int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
+ uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
int width = INT(buffer_config.width);
int height = INT(buffer_config.height);
@@ -300,13 +306,13 @@
}
uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
- uint64_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
- uint64_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
+ gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
+ gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
// TODO(user): Currently both flags are treated similarly in gralloc
- producer_usage = UINT64(alloc_flags);
- consumer_usage = producer_usage;
- Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS, width, height,
- format, producer_usage, consumer_usage, &aligned_width, &aligned_height, &buffer_size);
+ producer_usage = gralloc1_producer_usage_t(alloc_flags);
+ consumer_usage = gralloc1_consumer_usage_t(alloc_flags);
+ gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage);
+ GetBufferSizeAndDimensions(info, &aligned_width, &aligned_height, &buffer_size);
allocated_buffer_info->stride = UINT32(aligned_width);
allocated_buffer_info->aligned_width = UINT32(aligned_width);
allocated_buffer_info->aligned_height = UINT32(aligned_height);
@@ -315,4 +321,30 @@
return kErrorNone;
}
+DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
+ uint32_t stride[4], uint32_t offset[4],
+ uint32_t *num_planes) {
+ // TODO(user): Transition APIs to not need a private handle
+ private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
+ int format = HAL_PIXEL_FORMAT_RGBA_8888;
+ uint64_t flags = 0;
+
+ SetBufferInfo(buf_info.format, &format, &flags);
+ // Setup only the required stuff, skip rest
+ hnd.format = format;
+ hnd.width = INT32(buf_info.aligned_width);
+ hnd.height = INT32(buf_info.aligned_height);
+ if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
+ hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ }
+
+ int ret = gralloc1::GetBufferLayout(&hnd, stride, offset, num_planes);
+ if (ret < 0) {
+ DLOGE("GetBufferLayout failed");
+ return kErrorParameters;
+ }
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.h b/sdm/libs/hwc2/hwc_buffer_allocator.h
index c28a94e..d574401 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.h
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.h
@@ -57,7 +57,10 @@
int *aligned_width, int *aligned_height);
DisplayError GetAllocatedBufferInfo(const BufferConfig &buffer_config,
AllocatedBufferInfo *allocated_buffer_info);
- int SetBufferInfo(LayerBufferFormat format, int *target, int *flags);
+ DisplayError GetBufferLayout(const AllocatedBufferInfo &buf_info,
+ uint32_t stride[4], uint32_t offset[4],
+ uint32_t *num_planes);
+ int SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags);
private:
gralloc1_device_t *gralloc_device_ = nullptr;
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 0aaad8e..a39476e 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -189,6 +189,8 @@
PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string);
} else if (mode_string.find("hal_dci_p3") != std::string::npos) {
PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string);
+ } else if (mode_string.find("hal_display_p3") != std::string::npos) {
+ PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string);
}
}
}
@@ -573,6 +575,10 @@
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);
@@ -591,6 +597,7 @@
break;
default:
DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
+ *out_value = -1;
return HWC2::Error::BadConfig;
}
@@ -668,6 +675,9 @@
}
HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
+ if (config != 0) {
+ return HWC2::Error::BadConfig;
+ }
// We have only one config right now - do nothing
return HWC2::Error::None;
}
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 302e339..aec44ad 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -154,7 +154,6 @@
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 = handle->fb_id;
return HWC2::Error::None;
}
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index bf52ef6..255cb48 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -140,9 +140,11 @@
struct rlimit fd_limit = {};
getrlimit(RLIMIT_NOFILE, &fd_limit);
fd_limit.rlim_cur = fd_limit.rlim_cur * 2;
- auto err = setrlimit(RLIMIT_NOFILE, &fd_limit);
- if (err) {
- DLOGW("Unable to increase fd limit - err:%d, %s", errno, strerror(errno));
+ if (fd_limit.rlim_cur < fd_limit.rlim_max) {
+ auto err = setrlimit(RLIMIT_NOFILE, &fd_limit);
+ if (err) {
+ DLOGW("Unable to increase fd limit - err:%d, %s", errno, strerror(errno));
+ }
}
return 0;
}
@@ -369,11 +371,13 @@
}
static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display, int32_t *out_support) {
- // TODO(user): Check if it is an HDMI as primary display and disable support for it
if (display == HWC_DISPLAY_PRIMARY) {
*out_support = 1;
} else {
+ // TODO(user): Port over connect_display_ from HWC1
+ // Return no error for connected displays
*out_support = 0;
+ return HWC2_ERROR_BAD_DISPLAY;
}
return HWC2_ERROR_NONE;
}