From 448917d6623ed07091e0f3a1efa5ced31fcd50d4 Mon Sep 17 00:00:00 2001 From: Yuanjun Huang Date: Sat, 17 Mar 2018 18:18:19 -0700 Subject: [PATCH] Add Render Buffer Compression support in HWComposer. Jira: https://jira01.devtools.intel.com/browse/AREQ-23273 Test: Build passes and validates both on Linux and Android. Signed-off-by: Yuanjun Huang --- Android.common.mk | 6 +- Makefile.am | 5 ++ Makefile.sources | 1 + common/core/framebuffermanager.cpp | 17 ++-- common/core/framebuffermanager.h | 1 + os/android/gralloc1bufferhandler.cpp | 30 +++++-- os/android/gralloc1bufferhandler.h | 3 + os/android/platformdefines.cpp | 20 ----- os/linux/gbmbufferhandler.cpp | 162 ++++++++++++++++++++++++++++++----- os/linux/platformdefines.cpp | 20 ----- os/linux/platformdefines.h | 8 +- os/platformcommondefines.h | 1 + os/platformcommondrmdefines.cpp | 51 +++++++++++ public/hwcbuffer.h | 1 + tests/common/gllayerrenderer.cpp | 62 +++++++++++--- wsi/drm/drmbuffer.cpp | 55 +++++++++++- wsi/drm/drmbuffer.h | 1 + 17 files changed, 349 insertions(+), 95 deletions(-) create mode 100644 os/platformcommondrmdefines.cpp diff --git a/Android.common.mk b/Android.common.mk index f3480ee..61e129d 100644 --- a/Android.common.mk +++ b/Android.common.mk @@ -52,6 +52,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/wsi/drm LOCAL_SRC_FILES := \ + os/platformcommondrmdefines.cpp \ os/android/platformdefines.cpp ifeq ($(strip $(TARGET_USES_HWC2)), true) @@ -69,6 +70,8 @@ LOCAL_SHARED_LIBRARIES += \ LOCAL_CPPFLAGS += -DENABLE_DOUBLE_BUFFERING endif +LOCAL_CPPFLAGS += -DUSE_GRALLOC1 + ifeq ($(strip $(ENABLE_NESTED_DISPLAY_SUPPORT)), true) LOCAL_CPPFLAGS += -DNESTED_DISPLAY_SUPPORT endif @@ -108,7 +111,8 @@ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../mesa/include else LOCAL_CPPFLAGS += \ - -DUSE_GL + -DUSE_GL \ + -DENABLE_RBC endif LOCAL_C_INCLUDES += \ diff --git a/Makefile.am b/Makefile.am index 5b169c4..1a80ac0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,6 +36,11 @@ if !ENABLE_GBM AM_CPPFLAGS += -DUSE_MINIGBM endif + +if !ENABLE_VULKAN +AM_CPPFLAGS += -DENABLE_RBC +endif + libhwcomposer_la_LIBADD = \ $(DRM_LIBS) \ $(GBM_LIBS) \ diff --git a/Makefile.sources b/Makefile.sources index a8b7219..cfaa81a 100644 --- a/Makefile.sources +++ b/Makefile.sources @@ -1,4 +1,5 @@ hwc_SOURCES = \ + os/platformcommondrmdefines.cpp \ os/linux/gbmbufferhandler.cpp \ os/linux/pixeluploader.cpp \ os/linux/platformdefines.cpp \ diff --git a/common/core/framebuffermanager.cpp b/common/core/framebuffermanager.cpp index 6cb6f53..ba4e9a3 100644 --- a/common/core/framebuffermanager.cpp +++ b/common/core/framebuffermanager.cpp @@ -49,13 +49,11 @@ void FrameBufferManager::RegisterGemHandles(const uint32_t &num_planes, lock_.unlock(); } -uint32_t FrameBufferManager::FindFB(const uint32_t &iwidth, - const uint32_t &iheight, - const uint32_t &iframe_buffer_format, - const uint32_t &num_planes, - const uint32_t (&igem_handles)[4], - const uint32_t (&ipitches)[4], - const uint32_t (&ioffsets)[4]) { +uint32_t FrameBufferManager::FindFB( + const uint32_t &iwidth, const uint32_t &iheight, const uint32_t &modifier, + const uint32_t &iframe_buffer_format, const uint32_t &num_planes, + const uint32_t (&igem_handles)[4], const uint32_t (&ipitches)[4], + const uint32_t (&ioffsets)[4]) { lock_.lock(); FBKey key(num_planes, igem_handles); uint32_t fb_id = 0; @@ -63,8 +61,9 @@ uint32_t FrameBufferManager::FindFB(const uint32_t &iwidth, if (it != fb_map_.end()) { if (!it->second.fb_created) { it->second.fb_created = true; - CreateFrameBuffer(iwidth, iheight, iframe_buffer_format, igem_handles, - ipitches, ioffsets, gpu_fd_, &it->second.fb_id); + CreateFrameBuffer(iwidth, iheight, modifier, iframe_buffer_format, + igem_handles, ipitches, ioffsets, gpu_fd_, + &it->second.fb_id); } fb_id = it->second.fb_id; diff --git a/common/core/framebuffermanager.h b/common/core/framebuffermanager.h index bc6d86c..490f951 100644 --- a/common/core/framebuffermanager.h +++ b/common/core/framebuffermanager.h @@ -82,6 +82,7 @@ class FrameBufferManager { void RegisterGemHandles(const uint32_t &num_planes, const uint32_t (&igem_handles)[4]); uint32_t FindFB(const uint32_t &iwidth, const uint32_t &iheight, + const uint32_t &modifier, const uint32_t &iframe_buffer_format, const uint32_t &num_planes, const uint32_t (&igem_handles)[4], const uint32_t (&ipitches)[4], const uint32_t (&ioffsets)[4]); diff --git a/os/android/gralloc1bufferhandler.cpp b/os/android/gralloc1bufferhandler.cpp index 9b8addb..c465f7f 100644 --- a/os/android/gralloc1bufferhandler.cpp +++ b/os/android/gralloc1bufferhandler.cpp @@ -102,7 +102,10 @@ bool Gralloc1BufferHandler::Init() { GRALLOC1_FUNCTION_SET_PRODUCER_USAGE)); allocate_ = reinterpret_cast( gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_ALLOCATE)); - +#ifdef USE_GRALLOC1 + set_modifier_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_SET_MODIFIER)); +#endif return true; } @@ -127,6 +130,17 @@ bool Gralloc1BufferHandler::CreateBuffer(uint32_t w, uint32_t h, int format, set_format_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, pixel_format); +#ifdef ENABLE_RBC + // These formats are RBC supported in i915 driver + if ((format == DRM_FORMAT_XRGB8888) || (format == DRM_FORMAT_XBGR8888) || + (format == DRM_FORMAT_ARGB8888) || (format == DRM_FORMAT_ABGR8888)) { +#ifdef USE_GRALLOC1 + uint64_t modifier = I915_FORMAT_MOD_Y_TILED_CCS; + set_modifier_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, modifier); +#endif + } +#endif + if ((layer_type == hwcomposer::kLayerVideo) && !IsSupportedMediaFormat(format)) { ETRACE("Forcing normal usage for Video Layer. \n"); @@ -199,17 +213,15 @@ bool Gralloc1BufferHandler::ImportBuffer(HWCNativeHandle handle) const { gralloc1_device_t *gralloc1_dvc = reinterpret_cast(device_); register_(gralloc1_dvc, handle->imported_handle_); - return ImportGraphicsBuffer(handle, fd_); -} - -uint32_t Gralloc1BufferHandler::GetTotalPlanes(HWCNativeHandle handle) const { - auto gr_handle = (struct cros_gralloc_handle *)handle->imported_handle_; - if (!gr_handle) { - ETRACE("could not find gralloc drm handle"); + if (!ImportGraphicsBuffer(handle, fd_)) { return false; } - return drm_bo_get_num_planes(gr_handle->format); + return true; +} + +uint32_t Gralloc1BufferHandler::GetTotalPlanes(HWCNativeHandle handle) const { + return handle->meta_data_.num_planes_; } void Gralloc1BufferHandler::CopyHandle(HWCNativeHandle source, diff --git a/os/android/gralloc1bufferhandler.h b/os/android/gralloc1bufferhandler.h index fc1e914..91be5bd 100644 --- a/os/android/gralloc1bufferhandler.h +++ b/os/android/gralloc1bufferhandler.h @@ -68,6 +68,9 @@ class Gralloc1BufferHandler : public NativeBufferHandler { GRALLOC1_PFN_SET_FORMAT set_format_; GRALLOC1_PFN_SET_PRODUCER_USAGE set_producer_usage_; GRALLOC1_PFN_ALLOCATE allocate_; +#ifdef USE_GRALLOC1 + GRALLOC1_PFN_SET_MODIFIER set_modifier_; +#endif }; } // namespace hwcomposer diff --git a/os/android/platformdefines.cpp b/os/android/platformdefines.cpp index ca678d9..09b3fb1 100644 --- a/os/android/platformdefines.cpp +++ b/os/android/platformdefines.cpp @@ -99,23 +99,3 @@ int ReleaseFrameBuffer(const FBKey &key, uint32_t fd, uint32_t gpu_fd) { return ret; } - -int CreateFrameBuffer(const uint32_t &iwidth, const uint32_t &iheight, - const uint32_t &iframe_buffer_format, - const uint32_t (&igem_handles)[4], - const uint32_t (&ipitches)[4], - const uint32_t (&ioffsets)[4], uint32_t gpu_fd, - uint32_t *fb_id) { - int ret = drmModeAddFB2(gpu_fd, iwidth, iheight, iframe_buffer_format, - igem_handles, ipitches, ioffsets, fb_id, 0); - - if (ret) { - ETRACE("drmModeAddFB2 error (%dx%d, %c%c%c%c, handle %d pitch %d) (%s)", - iwidth, iheight, iframe_buffer_format, iframe_buffer_format >> 8, - iframe_buffer_format >> 16, iframe_buffer_format >> 24, - igem_handles[0], ipitches[0], strerror(-ret)); - *fb_id = 0; - } - - return ret; -} diff --git a/os/linux/gbmbufferhandler.cpp b/os/linux/gbmbufferhandler.cpp index 54bc18d..51ab17f 100644 --- a/os/linux/gbmbufferhandler.cpp +++ b/os/linux/gbmbufferhandler.cpp @@ -109,11 +109,26 @@ bool GbmBufferHandler::CreateBuffer(uint32_t w, uint32_t h, int format, h = preferred_cursor_height_; } - struct gbm_bo *bo = gbm_bo_create(device_, w, h, gbm_format, flags); + struct gbm_bo *bo = NULL; + + bool rbc_enabled = false; +#ifdef ENABLE_RBC + if (gbm_format == DRM_FORMAT_XRGB8888 || gbm_format == DRM_FORMAT_XBGR8888 || + gbm_format == DRM_FORMAT_ARGB8888 || gbm_format == DRM_FORMAT_ABGR8888) { + uint64_t modifier = I915_FORMAT_MOD_Y_TILED_CCS; + bo = gbm_bo_create_with_modifiers(device_, w, h, gbm_format, &modifier, 1); + rbc_enabled = true; + } else { + bo = gbm_bo_create(device_, w, h, gbm_format, flags); + } +#else + bo = gbm_bo_create(device_, w, h, gbm_format, flags); +#endif if (!bo) { flags &= ~GBM_BO_USE_SCANOUT; bo = gbm_bo_create(device_, w, h, gbm_format, flags); + rbc_enabled = false; } if (!bo) { @@ -138,11 +153,32 @@ bool GbmBufferHandler::CreateBuffer(uint32_t w, uint32_t h, int format, temp->import_data.strides[i] = gbm_bo_get_plane_stride(bo, i); } temp->meta_data_.num_planes_ = total_planes; + if (rbc_enabled) { + temp->modifier = gbm_bo_get_plane_format_modifier(bo, 0); + } #else - temp->import_data.fd = gbm_bo_get_fd(bo); - temp->import_data.stride = gbm_bo_get_stride(bo); - temp->meta_data_.num_planes_ = - drm_bo_get_num_planes(temp->import_data.format); + if (rbc_enabled) { + temp->import_data.fd_modifier_data.width = gbm_bo_get_width(bo); + temp->import_data.fd_modifier_data.height = gbm_bo_get_height(bo); + temp->import_data.fd_modifier_data.format = gbm_bo_get_format(bo); + temp->import_data.fd_modifier_data.num_fds = 1; + temp->import_data.fd_modifier_data.fds[0] = gbm_bo_get_fd(bo); + + for (size_t i = 0; i < temp->total_planes; i++) { + temp->import_data.fd_modifier_data.offsets[i] = gbm_bo_get_offset(bo, i); + temp->import_data.fd_modifier_data.strides[i] = + gbm_bo_get_stride_for_plane(bo, i); + } + + temp->import_data.fd_modifier_data.modifier = gbm_bo_get_modifier(bo); + temp->modifier = temp->import_data.fd_modifier_data.modifier; + } else { + temp->import_data.fd_data.width = gbm_bo_get_width(bo); + temp->import_data.fd_data.height = gbm_bo_get_height(bo); + temp->import_data.fd_data.format = gbm_bo_get_format(bo); + temp->import_data.fd_data.fd = gbm_bo_get_fd(bo); + temp->import_data.fd_data.stride = gbm_bo_get_stride(bo); + } #endif temp->bo = bo; @@ -168,7 +204,12 @@ bool GbmBufferHandler::ReleaseBuffer(HWCNativeHandle handle) const { for (size_t i = 0; i < total_planes; i++) close(handle->import_data.fds[i]); #else - close(handle->import_data.fd); + if (!handle->modifier) { + close(handle->import_data.fd_data.fd); + } else { + for (size_t i = 0; i < handle->import_data.fd_modifier_data.num_fds; i++) + close(handle->import_data.fd_modifier_data.fds[i]); + } #endif } @@ -183,19 +224,56 @@ void GbmBufferHandler::DestroyHandle(HWCNativeHandle handle) const { void GbmBufferHandler::CopyHandle(HWCNativeHandle source, HWCNativeHandle *target) const { struct gbm_handle *temp = new struct gbm_handle(); + +#if USE_MINIGBM temp->import_data.width = source->import_data.width; temp->import_data.height = source->import_data.height; temp->import_data.format = source->import_data.format; -#if USE_MINIGBM + size_t total_planes = source->meta_data_.num_planes_; for (size_t i = 0; i < total_planes; i++) { temp->import_data.fds[i] = dup(source->import_data.fds[i]); temp->import_data.offsets[i] = source->import_data.offsets[i]; temp->import_data.strides[i] = source->import_data.strides[i]; } + + if (source->modifier) { + temp->modifier = source->modifier; + } #else - temp->import_data.fd = dup(source->import_data.fd); - temp->import_data.stride = source->import_data.stride; + if (!source->modifier) { + temp->import_data.fd_data.width = source->import_data.fd_data.width; + temp->import_data.fd_data.height = source->import_data.fd_data.height; + temp->import_data.fd_data.format = source->import_data.fd_data.format; + temp->import_data.fd_data.fd = dup(source->import_data.fd_data.fd); + temp->import_data.fd_data.stride = source->import_data.fd_data.stride; + } else { + temp->import_data.fd_modifier_data.width = + source->import_data.fd_modifier_data.width; + temp->import_data.fd_modifier_data.height = + source->import_data.fd_modifier_data.height; + temp->import_data.fd_modifier_data.format = + source->import_data.fd_modifier_data.format; + temp->total_planes = source->total_planes; + temp->import_data.fd_modifier_data.num_fds = + source->import_data.fd_modifier_data.num_fds; + + for (size_t i = 0; i < temp->import_data.fd_modifier_data.num_fds; i++) { + temp->import_data.fd_modifier_data.fds[i] = + dup(source->import_data.fd_modifier_data.fds[i]); + } + + for (size_t i = 0; i < temp->total_planes; i++) { + temp->import_data.fd_modifier_data.offsets[i] = + source->import_data.fd_modifier_data.offsets[i]; + temp->import_data.fd_modifier_data.strides[i] = + source->import_data.fd_modifier_data.strides[i]; + } + + temp->import_data.fd_modifier_data.modifier = + source->import_data.fd_modifier_data.modifier; + temp->modifier = temp->import_data.fd_modifier_data.modifier; + } #endif temp->bo = source->bo; temp->meta_data_.num_planes_ = source->meta_data_.num_planes_; @@ -207,21 +285,34 @@ void GbmBufferHandler::CopyHandle(HWCNativeHandle source, bool GbmBufferHandler::ImportBuffer(HWCNativeHandle handle) const { memset(&(handle->meta_data_), 0, sizeof(struct HwcBuffer)); uint32_t gem_handle = 0; - handle->meta_data_.format_ = handle->import_data.format; - handle->meta_data_.native_format_ = handle->import_data.format; + HwcBuffer *bo = &(handle->meta_data_); + if (!handle->imported_bo) { #if USE_MINIGBM + bo->format_ = handle->import_data.format; + bo->native_format_ = handle->import_data.format; handle->imported_bo = gbm_bo_import(device_, GBM_BO_IMPORT_FD_PLANAR, &handle->import_data, handle->gbm_flags); - if (!handle->imported_bo) { - ETRACE("can't import bo"); - } + + if (!handle->imported_bo) { + ETRACE("can't import bo"); + } #else - handle->imported_bo = gbm_bo_import( - device_, GBM_BO_IMPORT_FD, &handle->import_data, handle->gbm_flags); + if (!handle->modifier) { + bo->format_ = handle->import_data.fd_data.format; + handle->imported_bo = + gbm_bo_import(device_, GBM_BO_IMPORT_FD, &handle->import_data.fd_data, + handle->gbm_flags); + } else { + bo->format_ = handle->import_data.fd_modifier_data.format; + handle->imported_bo = gbm_bo_import(device_, GBM_BO_IMPORT_FD_MODIFIER, + &handle->import_data.fd_modifier_data, + handle->gbm_flags); + } + if (!handle->imported_bo) { - ETRACE("can't import bo"); + ETRACE("can't import bo"); } #endif } @@ -233,8 +324,18 @@ bool GbmBufferHandler::ImportBuffer(HWCNativeHandle handle) const { return false; } +#if USE_MINIGBM handle->meta_data_.width_ = handle->import_data.width; handle->meta_data_.height_ = handle->import_data.height; +#else + if (!handle->modifier) { + handle->meta_data_.width_ = handle->import_data.fd_data.width; + handle->meta_data_.height_ = handle->import_data.fd_data.height; + } else { + handle->meta_data_.width_ = handle->import_data.fd_modifier_data.width; + handle->meta_data_.height_ = handle->import_data.fd_modifier_data.height; + } +#endif if (handle->layer_type_ == hwcomposer::kLayerCursor) { handle->meta_data_.usage_ = hwcomposer::kLayerCursor; @@ -249,6 +350,12 @@ bool GbmBufferHandler::ImportBuffer(HWCNativeHandle handle) const { #if USE_MINIGBM size_t total_planes = gbm_bo_get_num_planes(handle->bo); handle->meta_data_.num_planes_ = total_planes; + if (!handle->modifier) { + bo->modifier = 0; + } else { + bo->modifier = gbm_bo_get_plane_format_modifier(handle->bo, 0); + } + for (size_t i = 0; i < total_planes; i++) { handle->meta_data_.gem_handles_[i] = gem_handle; handle->meta_data_.offsets_[i] = gbm_bo_get_plane_offset(handle->bo, i); @@ -256,11 +363,22 @@ bool GbmBufferHandler::ImportBuffer(HWCNativeHandle handle) const { handle->meta_data_.prime_fds_[i] = handle->import_data.fds[i]; } #else - handle->meta_data_.prime_fds_[0] = handle->import_data.fd; - handle->meta_data_.num_planes_ = 1; - handle->meta_data_.gem_handles_[0] = gem_handle; - handle->meta_data_.offsets_[0] = 0; - handle->meta_data_.pitches_[0] = gbm_bo_get_stride(handle->bo); + if (!handle->modifier) { + bo->prime_fds_[0] = handle->import_data.fd_data.fd; + bo->modifier = 0; + } else { + bo->prime_fds_[0] = handle->import_data.fd_modifier_data.fds[0]; + bo->modifier = gbm_bo_get_modifier(handle->bo); + } + + size_t total_planes = gbm_bo_get_plane_count(handle->imported_bo); + bo->num_planes_ = total_planes; + for (size_t i = 0; i < total_planes; i++) { + bo->gem_handles_[i] = + gbm_bo_get_handle_for_plane(handle->imported_bo, i).u32; + bo->offsets_[i] = handle->import_data.fd_modifier_data.offsets[i]; + bo->pitches_[i] = gbm_bo_get_stride_for_plane(handle->bo, i); + } #endif return true; diff --git a/os/linux/platformdefines.cpp b/os/linux/platformdefines.cpp index 7d613b6..682daed 100644 --- a/os/linux/platformdefines.cpp +++ b/os/linux/platformdefines.cpp @@ -70,23 +70,3 @@ VkFormat NativeToVkFormat(int native_format) { int ReleaseFrameBuffer(const FBKey & /*key*/, uint32_t fd, uint32_t gpu_fd) { return fd > 0 ? drmModeRmFB(gpu_fd, fd) : 0; } - -int CreateFrameBuffer(const uint32_t &iwidth, const uint32_t &iheight, - const uint32_t &iframe_buffer_format, - const uint32_t (&igem_handles)[4], - const uint32_t (&ipitches)[4], - const uint32_t (&ioffsets)[4], uint32_t gpu_fd, - uint32_t *fb_id) { - int ret = drmModeAddFB2(gpu_fd, iwidth, iheight, iframe_buffer_format, - igem_handles, ipitches, ioffsets, fb_id, 0); - - if (ret) { - ETRACE("drmModeAddFB2 error (%dx%d, %c%c%c%c, handle %d pitch %d) (%s)", - iwidth, iheight, iframe_buffer_format, iframe_buffer_format >> 8, - iframe_buffer_format >> 16, iframe_buffer_format >> 24, - igem_handles[0], ipitches[0], strerror(-ret)); - *fb_id = 0; - } - - return ret; -} diff --git a/os/linux/platformdefines.h b/os/linux/platformdefines.h index 0257c47..06a7675 100644 --- a/os/linux/platformdefines.h +++ b/os/linux/platformdefines.h @@ -36,7 +36,12 @@ struct gbm_handle { #ifdef USE_MINIGBM struct gbm_import_fd_planar_data import_data; #else - struct gbm_import_fd_data import_data; + union { + // for GBM_BO_IMPORT_FD + struct gbm_import_fd_data fd_data; + // for GBM_BO_IMPORT_FD_MODIFIER + struct gbm_import_fd_modifier_data fd_modifier_data; + } import_data; #endif struct gbm_bo* bo = NULL; struct gbm_bo* imported_bo = NULL; @@ -49,6 +54,7 @@ struct gbm_handle { void* pixel_memory_ = NULL; uint32_t gbm_flags = 0; uint32_t layer_type_ = hwcomposer::kLayerNormal; + uint64_t modifier = 0; }; typedef struct gbm_handle* HWCNativeHandle; diff --git a/os/platformcommondefines.h b/os/platformcommondefines.h index 0f229f5..e2d7592 100644 --- a/os/platformcommondefines.h +++ b/os/platformcommondefines.h @@ -53,6 +53,7 @@ typedef struct FBKey { } FBKey; int CreateFrameBuffer(const uint32_t &iwidth, const uint32_t &iheight, + const uint32_t &modifier, const uint32_t &iframe_buffer_format, const uint32_t (&igem_handles)[4], const uint32_t (&ipitches)[4], diff --git a/os/platformcommondrmdefines.cpp b/os/platformcommondrmdefines.cpp new file mode 100644 index 0000000..cb3ad65 --- /dev/null +++ b/os/platformcommondrmdefines.cpp @@ -0,0 +1,51 @@ +/* +// Copyright (c) 2018 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +#include "platformdefines.h" + +#include + +int CreateFrameBuffer(const uint32_t &iwidth, const uint32_t &iheight, + const uint32_t &modifier, + const uint32_t &iframe_buffer_format, + const uint32_t (&igem_handles)[4], + const uint32_t (&ipitches)[4], + const uint32_t (&ioffsets)[4], uint32_t gpu_fd, + uint32_t *fb_id) { + int ret = 0; + if (modifier > 0) { + uint64_t modifiers[4]; + modifiers[1] = modifiers[0] = modifier; + modifiers[2] = modifiers[3] = DRM_FORMAT_MOD_NONE; + ret = drmModeAddFB2WithModifiers( + gpu_fd, iwidth, iheight, iframe_buffer_format, igem_handles, ipitches, + ioffsets, modifiers, fb_id, DRM_MODE_FB_MODIFIERS); + } else { + ret = drmModeAddFB2(gpu_fd, iwidth, iheight, iframe_buffer_format, + igem_handles, ipitches, ioffsets, fb_id, 0); + } + + if (ret) { + ETRACE("%s error (%dx%d, %c%c%c%c, handle %d pitch %d) (%s)", + (modifier == 0) ? "drmModeAddFB2" : "drmModeAddFB2WithModifiers", + iwidth, iheight, iframe_buffer_format, iframe_buffer_format >> 8, + iframe_buffer_format >> 16, iframe_buffer_format >> 24, + igem_handles[0], ipitches[0], strerror(-ret)); + *fb_id = 0; + } + + return ret; +} diff --git a/public/hwcbuffer.h b/public/hwcbuffer.h index c4c1c32..88bb2eb 100644 --- a/public/hwcbuffer.h +++ b/public/hwcbuffer.h @@ -37,6 +37,7 @@ struct HwcBuffer { uint32_t gem_handles_[4]; int prime_fds_[4]; uint32_t num_planes_ = 0; + uint64_t modifier_ = 0; hwcomposer::HWCLayerType usage_ = hwcomposer::kLayerNormal; }; diff --git a/tests/common/gllayerrenderer.cpp b/tests/common/gllayerrenderer.cpp index 206cc43..b9fc40b 100644 --- a/tests/common/gllayerrenderer.cpp +++ b/tests/common/gllayerrenderer.cpp @@ -81,19 +81,57 @@ bool GLLayerRenderer::Init(uint32_t width, uint32_t height, uint32_t format, eglMakeCurrent(gl_->display, EGL_NO_SURFACE, EGL_NO_SURFACE, gl_->context); - const EGLint image_attrs[] = { - EGL_WIDTH, (EGLint)width, - EGL_HEIGHT, (EGLint)height, - EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_XRGB8888, - EGL_DMA_BUF_PLANE0_FD_EXT, (EGLint)fd_, - EGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)stride_, - EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, - EGL_NONE, - }; + if (!handle_->meta_data_.modifier) { + const EGLint image_attrs[] = { + EGL_WIDTH, (EGLint)width, + EGL_HEIGHT, (EGLint)height, + EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_XRGB8888, + EGL_DMA_BUF_PLANE0_FD_EXT, (EGLint)fd_, + EGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)stride_, + EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, + EGL_NONE, + }; + egl_image_ = gl_->eglCreateImageKHR(gl_->display, EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, + (EGLClientBuffer)NULL, image_attrs); + } else { + uint64_t modifier = handle_->meta_data_.modifier; + EGLint modifier_low = (EGLint)modifier; + EGLint modifier_high = (EGLint)(modifier >> 32); + const EGLint image_attrs[] = { + EGL_WIDTH, + (EGLint)width, + EGL_HEIGHT, + (EGLint)height, + EGL_LINUX_DRM_FOURCC_EXT, + DRM_FORMAT_XRGB8888, + EGL_DMA_BUF_PLANE0_FD_EXT, + (EGLint)fd_, + EGL_DMA_BUF_PLANE0_PITCH_EXT, + (EGLint)handle_->meta_data_.pitches_[0], + EGL_DMA_BUF_PLANE0_OFFSET_EXT, + (EGLint)handle_->meta_data_.offsets_[0], + EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, + modifier_low, + EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, + modifier_high, + EGL_DMA_BUF_PLANE1_FD_EXT, + (EGLint)fd_, + EGL_DMA_BUF_PLANE1_PITCH_EXT, + (EGLint)handle_->meta_data_.pitches_[1], + EGL_DMA_BUF_PLANE1_OFFSET_EXT, + (EGLint)handle_->meta_data_.offsets_[1], + EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, + modifier_low, + EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT, + modifier_high, + EGL_NONE, + }; + egl_image_ = gl_->eglCreateImageKHR(gl_->display, EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, + (EGLClientBuffer)NULL, image_attrs); + } - egl_image_ = gl_->eglCreateImageKHR(gl_->display, EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, - (EGLClientBuffer)NULL, image_attrs); if (!egl_image_) { printf("failed to create EGLImage from gbm_bo\n"); return false; diff --git a/wsi/drm/drmbuffer.cpp b/wsi/drm/drmbuffer.cpp index 24bb5c5..58b0a49 100644 --- a/wsi/drm/drmbuffer.cpp +++ b/wsi/drm/drmbuffer.cpp @@ -32,6 +32,22 @@ #include +#ifndef EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT +#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 +#endif + +#ifndef EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT +#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 +#endif + +#ifndef EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT +#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 +#endif + +#ifndef EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT +#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 +#endif + namespace hwcomposer { DrmBuffer::~DrmBuffer() { @@ -160,6 +176,43 @@ const ResourceHandle& DrmBuffer::GetGpuResource(GpuDisplay egl_display, egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, static_cast(nullptr), attr_list_yv12); } + } else if (modifier_ && total_planes == 2) { + uint64_t modifier = modifier_; + EGLint modifier_low = static_cast(modifier); + EGLint modifier_high = static_cast(modifier >> 32); + const EGLint image_attrs[] = { + EGL_WIDTH, + static_cast(width_), + EGL_HEIGHT, + static_cast(height_), + EGL_LINUX_DRM_FOURCC_EXT, + static_cast(format_), + EGL_DMA_BUF_PLANE0_FD_EXT, + static_cast(image_.handle_->meta_data_.prime_fds_[0]), + EGL_DMA_BUF_PLANE0_PITCH_EXT, + static_cast(pitches_[0]), + EGL_DMA_BUF_PLANE0_OFFSET_EXT, + static_cast(offsets_[0]), + EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, + modifier_low, + EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, + modifier_high, + EGL_DMA_BUF_PLANE1_FD_EXT, + static_cast(image_.handle_->meta_data_.prime_fds_[1]), + EGL_DMA_BUF_PLANE1_PITCH_EXT, + static_cast(pitches_[1]), + EGL_DMA_BUF_PLANE1_OFFSET_EXT, + static_cast(offsets_[1]), + EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, + modifier_low, + EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT, + modifier_high, + EGL_NONE, + }; + + image = + eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, + static_cast(nullptr), image_attrs); } else { const EGLint attr_list[] = { EGL_WIDTH, @@ -326,7 +379,7 @@ bool DrmBuffer::CreateFrameBuffer() { media_image_.drm_fd_ = 0; image_.drm_fd_ = FrameBufferManager::GetInstance()->FindFB( - width_, height_, frame_buffer_format_, + width_, height_, modifier_, frame_buffer_format_, image_.handle_->meta_data_.num_planes_, gem_handles_, pitches_, offsets_); media_image_.drm_fd_ = image_.drm_fd_; return true; diff --git a/wsi/drm/drmbuffer.h b/wsi/drm/drmbuffer.h index e0e81f1..c2beced 100644 --- a/wsi/drm/drmbuffer.h +++ b/wsi/drm/drmbuffer.h @@ -98,6 +98,7 @@ class DrmBuffer : public OverlayBuffer { HWCLayerType usage_ = kLayerNormal; uint32_t previous_width_ = 0; // For Media usage. uint32_t previous_height_ = 0; // For Media usage. + uint64_t modifier_ = 0; ResourceManager* resource_manager_ = 0; ResourceHandle image_; MediaResourceHandle media_image_; -- 2.11.0