From f50f5e21df43f6a96095c0598bd26ba0ee200c92 Mon Sep 17 00:00:00 2001 From: bozhengx Date: Wed, 25 Dec 2019 16:28:08 +0800 Subject: [PATCH 1/2] add libva support Signed-off-by: bozhengx --- Android.bp | 112 ------- Android.mk | 100 ++++++ drmdisplaycompositor.cpp | 28 +- drmhwcomposer.h | 35 ++- drmhwctwo.cpp | 126 ++++++-- drmhwctwo.h | 6 +- gralloc1bufferhandler.cpp | 337 +++++++++++++++++++++ gralloc1bufferhandler.h | 82 +++++ hwcutils.cpp | 7 +- nativebufferhandler.h | 64 ++++ platform.h | 3 +- platformdrmgeneric.cpp | 5 +- platformdrmgeneric.h | 2 +- platformminigbm.cpp | 110 ++++++- platformminigbm.h | 7 +- tests/Android.bp | 13 - tests/worker_test.cpp | 110 ------- varenderer.cpp | 621 ++++++++++++++++++++++++++++++++++++++ varenderer.h | 235 +++++++++++++++ vautils.cpp | 303 +++++++++++++++++++ vautils.h | 43 +++ 21 files changed, 2056 insertions(+), 293 deletions(-) delete mode 100644 Android.bp create mode 100755 Android.mk mode change 100644 => 100755 drmdisplaycompositor.cpp mode change 100644 => 100755 drmhwcomposer.h mode change 100644 => 100755 drmhwctwo.cpp mode change 100644 => 100755 drmhwctwo.h create mode 100755 gralloc1bufferhandler.cpp create mode 100755 gralloc1bufferhandler.h mode change 100644 => 100755 hwcutils.cpp create mode 100755 nativebufferhandler.h mode change 100644 => 100755 platform.h mode change 100644 => 100755 platformdrmgeneric.cpp mode change 100644 => 100755 platformdrmgeneric.h mode change 100644 => 100755 platformminigbm.cpp mode change 100644 => 100755 platformminigbm.h delete mode 100644 tests/Android.bp delete mode 100644 tests/worker_test.cpp create mode 100755 varenderer.cpp create mode 100755 varenderer.h create mode 100755 vautils.cpp create mode 100755 vautils.h diff --git a/Android.bp b/Android.bp deleted file mode 100644 index 2af4548f0..000000000 --- a/Android.bp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2015 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// ===================== -// libdrmhwc_utils.a -// ===================== -cc_library_static { - name: "libdrmhwc_utils", - - srcs: ["worker.cpp"], - - cflags: [ - "-Wall", - "-Werror", - ], - - vendor: true, - -} - -// ===================== -// hwcomposer.drm.so -// ===================== -cc_defaults { - name: "hwcomposer.drm_defaults", - - shared_libs: [ - "libcutils", - "libdrm", - "libhardware", - "liblog", - "libsync", - "libui", - "libutils", - ], - - static_libs: ["libdrmhwc_utils"], - - cflags: [ - "-Wall", - "-Werror", - ], - - cppflags: [ - "-DHWC2_USE_CPP11", - "-DHWC2_INCLUDE_STRINGIFICATION", - ], - - relative_install_path: "hw", - vendor: true, -} -cc_library_static { - name: "drm_hwcomposer", - defaults: ["hwcomposer.drm_defaults"], - srcs: [ - "autolock.cpp", - "resourcemanager.cpp", - "drmdevice.cpp", - "drmconnector.cpp", - "drmcrtc.cpp", - "drmdisplaycomposition.cpp", - "drmdisplaycompositor.cpp", - "drmencoder.cpp", - "drmeventlistener.cpp", - "drmhwctwo.cpp", - "drmmode.cpp", - "drmplane.cpp", - "drmproperty.cpp", - "hwcutils.cpp", - "platform.cpp", - "vsyncworker.cpp", - ], -} - -cc_library_shared { - name: "hwcomposer.drm", - defaults: ["hwcomposer.drm_defaults"], - whole_static_libs: ["drm_hwcomposer"], - srcs: ["platformdrmgeneric.cpp"], - cppflags: ["-DUSE_DRM_GENERIC_IMPORTER"], -} - -cc_library_shared { - name: "hwcomposer.drm_minigbm", - defaults: ["hwcomposer.drm_defaults"], - whole_static_libs: ["drm_hwcomposer"], - srcs: [ - "platformdrmgeneric.cpp", - "platformminigbm.cpp", - ], - include_dirs: ["external/minigbm/cros_gralloc"], -} - -// Used by hwcomposer.drm_hikey and hwcomposer.drm_hikey960 -filegroup { - name: "drm_hwcomposer_platformhisi", - srcs: [ - "platformdrmgeneric.cpp", - "platformhisi.cpp", - ], -} diff --git a/Android.mk b/Android.mk new file mode 100755 index 000000000..ea39bae10 --- /dev/null +++ b/Android.mk @@ -0,0 +1,100 @@ +# Copyright (c) 2017 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. + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libdrm_pri \ + libhardware \ + liblog \ + libsync \ + libui \ + libutils \ + libva \ + libva-android + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + system/core/include/utils \ + system/core/libcutils/include \ + external/minigbm/cros_gralloc \ + hardware/intel/external/libva \ + hardware/intel/external/drm-intel/android + #external/libdrm/android + +LOCAL_SRC_FILES := \ + drmhwctwo.cpp \ + drmdisplaycomposition.cpp \ + drmdisplaycompositor.cpp \ + drmconnector.cpp \ + drmcrtc.cpp \ + drmdevice.cpp \ + drmencoder.cpp \ + drmeventlistener.cpp \ + drmmode.cpp \ + drmplane.cpp \ + drmproperty.cpp \ + resourcemanager.cpp \ + vsyncworker.cpp \ + platform.cpp \ + autolock.cpp \ + hwcutils.cpp \ + worker.cpp \ + platformdrmgeneric.cpp \ + platformminigbm.cpp \ + varenderer.cpp \ + vautils.cpp \ + gralloc1bufferhandler.cpp + + + +LOCAL_C_INCLUDES += \ + system/core/libsync \ + system/core/libsync/include + + +LOCAL_CPPFLAGS += -DENABLE_DOUBLE_BUFFERING +LOCAL_CPPFLAGS += -DUSE_GRALLOC1 +LOCAL_CPPFLAGS += -DMODIFICATOR_WA +LOCAL_CPPFLAGS += -DENABLE_RBC + +LOCAL_CPPFLAGS += \ + -DHWC2_INCLUDE_STRINGIFICATION \ + -DHWC2_USE_CPP11 \ + -Wno-date-time \ + -DUSE_ANDROID_SHIM \ + -D_FORTIFY_SOURCE=2 \ + -fstack-protector-strong \ + -Wformat -Wformat-security \ + -std=c++14 -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 \ + -Wall -Wsign-compare -Wpointer-arith \ + -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 \ + -Wno-unused-parameter \ + -O3 \ + -Werror + + + + + +LOCAL_CPPFLAGS += -DENABLE_ANDROID_WA -DVA_SUPPORT_COLOR_RANGE +#LOCAL_CPPFLAGS += -DENABLE_DUMP_YUV_DATA +LOCAL_VENDOR_MODULE := true +LOCAL_MODULE := hwcomposer.drm_minigbm +LOCAL_CFLAGS += -fvisibility=default +LOCAL_PROPRIETARY_MODULE := true +include $(BUILD_SHARED_LIBRARY) diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp old mode 100644 new mode 100755 index e6f6922d3..0e9bf1710 --- a/drmdisplaycompositor.cpp +++ b/drmdisplaycompositor.cpp @@ -381,15 +381,27 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, rotation |= DRM_MODE_REFLECT_X; if (layer.transform & DrmHwcTransform::kFlipV) rotation |= DRM_MODE_REFLECT_Y; - if (layer.transform & DrmHwcTransform::kRotate90) - rotation |= DRM_MODE_ROTATE_90; - else if (layer.transform & DrmHwcTransform::kRotate180) - rotation |= DRM_MODE_ROTATE_180; - else if (layer.transform & DrmHwcTransform::kRotate270) - rotation |= DRM_MODE_ROTATE_270; - else + if (layer.IsVideoLayer()) { rotation |= DRM_MODE_ROTATE_0; - + source_crop.left = 0; + source_crop.top = 0; + source_crop.bottom = 1080; + source_crop.right = 1920; + + display_frame.left = 0; + display_frame.top = 0; + display_frame.bottom = 1080; + display_frame.right = 1920; + }else{ + if (layer.transform & DrmHwcTransform::kRotate90) + rotation |= DRM_MODE_ROTATE_90; + else if (layer.transform & DrmHwcTransform::kRotate180) + rotation |= DRM_MODE_ROTATE_180; + else if (layer.transform & DrmHwcTransform::kRotate270) + rotation |= DRM_MODE_ROTATE_270; + else + rotation |= DRM_MODE_ROTATE_0; + } if (fence_fd >= 0) { int prop_id = plane->in_fence_fd_property().id(); if (prop_id == 0) { diff --git a/drmhwcomposer.h b/drmhwcomposer.h old mode 100644 new mode 100755 index 2af7e6e61..db6a2ef6d --- a/drmhwcomposer.h +++ b/drmhwcomposer.h @@ -26,6 +26,8 @@ #include #include "autofd.h" #include "drmhwcgralloc.h" +#include +#include struct hwc_import_context; @@ -41,6 +43,8 @@ namespace android { class Importer; +struct DrmHwcLayer; + class DrmHwcBuffer { public: DrmHwcBuffer() = default; @@ -71,7 +75,7 @@ class DrmHwcBuffer { void Clear(); - int ImportBuffer(buffer_handle_t handle, Importer *importer); + int ImportBuffer(DrmHwcLayer* layer, Importer *importer); private: hwc_drm_bo bo_; @@ -121,6 +125,14 @@ enum DrmHwcTransform { kRotate270 = 1 << 4, }; +enum DrmHwcLayerType { + kLayerNormal = 0, + kLayerCursor = 1, + kLayerProtected = 2, + kLayerVideo = 3, + kLayerSolidColor = 4, +}; + enum class DrmHwcBlending : int32_t { kNone = HWC_BLENDING_NONE, kPreMult = HWC_BLENDING_PREMULT, @@ -129,6 +141,7 @@ enum class DrmHwcBlending : int32_t { struct DrmHwcLayer { buffer_handle_t sf_handle = NULL; + std::map> va_z_map; int gralloc_buffer_usage = 0; DrmHwcBuffer buffer; DrmHwcNativeHandle handle; @@ -137,10 +150,17 @@ struct DrmHwcLayer { uint16_t alpha = 0xffff; hwc_frect_t source_crop; hwc_rect_t display_frame; + DrmHwcLayerType type_ = kLayerNormal; + android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN; UniqueFd acquire_fence; OutputFd release_fence; - + void addVaLayerMapData(int zorder, DrmHwcLayer* layer){ + va_z_map.emplace(std::make_pair(zorder, layer)); + } + std::map> getVaLayerMapData(){ + return va_z_map; + } int ImportBuffer(Importer *importer); int InitFromDrmHwcLayer(DrmHwcLayer *layer, Importer *importer); @@ -148,6 +168,17 @@ struct DrmHwcLayer { void SetSourceCrop(hwc_frect_t const &crop); void SetDisplayFrame(hwc_rect_t const &frame); + void SetVideoLayer(bool isVideo) { + if (isVideo) + type_ = kLayerVideo; + else + type_ = kLayerNormal; + } + + bool IsVideoLayer() const { + return type_ == kLayerVideo; + } + buffer_handle_t get_usable_handle() const { return handle.get() != NULL ? handle.get() : sf_handle; } diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp old mode 100644 new mode 100755 index 3123b298d..6292dfc0d --- a/drmhwctwo.cpp +++ b/drmhwctwo.cpp @@ -30,6 +30,8 @@ #include #include #include +#include "cros_gralloc_handle.h" +#include "vautils.h" namespace android { @@ -502,14 +504,14 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) { std::vector layers_map; layers_map.emplace_back(); DrmCompositionDisplayLayersMap &map = layers_map.back(); - + int ret = 0; map.display = static_cast(handle_); map.geometry_changed = true; // TODO: Fix this - // order the layers by z-order bool use_client_layer = false; uint32_t client_z_order = UINT32_MAX; std::map z_map; + bool includeVideoFlag = false; for (std::pair &l : layers_) { HWC2::Composition comp_type; if (test) { @@ -520,7 +522,8 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) { } } else comp_type = l.second.validated_type(); - + if (l.second.IsVideoLayer()) + includeVideoFlag= true; switch (comp_type) { case HWC2::Composition::Device: z_map.emplace(std::make_pair(l.second.z_order(), &l.second)); @@ -531,6 +534,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) { client_z_order = std::min(client_z_order, l.second.z_order()); break; default: + z_map.emplace(std::make_pair(l.second.z_order(), &l.second)); continue; } } @@ -541,28 +545,52 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) { return HWC2::Error::BadLayer; // now that they're ordered by z, add them to the composition - for (std::pair &l : z_map) { - DrmHwcLayer layer; - l.second->PopulateDrmLayer(&layer); - int ret = layer.ImportBuffer(importer_.get()); - if (ret) { - ALOGE("Failed to import layer, ret=%d", ret); - return HWC2::Error::NoResources; + if(includeVideoFlag && (!use_client_layer)){ + for (std::pair &l : z_map) { + if (l.second->IsVideoLayer()) { + DrmHwcLayer layer; + DrmHwcLayer layera[z_map.size()]; + l.second->PopulateDrmLayer(&layer); + int index =0; + for (std::pair &a : z_map) { + a.second->PopulateDrmLayer(&layera[index]); + layer.addVaLayerMapData(a.first, &layera[index]); + index++; + } + ret = layer.ImportBuffer(importer_.get()); + map.layers.emplace_back(std::move(layer)); + break; + } + } + }else{ + for (std::pair &l : z_map) { + DrmHwcLayer layer; + l.second->PopulateDrmLayer(&layer); + int ret = layer.ImportBuffer(importer_.get()); + if (ret) { + ALOGE("Failed to import layer, ret=%d", ret); + return HWC2::Error::NoResources; + // continue; + } + if (test && includeVideoFlag) { + if (l.second->IsVideoLayer()) { + map.layers.emplace_back(std::move(layer)); + break; + } + }else + map.layers.emplace_back(std::move(layer)); } - map.layers.emplace_back(std::move(layer)); } - std::unique_ptr composition = compositor_ .CreateComposition(); composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); // TODO: Don't always assume geometry changed - int ret = composition->SetLayers(map.layers.data(), map.layers.size(), true); + ret = composition->SetLayers(map.layers.data(), map.layers.size(), true); if (ret) { ALOGE("Failed to set layers in the composition ret=%d", ret); return HWC2::Error::BadLayer; } - std::vector primary_planes(primary_planes_); std::vector overlay_planes(overlay_planes_); ret = composition->Plan(&primary_planes, &overlay_planes); @@ -727,6 +755,21 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) { return HWC2::Error::None; } +//check whether the layer with the lease two zorder is the video layer +bool DrmHwcTwo::HwcDisplay::ContainVideoLayer(std::map< uint32_t, + DrmHwcTwo::HwcLayer *, + std::greater> zmap) { + int i = 0; + if (zmap.empty()) + return false; + for (std::map::reverse_iterator rit = zmap.rbegin(); rit != zmap.rend() && i < 2; rit++, i++) { + if (rit->second->IsVideoLayer()) + return true; + } + return false; +} + + HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types, uint32_t *num_requests) { supported(__func__); @@ -734,9 +777,8 @@ HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types, *num_requests = 0; size_t avail_planes = primary_planes_.size() + overlay_planes_.size(); bool comp_failed = false; - + bool video_flag = false; HWC2::Error ret; - for (std::pair &l : layers_) l.second.set_validated_type(HWC2::Composition::Invalid); @@ -746,31 +788,50 @@ HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types, std::map> z_map; for (std::pair &l : layers_) { - if (l.second.sf_type() == HWC2::Composition::Device) - z_map.emplace(std::make_pair(l.second.z_order(), &l.second)); + //if enable the condition, it would filter the sprite layer + //if (l.second.sf_type() == HWC2::Composition::Device){ + z_map.emplace(std::make_pair(l.second.z_order(), &l.second)); + //} } - + video_flag = ContainVideoLayer(z_map); /* * If more layers then planes, save one plane * for client composited layers */ if (avail_planes < layers_.size()) avail_planes--; - - for (std::pair &l : z_map) { - if (comp_failed || !avail_planes--) - break; - if (importer_->CanImportBuffer(l.second->buffer())) - l.second->set_validated_type(HWC2::Composition::Device); + if (video_flag) { + for (std::map::reverse_iterator rit = z_map.rbegin(); rit != z_map.rend(); rit++) { + //if (comp_failed || !avail_planes--) + if (comp_failed ) + break; + //if the layers include video,set all the layers Device mode + if (importer_->CanImportBuffer(rit->second->buffer())) + rit->second->set_validated_type(HWC2::Composition::Device); + } + } else { + for (std::pair &l : z_map) { + if (comp_failed || !avail_planes--) + break; + if (importer_->CanImportBuffer(l.second->buffer())){ + l.second->set_validated_type(HWC2::Composition::Device); + } + } } - for (std::pair &l : layers_) { DrmHwcTwo::HwcLayer &layer = l.second; // We can only handle layers of Device type, send everything else to SF - if (layer.sf_type() != HWC2::Composition::Device || + if (video_flag) { + if (layer.validated_type() != HWC2::Composition::Device) { + layer.set_validated_type(HWC2::Composition::Client); + ++*num_types; + } + } else { + if (layer.sf_type() != HWC2::Composition::Device || layer.validated_type() != HWC2::Composition::Device) { - layer.set_validated_type(HWC2::Composition::Client); - ++*num_types; + layer.set_validated_type(HWC2::Composition::Client); + ++*num_types; + } } } return *num_types ? HWC2::Error::HasChanges : HWC2::Error::None; @@ -802,6 +863,11 @@ HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer, set_buffer(buffer); set_acquire_fence(uf.get()); + if (NULL != buffer) { + cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)(buffer); + if ((NULL != gr_handle) && (IsSupportedMediaFormat(gr_handle->format))) + layer_type_ = kLayerVideo; + } return HWC2::Error::None; } @@ -893,12 +959,14 @@ void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) { OutputFd release_fence = release_fence_output(); layer->sf_handle = buffer_; + layer->dataspace = dataspace_; layer->acquire_fence = acquire_fence_.Release(); layer->release_fence = std::move(release_fence); layer->SetDisplayFrame(display_frame_); layer->alpha = static_cast(65535.0f * alpha_ + 0.5f); layer->SetSourceCrop(source_crop_); layer->SetTransform(static_cast(transform_)); + layer->SetVideoLayer(IsVideoLayer()); } void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) { diff --git a/drmhwctwo.h b/drmhwctwo.h old mode 100644 new mode 100755 index a71d7cc69..a1fc91f93 --- a/drmhwctwo.h +++ b/drmhwctwo.h @@ -64,7 +64,9 @@ class DrmHwcTwo : public hwc2_device_t { void set_buffer(buffer_handle_t buffer) { buffer_ = buffer; } - + bool IsVideoLayer() const { + return layer_type_ == kLayerVideo; + } int take_acquire_fence() { return acquire_fence_.Release(); } @@ -123,6 +125,7 @@ class DrmHwcTwo : public hwc2_device_t { HWC2::Transform transform_ = HWC2::Transform::None; uint32_t z_order_ = 0; android_dataspace_t dataspace_ = HAL_DATASPACE_UNKNOWN; + DrmHwcLayerType layer_type_ = kLayerNormal; }; struct HwcCallback { @@ -183,6 +186,7 @@ class DrmHwcTwo : public hwc2_device_t { HWC2::Error SetPowerMode(int32_t mode); HWC2::Error SetVsyncEnabled(int32_t enabled); HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests); + bool ContainVideoLayer(std::map< uint32_t, DrmHwcTwo::HwcLayer *, std::greater> zmap); HwcLayer &get_layer(hwc2_layer_t layer) { return layers_.at(layer); } diff --git a/gralloc1bufferhandler.cpp b/gralloc1bufferhandler.cpp new file mode 100755 index 000000000..5c8175ff1 --- /dev/null +++ b/gralloc1bufferhandler.cpp @@ -0,0 +1,337 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gralloc1bufferhandler.h" + +#include +#include +#include +#include +#include "vautils.h" +#include +#include "cros_gralloc_handle.h" +#include "drm_fourcc.h" + + +namespace android { + +// static +NativeBufferHandler *NativeBufferHandler::CreateInstance(uint32_t fd) { + Gralloc1BufferHandler *handler = new Gralloc1BufferHandler(fd); + if (!handler) + return NULL; + + if (!handler->Init()) { + ALOGE("Failed to initialize GralocBufferHandlers."); + delete handler; + return NULL; + } + return handler; +} + +Gralloc1BufferHandler::Gralloc1BufferHandler(uint32_t fd) + : fd_(fd), + gralloc_(nullptr), + device_(nullptr), + register_(nullptr), + release_(nullptr), + dimensions_(nullptr), + lock_(nullptr), + unlock_(nullptr), + create_descriptor_(nullptr), + destroy_descriptor_(nullptr), + set_consumer_usage_(nullptr), + set_dimensions_(nullptr), + set_format_(nullptr), + set_producer_usage_(nullptr), + allocate_(nullptr){ +} + +Gralloc1BufferHandler::~Gralloc1BufferHandler() { + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + gralloc1_dvc->common.close(device_); +} + +bool Gralloc1BufferHandler::Init() { + int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, + (const hw_module_t **)&gralloc_); + if (ret) { + ALOGE("Failed to get gralloc module"); + return false; + } + + ret = gralloc_->methods->open(gralloc_, GRALLOC_HARDWARE_MODULE_ID, &device_); + if (ret) { + ALOGE("Failed to open gralloc module"); + return false; + } + + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + register_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_RETAIN)); + release_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_RELEASE)); + lock_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_LOCK)); + unlock_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_UNLOCK)); + + dimensions_ = + reinterpret_cast(gralloc1_dvc->getFunction( + gralloc1_dvc, GRALLOC1_FUNCTION_GET_DIMENSIONS)); + + create_descriptor_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, + GRALLOC1_FUNCTION_CREATE_DESCRIPTOR)); + destroy_descriptor_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, + GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR)); + + set_consumer_usage_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, + GRALLOC1_FUNCTION_SET_CONSUMER_USAGE)); + set_dimensions_ = + reinterpret_cast(gralloc1_dvc->getFunction( + gralloc1_dvc, GRALLOC1_FUNCTION_SET_DIMENSIONS)); + set_format_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_SET_FORMAT)); + set_producer_usage_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, + 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; +} + +bool Gralloc1BufferHandler::CreateBuffer(uint32_t w, uint32_t h, int format, + DRMHwcNativeHandle *handle, + uint32_t layer_type, + bool *modifier_used, + int64_t preferred_modifier, + bool /*raw_pixel_buffer*/) const { + struct gralloc_handle *temp = new struct gralloc_handle(); + (void)preferred_modifier; + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + uint32_t usage = 0; + uint32_t pixel_format = 0; + bool force_normal_usage = false; + + create_descriptor_(gralloc1_dvc, &temp->gralloc1_buffer_descriptor_t_); + ALOGE("in Gralloc1BufferHandler.cpp %s,line %d \n",__FUNCTION__,__LINE__); + if (format != 0) { + ALOGE("in Gralloc1BufferHandler.cpp %s,line %d \n",__FUNCTION__,__LINE__); + pixel_format = DrmFormatToHALFormat(format); + } + ALOGE("in Gralloc1BufferHandler.cpp %s,line %d \n",__FUNCTION__,__LINE__); + if (pixel_format == 0) { + ALOGE("in Gralloc1BufferHandler.cpp %s,line %d \n",__FUNCTION__,__LINE__); + pixel_format = HAL_PIXEL_FORMAT_RGBA_8888; + } + set_format_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, pixel_format); +#ifdef ENABLE_RBC + if (preferred_modifier != 0) { + uint64_t modifier = 0; + if (set_modifier_) { + if (preferred_modifier != -1) { + modifier = preferred_modifier; + } + set_modifier_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, + modifier); + } + if (modifier_used && modifier != DRM_FORMAT_MOD_NONE) { + *modifier_used = true; + } + } else { + *modifier_used = false; + } +#else + if (modifier_used) { + *modifier_used = false; + } +#endif + if (layer_type == 3){ +// !IsSupportedMediaFormat(format)) { + ALOGE("Forcing normal usage for Video Layer. \n"); + force_normal_usage = true; + } + + if ((layer_type == 0) || force_normal_usage) { + ALOGE("in Gralloc1BufferHandler.cpp %s,line %d \n",__FUNCTION__,__LINE__); + usage |= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER | + GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET | + GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE; + layer_type = 0; + } else if (layer_type == 3 || + layer_type == 2) { + switch (pixel_format) { + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case HAL_PIXEL_FORMAT_Y8: + ALOGE("in Gralloc1BufferHandler.cpp %s,line %d \n",__FUNCTION__,__LINE__); + usage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE | + GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER; + break; + default: + ALOGE("in Gralloc1BufferHandler.cpp %s,line %d \n",__FUNCTION__,__LINE__); + usage |= GRALLOC1_PRODUCER_USAGE_CAMERA | + GRALLOC1_CONSUMER_USAGE_CAMERA | + GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER | + GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE; + } + } else if (layer_type == 1) { + ALOGE("in Gralloc1BufferHandler.cpp %s,line %d \n",__FUNCTION__,__LINE__); + usage |= GRALLOC1_CONSUMER_USAGE_CURSOR; + } + set_consumer_usage_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, usage); + set_producer_usage_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, usage); + set_dimensions_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, w, h); + allocate_(gralloc1_dvc, 1, &temp->gralloc1_buffer_descriptor_t_, + &temp->handle_); + //ALOGE("in Gralloc1BufferHandler.cpp %s,line %d handle_=%p\n",__FUNCTION__,__LINE__,temp->handle_); + if (!temp) { + ALOGE("Failed to allocate buffer \n"); + } + *handle = temp; + return true; +} + +bool Gralloc1BufferHandler::ReleaseBuffer(DRMHwcNativeHandle handle) const { + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + release_(gralloc1_dvc, handle->handle_); + + if (handle->gralloc1_buffer_descriptor_t_ > 0) + destroy_descriptor_(gralloc1_dvc, handle->gralloc1_buffer_descriptor_t_); + + return true; +} + +void Gralloc1BufferHandler::DestroyHandle(DRMHwcNativeHandle handle) const { + if (handle) { + int ret = native_handle_close((native_handle_t* )handle->handle_); + if (ret){ + ALOGE("Failed to close native handle %d", ret); + return; + } + if (NULL != handle->handle_) + ret = native_handle_delete((native_handle_t* )handle->handle_); + if (NULL != handle->handle_){ + delete handle->handle_; + handle->handle_= NULL; + } + } +} + +bool Gralloc1BufferHandler::ImportBuffer(DRMHwcNativeHandle handle) const { + // if (&handle) { + // ALOGE("could not find gralloc drm handle"); + // return false; + // } + + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + register_(gralloc1_dvc, handle->handle_); + + return true; +} + +uint32_t Gralloc1BufferHandler::GetTotalPlanes(DRMHwcNativeHandle handle) const { + // return handle->meta_data_.num_planes_; + (void)handle; + return 0; +} + +void Gralloc1BufferHandler::CopyHandle(DRMHwcNativeHandle source, + DRMHwcNativeHandle target) const { + // *target = source; + cros_gralloc_handle *source_handle = (cros_gralloc_handle *)source->handle_; + cros_gralloc_handle *target_handle = (cros_gralloc_handle *)target->handle_; + target_handle->format = source_handle->format; + target_handle->tiling_mode = source_handle->tiling_mode; + target_handle->width = source_handle->width; + target_handle->height = source_handle->height; + target_handle->droid_format = source_handle->droid_format; + target_handle->is_interlaced = source_handle->is_interlaced; + int32_t numplanes = source_handle->base.numFds; + target_handle->base.numFds = source_handle->base.numFds; + for (int32_t p = 0; p < numplanes; p++) { + target_handle->offsets[p] = source_handle->offsets[p]; + target_handle->strides[p] = source_handle->strides[p]; + target_handle->fds[p] = source_handle->fds[p]; + target_handle->format_modifiers[p] =source_handle->format_modifiers[p]; + } + target_handle->consumer_usage = source_handle->consumer_usage; +} + +void *Gralloc1BufferHandler::Map(DRMHwcNativeHandle handle, uint32_t x, uint32_t y, + uint32_t width, uint32_t height, + uint32_t * /*stride*/, void **map_data, + size_t /*plane*/) const { + //auto gr_handle = (struct cros_gralloc_handle *)handle; + cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)handle->handle_; + if (!gr_handle) { + ALOGE("could not find gralloc drm handle"); + return NULL; + } + + int acquireFence = -1; + gralloc1_rect_t rect{}; + rect.left = x; + rect.top = y; + rect.width = width; + rect.height = height; + + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + uint32_t status = lock_(gralloc1_dvc, handle->handle_, + GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, + GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, &rect, + map_data, acquireFence); + return (GRALLOC1_ERROR_NONE == status) ? *map_data : NULL; + +} + +int32_t Gralloc1BufferHandler::UnMap(DRMHwcNativeHandle handle, + void * /*map_data*/) const { + cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)handle->handle_; + if (!gr_handle) { + ALOGE("could not find gralloc drm handle"); + return GRALLOC1_ERROR_BAD_HANDLE; + } + + int releaseFence = 0; + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + return unlock_(gralloc1_dvc, handle->handle_, &releaseFence); +} + +bool Gralloc1BufferHandler::GetInterlace(DRMHwcNativeHandle handle) const { + // if (((const struct cros_gralloc_handle *)handle->handle_)->is_interlaced > 0) + // return true; + // else + // return false; + if(!handle) + return true; + return false; +} + +} // namespace hwcomposer diff --git a/gralloc1bufferhandler.h b/gralloc1bufferhandler.h new file mode 100755 index 000000000..968cb3999 --- /dev/null +++ b/gralloc1bufferhandler.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OS_ANDROID_DRM_Gralloc1BufferHandler_H_ +#define OS_ANDROID_DRM_Gralloc1BufferHandler_H_ +#include +#include + +#include + +#include +//#include "gralloc_handle.h" +#include "vautils.h" + +namespace android { + + +class Gralloc1BufferHandler : public NativeBufferHandler { + public: + explicit Gralloc1BufferHandler(uint32_t fd); + ~Gralloc1BufferHandler() override; + + bool Init(); + + bool CreateBuffer(uint32_t w, uint32_t h, int format, DRMHwcNativeHandle *handle, + uint32_t layer_type = 0, + bool *modifier_used = NULL, int64_t modifier = -1, + bool raw_pixel_buffer = false) const override; + bool ReleaseBuffer(DRMHwcNativeHandle handle) const override; + void DestroyHandle(DRMHwcNativeHandle handle) const override; + bool ImportBuffer(DRMHwcNativeHandle handle) const override; + void CopyHandle(DRMHwcNativeHandle source, + DRMHwcNativeHandle target) const override; + uint32_t GetTotalPlanes(DRMHwcNativeHandle handle) const override; + void *Map(DRMHwcNativeHandle handle, uint32_t x, uint32_t y, uint32_t width, + uint32_t height, uint32_t *stride, void **map_data, + size_t plane) const override; + int32_t UnMap(DRMHwcNativeHandle handle, void *map_data) const override; + + uint32_t GetFd() const override { + return fd_; + } + + bool GetInterlace(DRMHwcNativeHandle handle) const override; + + private: + uint32_t ConvertHalFormatToDrm(uint32_t hal_format); + uint32_t fd_; + const hw_module_t *gralloc_; + hw_device_t *device_; + GRALLOC1_PFN_RETAIN register_; + GRALLOC1_PFN_RELEASE release_; + GRALLOC1_PFN_GET_DIMENSIONS dimensions_; + GRALLOC1_PFN_LOCK lock_; + GRALLOC1_PFN_UNLOCK unlock_; + GRALLOC1_PFN_CREATE_DESCRIPTOR create_descriptor_; + GRALLOC1_PFN_DESTROY_DESCRIPTOR destroy_descriptor_; + GRALLOC1_PFN_SET_CONSUMER_USAGE set_consumer_usage_; + GRALLOC1_PFN_SET_DIMENSIONS set_dimensions_; + 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 +#endif // OS_ANDROID_Gralloc1BufferHandler_H_ diff --git a/hwcutils.cpp b/hwcutils.cpp old mode 100644 new mode 100755 index 87e3c42ed..d66aa4260 --- a/hwcutils.cpp +++ b/hwcutils.cpp @@ -22,6 +22,7 @@ #include #include +#include "cros_gralloc_handle.h" #define UNUSED(x) (void)(x) @@ -43,10 +44,10 @@ void DrmHwcBuffer::Clear() { } } -int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) { +int DrmHwcBuffer::ImportBuffer(DrmHwcLayer* layer, Importer *importer) { hwc_drm_bo tmp_bo; - int ret = importer->ImportBuffer(handle, &tmp_bo); + int ret = importer->ImportBuffer(layer, &tmp_bo); if (ret) return ret; @@ -108,7 +109,7 @@ void DrmHwcNativeHandle::Clear() { } int DrmHwcLayer::ImportBuffer(Importer *importer) { - int ret = buffer.ImportBuffer(sf_handle, importer); + int ret = buffer.ImportBuffer(this, importer); if (ret) return ret; diff --git a/nativebufferhandler.h b/nativebufferhandler.h new file mode 100755 index 000000000..f41b868c4 --- /dev/null +++ b/nativebufferhandler.h @@ -0,0 +1,64 @@ +/* +// Copyright (c) 2016 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. +*/ + +#ifndef PUBLIC_DMRNATIVEBUFFERHANDLER_H_ +#define PUBLIC_DMRNATIVEBUFFERHANDLER_H_ + +#include +#include + +//#include +//#include +#include "vautils.h" + +namespace android { + +class NativeBufferHandler { + public: + static NativeBufferHandler *CreateInstance(uint32_t fd); + + virtual ~NativeBufferHandler() { + } + + virtual bool CreateBuffer(uint32_t w, uint32_t h, int format, + DRMHwcNativeHandle *handle = NULL, + uint32_t layer_type = 0, + bool *modifier_used = NULL, int64_t modifier = -1, + bool raw_pixel_buffer = false) const = 0; + + virtual bool ReleaseBuffer(DRMHwcNativeHandle handle) const = 0; + + virtual void DestroyHandle(DRMHwcNativeHandle handle) const = 0; + + virtual bool ImportBuffer(DRMHwcNativeHandle handle) const = 0; + + virtual void CopyHandle(DRMHwcNativeHandle source, + DRMHwcNativeHandle target) const = 0; + + virtual uint32_t GetTotalPlanes(DRMHwcNativeHandle handle) const = 0; + + virtual void *Map(DRMHwcNativeHandle handle, uint32_t x, uint32_t y, + uint32_t width, uint32_t height, uint32_t *stride, + void **map_data, size_t plane) const = 0; + + virtual int32_t UnMap(DRMHwcNativeHandle handle, void *map_data) const = 0; + + virtual uint32_t GetFd() const = 0; + virtual bool GetInterlace(DRMHwcNativeHandle handle) const = 0; +}; + +} // namespace hwcomposer +#endif // PUBLIC_NATIVEBUFFERHANDLER_H_ diff --git a/platform.h b/platform.h old mode 100644 new mode 100755 index 6fdece260..5896022ee --- a/platform.h +++ b/platform.h @@ -42,7 +42,8 @@ class Importer { // // Note: This can be called from a different thread than ReleaseBuffer. The // implementation is responsible for ensuring thread safety. - virtual int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) = 0; + //virtual int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) = 0; + virtual int ImportBuffer(DrmHwcLayer* layer, hwc_drm_bo_t *bo) = 0; // Releases the buffer object (ie: does the inverse of ImportBuffer) // diff --git a/platformdrmgeneric.cpp b/platformdrmgeneric.cpp old mode 100644 new mode 100755 index 503c04a6a..d20062b56 --- a/platformdrmgeneric.cpp +++ b/platformdrmgeneric.cpp @@ -101,8 +101,9 @@ uint32_t DrmGenericImporter::DrmFormatToBitsPerPixel(uint32_t drm_format) { } } -int DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { - gralloc_handle_t *gr_handle = gralloc_handle(handle); +//int DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { +int DrmGenericImporter::ImportBuffer(DrmHwcLayer* layer, hwc_drm_bo_t *bo){ + gralloc_handle_t *gr_handle = gralloc_handle(layer->get_usable_handle()); if (!gr_handle) return -EINVAL; diff --git a/platformdrmgeneric.h b/platformdrmgeneric.h old mode 100644 new mode 100755 index 233ba5569..8918aee0b --- a/platformdrmgeneric.h +++ b/platformdrmgeneric.h @@ -31,7 +31,7 @@ class DrmGenericImporter : public Importer { int Init(); - int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override; + int ImportBuffer(DrmHwcLayer* layer, hwc_drm_bo_t *bo) override; int ReleaseBuffer(hwc_drm_bo_t *bo) override; bool CanImportBuffer(buffer_handle_t handle) override; diff --git a/platformminigbm.cpp b/platformminigbm.cpp old mode 100644 new mode 100755 index dce1d114b..2a1431c71 --- a/platformminigbm.cpp +++ b/platformminigbm.cpp @@ -28,6 +28,16 @@ #include #include "cros_gralloc_handle.h" +#include "vautils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace android { @@ -42,14 +52,28 @@ Importer *Importer::CreateInstance(DrmDevice *drm) { delete importer; return NULL; } + importer->EnableVaRender(); return importer; } + +void DrmMinigbmImporter::EnableVaRender() { + if (!media_renderer_) { + media_renderer_.reset(new VARenderer()); + if (!media_renderer_->Init(drm_->fd())) { + ALOGE("Failed to initialize Media va Renderer \n"); + media_renderer_.reset(nullptr); + } + } +} + DrmMinigbmImporter::DrmMinigbmImporter(DrmDevice *drm) : DrmGenericImporter(drm), drm_(drm) { } DrmMinigbmImporter::~DrmMinigbmImporter() { + if (NULL != media_renderer_) + media_renderer_.reset(nullptr); } int DrmMinigbmImporter::Init() { @@ -67,19 +91,66 @@ int DrmMinigbmImporter::Init() { return 0; } -int DrmMinigbmImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { +#ifdef ENABLE_DUMP_YUV_DATA + +static void DumpData(buffer_handle_t handle){ + if (NULL == handle) + return; + char dump_file[200]; cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)handle; - if (!gr_handle) + native_handle_t *handle_copy; + uint8_t* pixels; + GraphicBufferMapper &gm(GraphicBufferMapper::get()); + int ret = gm.importBuffer(handle, gr_handle->width, gr_handle->height, 1, gr_handle->format/*DRM_FORMAT_YUV420*/, gr_handle->usage, + gr_handle->pixel_stride, const_cast(&handle_copy)); + if (ret != 0) + ALOGE("in platformminigbm.cpp function %s,line %d ret=%d::fail to import buffer\n",__FUNCTION__,__LINE__,ret); + ret = gm.lock(handle_copy, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER, + Rect(gr_handle->width, gr_handle->height), reinterpret_cast(&pixels)); + if (ret != 0) + ALOGE("in platformminigbm.cpp function %s,line %d ret=%d::fail to lock buffer\n",__FUNCTION__,__LINE__,ret); + char ctime[32]; + time_t t = time(0); + strftime(ctime, sizeof(ctime), "%Y-%m-%d", localtime(&t)); + sprintf(dump_file, "/data/dump_%d*%d_0x%x_%s", gr_handle->width, gr_handle->height, gr_handle->format, ctime); + int file_fd = 0; + file_fd = open(dump_file, O_RDWR|O_CREAT|O_APPEND, 0666); + if (file_fd == -1) { + ALOGE("in platformminigbm.cpp function %s,line %d::fail to open file\n",__FUNCTION__,__LINE__); + return; + } + write(file_fd, pixels, gr_handle->sizes[0]); + gm.unlock(handle_copy); + gm.freeBuffer(handle_copy); + close(file_fd); +} +#endif + +int DrmMinigbmImporter::ImportBuffer(DrmHwcLayer* layer, hwc_drm_bo_t *bo){ + cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)layer->get_usable_handle(); + int ret = 0; + uint32_t flag =0; + bool vendor_flag = false; + if (!gr_handle) { return -EINVAL; - + } uint32_t gem_handle; - int ret = drmPrimeFDToHandle(drm_->fd(), gr_handle->fds[0], &gem_handle); + memset(bo, 0, sizeof(hwc_drm_bo_t)); + if (IsSupportedMediaFormat(gr_handle->format)) { + media_renderer_->startRender(layer, DRM_FORMAT_ABGR8888); + //for avoid flushing when do the rotation + if(bak_transform != layer->transform){ + bak_transform = layer->transform; + return -EINVAL; + } + gr_handle = (cros_gralloc_handle *)media_renderer_->getPreBuffer(); + vendor_flag = true; + } + ret = drmPrimeFDToHandle(drm_->fd(), gr_handle->fds[0], &gem_handle); if (ret) { ALOGE("failed to import prime fd %d ret=%d", gr_handle->fds[0], ret); return ret; } - - memset(bo, 0, sizeof(hwc_drm_bo_t)); bo->width = gr_handle->width; bo->height = gr_handle->height; bo->hal_format = gr_handle->droid_format; @@ -89,9 +160,30 @@ int DrmMinigbmImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { bo->pitches[0] = gr_handle->strides[0]; bo->offsets[0] = gr_handle->offsets[0]; bo->gem_handles[0] = gem_handle; - - ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format, - bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id, 0); +#ifdef ENABLE_DUMP_YUV_DATA + if(vendor_flag){ + DumpData((buffer_handle_t)gr_handle); + } +#endif + if ((vendor_flag) && ((layer->transform == kHwcTransform270) || (layer->transform == kHwcTransform90))) { + flag = DRM_MODE_FB_MODIFIERS; + uint64_t modifiers[4]; + uint32_t numplanes = gr_handle->base.numFds; + + for (uint32_t i = 0; i < numplanes; i++) { + if(vendor_flag){ + modifiers[i] = I915_FORMAT_MOD_Y_TILED; + } + } + for (uint32_t i = numplanes; i < 4; i++) { + modifiers[i] = DRM_FORMAT_MOD_NONE; + } + ret = drmModeAddFB2WithModifiers( + drm_->fd(), bo->width, bo->height, bo->format, bo->gem_handles, + bo->pitches, bo->offsets, modifiers, &bo->fb_id, flag); + }else + ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format, + bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id, flag); if (ret) { ALOGE("could not create drm fb %d", ret); return ret; diff --git a/platformminigbm.h b/platformminigbm.h old mode 100644 new mode 100755 index 25f8404d3..69fab4e40 --- a/platformminigbm.h +++ b/platformminigbm.h @@ -22,6 +22,7 @@ #include "platformdrmgeneric.h" #include +#include "varenderer.h" namespace android { @@ -32,11 +33,13 @@ class DrmMinigbmImporter : public DrmGenericImporter { int Init(); - int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override; + int ImportBuffer(DrmHwcLayer* layer, hwc_drm_bo_t *bo) override; + void EnableVaRender(); private: DrmDevice *drm_; - + uint32_t bak_transform = 0; + std::unique_ptr media_renderer_; const gralloc_module_t *gralloc_; }; diff --git a/tests/Android.bp b/tests/Android.bp deleted file mode 100644 index 058faa03c..000000000 --- a/tests/Android.bp +++ /dev/null @@ -1,13 +0,0 @@ - - -cc_test { - name: "hwc-drm-tests", - - srcs: ["worker_test.cpp"], - - vendor: true, - header_libs: ["libhardware_headers"], - static_libs: ["libdrmhwc_utils"], - shared_libs: ["hwcomposer.drm"], - include_dirs: ["external/drm_hwcomposer"], -} diff --git a/tests/worker_test.cpp b/tests/worker_test.cpp deleted file mode 100644 index 82523f009..000000000 --- a/tests/worker_test.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include - -#include - -#include "worker.h" - -using android::Worker; - -struct TestWorker : public Worker { - TestWorker() - : Worker("test-worker", HAL_PRIORITY_URGENT_DISPLAY), - value(0), - enabled_(false) { - } - - int Init() { - return InitWorker(); - } - - void Routine() { - Lock(); - if (!enabled_) { - int ret = WaitForSignalOrExitLocked(); - if (ret == -EINTR) { - Unlock(); - return; - } - // should only reached here if it was enabled - if (!enabled_) - printf("Shouldn't reach here while disabled %d %d\n", value, ret); - } - value++; - Unlock(); - } - - void Control(bool enable) { - bool changed = false; - Lock(); - if (enabled_ != enable) { - enabled_ = enable; - changed = true; - } - Unlock(); - - if (enable && changed) - Signal(); - } - - int value; - - private: - bool enabled_; -}; - -struct WorkerTest : public testing::Test { - TestWorker worker; - - virtual void SetUp() { - worker.Init(); - } - - void small_delay() { - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - } -}; - -TEST_F(WorkerTest, test_worker) { - // already isInitialized so should succeed - ASSERT_TRUE(worker.initialized()); - - int val = worker.value; - small_delay(); - - // value shouldn't change when isInitialized - ASSERT_EQ(val, worker.value); - - worker.Control(true); - small_delay(); - - // while locked, value shouldn't be changing - worker.Lock(); - val = worker.value; - small_delay(); - ASSERT_EQ(val, worker.value); - worker.Unlock(); - - small_delay(); - // value should be different now - ASSERT_NE(val, worker.value); - - worker.Control(false); - worker.Lock(); - val = worker.value; - worker.Unlock(); - small_delay(); - - // value should be same - ASSERT_EQ(val, worker.value); - - worker.Exit(); - ASSERT_FALSE(worker.initialized()); -} - -TEST_F(WorkerTest, exit_while_running) { - worker.Control(true); - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - worker.Exit(); -} diff --git a/varenderer.cpp b/varenderer.cpp new file mode 100755 index 000000000..bf951f876 --- /dev/null +++ b/varenderer.cpp @@ -0,0 +1,621 @@ +/* +// Copyright (c) 2017 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 "va/sysdeps.h" +#include "varenderer.h" + +#include +#include +#include +#include +#include "va/va_backend.h" +#include "va/va_internal.h" +#include "va/va_fool.h" +#include "va/va_android.h" +#include "va/va_drmcommon.h" +#include "va/drm/va_drm_utils.h" + +#include +#include +#include +#include +#include +#include "cros_gralloc_handle.h" +#include "vautils.h" +#include +#include "autolock.h" +#include + +namespace android { +#define ANDROID_DISPLAY_HANDLE 0x18C34078 +#define CHECK_SYMBOL(func) { if (!func) printf("func %s not found\n", #func); return VA_STATUS_ERROR_UNKNOWN; } +#define DEVICE_NAME "/dev/dri/renderD128" + +VARenderer::~VARenderer() { + DestroyContext(); + if (va_display_) { + vaTerminate(va_display_); + } + DRMHwcNativeHandle temp_handle; + if(native_handles.size() == NATIVE_BUFFER_VECTOR_SIZE){ + for( int32_t i=0; iReleaseBuffer(temp_handle); + buffer_handler_->DestroyHandle(temp_handle); + } + native_handles.clear(); + } + if(native_rotation_handles.size() == NATIVE_BUFFER_VECTOR_SIZE){ + for( int32_t i=0; iReleaseBuffer(temp_handle); + buffer_handler_->DestroyHandle(temp_handle); + } + native_rotation_handles.clear(); + } + if(native_active_handles.size() == NATIVE_BUFFER_VECTOR_SIZE){ + for( int32_t i=0; iReleaseBuffer(temp_handle); + buffer_handler_->DestroyHandle(temp_handle); + } + native_active_handles.clear(); + } + if(va_surface_in_ != VA_INVALID_ID) + vaDestroySurfaces(va_display_, &va_surface_out_, 1); + if(va_surface_in_ != VA_INVALID_ID) + vaDestroySurfaces(va_display_, &va_surface_in_, 1); + + std::vector::iterator itr = pipeline_buffers.begin(); + while (itr!=pipeline_buffers.end()) + { + pipeline_buffers.erase(itr); + itr++; + } +} + +bool VARenderer::Init(uint32_t fd) { + unsigned int native_display = ANDROID_DISPLAY_HANDLE; + buffer_handler_.reset(NativeBufferHandler::CreateInstance(fd)); + VAStatus ret = VA_STATUS_SUCCESS; + va_display_ = vaGetDisplay(&native_display); + if (!va_display_) { + ALOGE("vaGetDisplay failed\n"); + return false; + } + ret = pthread_mutex_init(&lock_, NULL); + if (ret) + ALOGE("Failed to initialize the mutex lock %d\n", ret); + // ret = VA_STATUS_SUCCESS; + int major, minor; + ret = vaInitialize(va_display_, &major, &minor); + + std::vector temp_pipeline_buffers(NATIVE_BUFFER_VECTOR_SIZE, va_display_); + pipeline_buffers.swap(temp_pipeline_buffers); + return ret == VA_STATUS_SUCCESS ? true : false; +} + +bool VARenderer::QueryVAProcFilterCaps(VAContextID context, + VAProcFilterType type, void* caps, + uint32_t* num) { + VAStatus ret = + vaQueryVideoProcFilterCaps(va_display_, context, type, caps, num); + if (ret != VA_STATUS_SUCCESS) + ALOGE("Query Filter Caps failed\n"); + return ret == VA_STATUS_SUCCESS ? true : false; +} + +bool VARenderer::MapVAProcFilterColorModetoHwc(HWCColorControl& vppmode, + VAProcColorBalanceType vamode) { + switch (vamode) { + case VAProcColorBalanceHue: + vppmode = HWCColorControl::kColorHue; + break; + case VAProcColorBalanceSaturation: + vppmode = HWCColorControl::kColorSaturation; + break; + case VAProcColorBalanceBrightness: + vppmode = HWCColorControl::kColorBrightness; + break; + case VAProcColorBalanceContrast: + vppmode = HWCColorControl::kColorContrast; + break; + default: + return false; + } + return true; +} + +bool VARenderer::SetVAProcFilterColorDefaultValue( + VAProcFilterCapColorBalance* caps) { + HWCColorControl mode; + for (int i = 0; i < VAProcColorBalanceCount; i++) { + if (MapVAProcFilterColorModetoHwc(mode, caps[i].type)) { + colorbalance_caps_[mode].caps_ = caps[i]; + colorbalance_caps_[mode].value_ = caps[i].range.default_value; + } + } + sharp_caps_.value_ = sharp_caps_.caps_.range.default_value; + update_caps_ = true; + return true; +} + +bool VARenderer::SetVAProcFilterDeinterlaceDefaultMode() { + if (deinterlace_caps_.mode_ != VAProcDeinterlacingNone) { + deinterlace_caps_.mode_ = VAProcDeinterlacingNone; + update_caps_ = true; + } + return true; +} + +bool VARenderer::SetVAProcFilterColorValue(HWCColorControl mode, + const HWCColorProp& prop) { + if (mode == HWCColorControl::kColorHue || + mode == HWCColorControl::kColorSaturation || + mode == HWCColorControl::kColorBrightness || + mode == HWCColorControl::kColorContrast) { + if (prop.use_default_) { + if (!colorbalance_caps_[mode].use_default_) { + colorbalance_caps_[mode].use_default_ = true; + update_caps_ = true; + } + } else if (prop.value_ != colorbalance_caps_[mode].value_) { + if (prop.value_ > colorbalance_caps_[mode].caps_.range.max_value || + prop.value_ < colorbalance_caps_[mode].caps_.range.min_value) { + ALOGE("VA Filter value out of range. Mode %d range shoud be %f~%f\n", + mode, colorbalance_caps_[mode].caps_.range.min_value, + colorbalance_caps_[mode].caps_.range.max_value); + return false; + } + colorbalance_caps_[mode].value_ = prop.value_; + colorbalance_caps_[mode].use_default_ = false; + update_caps_ = true; + } + return true; + } else if (mode == HWCColorControl::kColorSharpness) { + if (prop.use_default_) { + if (!sharp_caps_.use_default_) { + sharp_caps_.use_default_ = true; + update_caps_ = true; + } + } else if (prop.value_ != sharp_caps_.value_) { + if (prop.value_ > sharp_caps_.caps_.range.max_value || + prop.value_ < sharp_caps_.caps_.range.min_value) { + ALOGE("VA Filter sharp value out of range. should be %f~%f\n", + sharp_caps_.caps_.range.min_value, + sharp_caps_.caps_.range.max_value); + return false; + } + sharp_caps_.value_ = prop.value_; + sharp_caps_.use_default_ = false; + update_caps_ = true; + } + return true; + } else { + ALOGE("VA Filter undefined color mode\n"); + return false; + } +} + +unsigned int VARenderer::GetVAProcFilterScalingMode(uint32_t mode) { + if (deinterlace_caps_.mode_ == VAProcDeinterlacingNone) { + switch (mode) { + case 1: + return VA_FILTER_SCALING_FAST; + case 2: + return VA_FILTER_SCALING_HQ; + default: + return VA_FILTER_SCALING_HQ; + } + } else + return VA_FILTER_SCALING_FAST; +} + + +//get vasurface by the buffer_hande_t from the layer +int VARenderer::getSurfaceIn(buffer_handle_t bufferHandle, VADisplay display, VASurfaceID* surface, uint32_t format, uint32_t width, uint32_t height){ + if (NULL == bufferHandle) { + ALOGE(" in varender.cpp %s,line %d bufferHandle==NULL\n",__FUNCTION__,__LINE__); + return -1; + } + cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)bufferHandle; + if ((gr_handle->width == 0) || (gr_handle->height == 0)){ + ALOGE(" in varender.cpp %s,line %d bufferHandle is error\n",__FUNCTION__,__LINE__); + return -1; + } + VASurfaceAttribExternalBuffers external; + memset(&external, 0, sizeof(external)); + int32_t numplanes = gr_handle->base.numFds; + uint32_t rt_format = DrmFormatToRTFormat(format); + uint32_t total_planes = numplanes; + external.pixel_format = DrmFormatToVAFormat(format); + external.width = width;//gr_handle->width; + external.height = height;//gr_handle->height; + external.num_planes = total_planes; + uintptr_t prime_fds[total_planes]; + for (unsigned int i = 0; i < total_planes; i++) { + external.pitches[i] = gr_handle->strides[i]; + external.offsets[i] = gr_handle->offsets[i]; + prime_fds[i] = gr_handle->fds[i]; + } + external.num_buffers = total_planes; + external.buffers = prime_fds; + VASurfaceAttrib attribs[2]; + attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE; + attribs[0].type = VASurfaceAttribMemoryType; + attribs[0].value.type = VAGenericValueTypeInteger; + attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; + attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE; + attribs[1].type = VASurfaceAttribExternalBufferDescriptor; + attribs[1].value.type = VAGenericValueTypePointer; + attribs[1].value.value.p = &external; + VAStatus ret = vaCreateSurfaces(display, rt_format, external.width, external.height, + surface, 1, attribs, 2); + if (ret != VA_STATUS_SUCCESS) + ALOGE("AAAfail to create VASurface from drmbuffer with ret %x", ret); + return ret; +} + +bool VARenderer::startRender(DrmHwcLayer* layer,uint32_t format){ + cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)layer->get_usable_handle(); + int64_t modifier = 0; + uint32_t usage =3; + VAStatus ret = VA_STATUS_SUCCESS; + bool modifer_succeeded = false; + DRMHwcNativeHandle temp_handle = 0; + uint32_t input_layer_numer = 1; + std::map> va_layer_map = layer->getVaLayerMapData(); + input_layer_numer = va_layer_map.size(); + //format = DRM_FORMAT_ABGR8888; + int rt_format = DrmFormatToRTFormat(format); + if(render_target_format_ != rt_format) + render_target_format_ = rt_format; + if ((layer->transform == kHwcTransform270) || (layer->transform == kHwcTransform90)) + modifier = I915_FORMAT_MOD_Y_TILED; + else + modifier = 0; + //if don't init the context , create the va context and gralloc buffer for the native_handles + std::vector relese_handles; + AutoLock lock(&lock_, __func__); + ret = lock.Lock(); + if (va_context_ == VA_INVALID_ID ) { + if (!CreateContext()) { + ALOGE("AAAfail Create VA context failed\n"); + return false; + } + for( int32_t i=0; iCreateBuffer(/*gr_handle->width, gr_handle->height,*/1920,1080,format,//2560*1440 + &temp_handle,usage,&modifer_succeeded,modifier); + if (modifier == 0) { + native_handles.push_back(temp_handle); + native_active_handles.push_back(temp_handle); + }else{ + native_rotation_handles.push_back(temp_handle); + native_active_handles.push_back(temp_handle); + } + } + modifier_bak = modifier; + current_handle_position = 0; + } + if (modifier_bak !=modifier) { + if (modifier == I915_FORMAT_MOD_Y_TILED) { + if (native_rotation_handles.size() == 0) { + for( int32_t i=0; iCreateBuffer(/*gr_handle->width, gr_handle->height,*/1920,1080,format, + &temp_handle,usage,&modifer_succeeded,modifier); + native_rotation_handles.push_back(temp_handle); + } + } + native_handles.swap(native_active_handles); + native_active_handles.swap(native_rotation_handles); + } else { + if (native_handles.size() == 0) { + for( int32_t i=0; iCreateBuffer(/*gr_handle->width, gr_handle->height,*/1920,1080,format,//2560*1440 + &temp_handle,usage,&modifer_succeeded,modifier); + native_handles.push_back(temp_handle); + } + } + native_rotation_handles.swap(native_active_handles); + native_active_handles.swap(native_handles); + } + modifier_bak = modifier; + current_handle_position = 0; + } + //create va output surface + VASurfaceID surface_in = VA_INVALID_ID; + VASurfaceID surface_out = VA_INVALID_ID; + if (gr_handle->format == DRM_FORMAT_NV12_Y_TILED_INTEL) + gr_handle->format = DRM_FORMAT_NV12; + + ScopedVABufferID& pipeline_buffer = pipeline_buffers.at(current_handle_position); + + for (int i =0; ihandle_, va_display_, &surface_out, format, 1920, 1080);//gr_handle->width, gr_handle->height); + if (VA_STATUS_SUCCESS != ret) { + ALOGE("in varender.cpp %s,line %d fail to get surface_in\n",__FUNCTION__,__LINE__); + if (current_handle_position == (NATIVE_BUFFER_VECTOR_SIZE -1 )) + current_handle_position = 0; + else + current_handle_position ++; + }else + break; + } + if (VA_STATUS_SUCCESS != ret) + return false; + + va_surface_out_ = surface_out; + ret = vaBeginPicture(va_display_, va_context_, va_surface_out_); + for (std::map::reverse_iterator a = va_layer_map.rbegin(); a != va_layer_map.rend(); a++) { + VAProcPipelineParameterBuffer pipe_param = {}; + cros_gralloc_handle *gr_handle_t = (cros_gralloc_handle *)a->second->get_usable_handle(); + hwc_frect_t source_crop = a->second->source_crop; + VARectangle surface_region; + //create va input surface + surface_region.x = source_crop.left;//gr_handle->left; + surface_region.y = source_crop.top;//gr_handle->top; + surface_region.width = source_crop.right - source_crop.left; + surface_region.height = source_crop.bottom - source_crop.top; + ALOGE(" in varender.cpp %s,line %d surface_region(x=%d,y=%d,w=%d,h=%d)\n",__FUNCTION__,__LINE__,surface_region.x,surface_region.y,surface_region.width,surface_region.height); + if ((0 == surface_region.width) || (0 == surface_region.height)) + return false; + hwc_rect_t display_frame = a->second->display_frame; + VARectangle output_region; + output_region.x = display_frame.left; + output_region.y = display_frame.top; + output_region.width = display_frame.right - display_frame.left; + output_region.height = display_frame.bottom - display_frame.top; + ALOGE(" in varender.cpp %s,line %d output_region(x=%d,y=%d,w=%d,h=%d),zorder=%d\n",__FUNCTION__,__LINE__,output_region.x,output_region.y,output_region.width,output_region.height,a->first); + ret = getSurfaceIn(a->second->get_usable_handle(), va_display_, &surface_in, gr_handle_t->format, gr_handle_t->width, gr_handle_t->height); + if (VA_STATUS_SUCCESS != ret) { + ALOGE("in varender.cpp %s,line %d fail to get surface_in\n",__FUNCTION__,__LINE__); + return false; + } + va_surface_in_ = surface_in; + pipe_param.surface = va_surface_in_; + pipe_param.surface_region = &surface_region; + pipe_param.surface_color_standard = VAProcColorStandardBT601; + pipe_param.output_region = &output_region; + pipe_param.output_color_standard = VAProcColorStandardBT601; + VABlendState bs = {}; + bs.flags = VA_BLEND_PREMULTIPLIED_ALPHA; + pipe_param.blend_state = &bs; + pipe_param.filter_flags = GetVAProcFilterScalingMode(1); + if (filters_.size()) + pipe_param.filters = filters_.data(); + pipe_param.num_filters = static_cast(filters_.size()); +#if VA_MAJOR_VERSION >= 1 + // currently rotation is only supported by VA on Android. + uint32_t rotation = 0, mirror = 0; + HWCTransformToVA(layer->transform, rotation, mirror); + pipe_param.rotation_state = rotation; + pipe_param.mirror_state = mirror; +#endif +#ifdef VA_SUPPORT_COLOR_RANGE + uint32_t dataspace = layer->dataspace; + if ((dataspace & HAL_DATASPACE_RANGE_FULL) != 0) { + pipe_param.input_color_properties.color_range = VA_SOURCE_RANGE_FULL; + } +#endif + if (!pipeline_buffer.CreateBuffer(va_context_, VAProcPipelineParameterBufferType, + sizeof(VAProcPipelineParameterBuffer), 1, &pipe_param)) { + return false; + } + ret |= vaRenderPicture(va_display_, va_context_, &pipeline_buffer.buffer(), 1); + if (ret != VA_STATUS_SUCCESS) { + ALOGE(" in varender.cpp %s,line %d, fail to vaRenderPicture ,ret=%d\n",__FUNCTION__,__LINE__,ret); + return false; + } + } + ret |= vaEndPicture(va_display_, va_context_); + if (ret != VA_STATUS_SUCCESS) + ALOGE(" in varender.cpp %s,line %d, fail to vaEndPicture ,ret=%d\n",__FUNCTION__,__LINE__,ret); + + current_handle_position++; + if (current_handle_position >= NATIVE_BUFFER_VECTOR_SIZE) + current_handle_position = 0; + + return true; +} + +bool VARenderer::LoadCaps() { + VAProcFilterCapColorBalance colorbalancecaps[VAProcColorBalanceCount]; + uint32_t colorbalance_num = VAProcColorBalanceCount; + uint32_t sharp_num = 1; + uint32_t deinterlace_num = VAProcDeinterlacingCount; + memset(colorbalancecaps, 0, + sizeof(VAProcFilterCapColorBalance) * VAProcColorBalanceCount); + if (!QueryVAProcFilterCaps(va_context_, VAProcFilterColorBalance, + colorbalancecaps, &colorbalance_num)) { + return false; + } + if (!QueryVAProcFilterCaps(va_context_, VAProcFilterSharpening, + &sharp_caps_.caps_, &sharp_num)) { + return false; + } + if (!QueryVAProcFilterCaps(va_context_, VAProcFilterDeinterlacing, + &deinterlace_caps_.caps_, &deinterlace_num)) { + return false; + } + + SetVAProcFilterColorDefaultValue(&colorbalancecaps[0]); + SetVAProcFilterDeinterlaceDefaultMode(); + + return true; +} + +bool VARenderer::CreateContext() { + DestroyContext(); + VAConfigAttrib config_attrib; + config_attrib.type = VAConfigAttribRTFormat; + config_attrib.value = render_target_format_; + VAStatus ret = + vaCreateConfig(va_display_, VAProfileNone, VAEntrypointVideoProc, + &config_attrib, 1, &va_config_); + if (ret != VA_STATUS_SUCCESS) { + ALOGE("Create VA Config failed\n"); + return false; + } + // These parameters are not used in vaCreateContext so just set them to dummy + int width = 1; + int height = 1; + ret = vaCreateContext(va_display_, va_config_, width, height, 0x00, nullptr, + 0, &va_context_); + + update_caps_ = true; + if (ret == VA_STATUS_SUCCESS) { + if (!LoadCaps() || !UpdateCaps()) + return false; + } + + return ret == VA_STATUS_SUCCESS ? true : false; +} + +void VARenderer::DestroyContext() { + if (va_context_ != VA_INVALID_ID) { + vaDestroyContext(va_display_, va_context_); + va_context_ = VA_INVALID_ID; + } + if (va_config_ != VA_INVALID_ID) { + vaDestroyConfig(va_display_, va_config_); + va_config_ = VA_INVALID_ID; + } + std::vector().swap(filters_); + std::vector().swap(cb_elements_); + std::vector().swap(sharp_); +} + +bool VARenderer::UpdateCaps() { + if (!update_caps_) { + return true; + } + + update_caps_ = false; + + std::vector cb_elements(1, va_display_); + std::vector sharp(1, va_display_); + std::vector deinterlace(1, va_display_); + + std::vector().swap(filters_); + std::vector().swap(cb_elements_); + std::vector().swap(sharp_); + std::vector().swap(deinterlace_); + + VAProcFilterParameterBufferColorBalance cbparam[VAProcColorBalanceCount]; + VAProcFilterParameterBuffer sharpparam; + VAProcFilterParameterBufferDeinterlacing deinterlaceparam; + memset(cbparam, 0, VAProcColorBalanceCount * + sizeof(VAProcFilterParameterBufferColorBalance)); + int index = 0; + for (auto itr = colorbalance_caps_.begin(); itr != colorbalance_caps_.end(); + itr++) { + if (itr->second.use_default_) { + itr->second.value_ = itr->second.caps_.range.default_value; + } + if (fabs(itr->second.value_ - itr->second.caps_.range.default_value) >= + itr->second.caps_.range.step) { + cbparam[index].type = VAProcFilterColorBalance; + cbparam[index].value = itr->second.value_; + cbparam[index].attrib = itr->second.caps_.type; + index++; + } + } + + if (index) { + if (!cb_elements[0].CreateBuffer( + va_context_, VAProcFilterParameterBufferType, + sizeof(VAProcFilterParameterBufferColorBalance), index, cbparam)) { + ALOGE("Create color fail\n"); + return false; + } + filters_.push_back(cb_elements[0].buffer()); + } + cb_elements_.swap(cb_elements); + + if (sharp_caps_.use_default_) { + sharp_caps_.value_ = sharp_caps_.caps_.range.default_value; + } + if (fabs(sharp_caps_.value_ - sharp_caps_.caps_.range.default_value) >= + sharp_caps_.caps_.range.step) { + sharpparam.value = sharp_caps_.value_; + sharpparam.type = VAProcFilterSharpening; + if (!sharp[0].CreateBuffer(va_context_, VAProcFilterParameterBufferType, + sizeof(VAProcFilterParameterBuffer), 1, + &sharpparam)) { + return false; + } + filters_.push_back(sharp[0].buffer()); + } + sharp_.swap(sharp); + + if (deinterlace_caps_.mode_ != VAProcDeinterlacingNone) { + deinterlaceparam.algorithm = deinterlace_caps_.mode_; + deinterlaceparam.type = VAProcFilterDeinterlacing; + if (!deinterlace[0].CreateBuffer( + va_context_, VAProcFilterParameterBufferType, + sizeof(VAProcFilterParameterBufferDeinterlacing), 1, + &deinterlaceparam)) { + return false; + } + filters_.push_back(deinterlace[0].buffer()); + } + deinterlace_.swap(deinterlace); + + return true; +} + +#if VA_MAJOR_VERSION >= 1 +void VARenderer::HWCTransformToVA(uint32_t transform, uint32_t& rotation, + uint32_t& mirror) { + rotation = VA_ROTATION_NONE; + mirror = VA_MIRROR_NONE; + + if (transform & kHwcReflectX) + mirror |= VA_MIRROR_HORIZONTAL; + if (transform & kHwcReflectY) + mirror |= VA_MIRROR_VERTICAL; + + if (mirror == VA_MIRROR_NONE || + mirror == (VA_MIRROR_HORIZONTAL | VA_MIRROR_VERTICAL)) { + transform &= ~kHwcReflectX; + transform &= ~kHwcReflectY; + switch (transform) { + case kHwcTransform270: + rotation = VA_ROTATION_270; + break; + case kHwcTransform180: + rotation = VA_ROTATION_180; + break; + case kHwcTransform90: + rotation = VA_ROTATION_90; + break; + default: + break; + } + } else { + // Fixme? WA added. VA is using rotation then mirror order + // CTS Cameration orientation is expecting mirror, then rotation + // WA added to use inverse rotation to make the same result + if (transform & kHwcTransform180) + rotation = VA_ROTATION_180; + else if (transform & kHwcTransform90) + rotation = VA_ROTATION_270; + else if (transform & kHwcTransform270) + rotation = VA_ROTATION_90; + } +} +#endif + +} // namespace hwcomposer diff --git a/varenderer.h b/varenderer.h new file mode 100755 index 000000000..b3a39e887 --- /dev/null +++ b/varenderer.h @@ -0,0 +1,235 @@ +/* +// Copyright (c) 2016 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. +*/ + +#ifndef COMMON_DRM_COMPOSITOR_VA_VARENDERER_H_ +#define COMMON_DRM_COMPOSITOR_VA_VARENDERER_H_ + +//#include +//#include +#include +#include +#include +#include "nativebufferhandler.h" + +//#include "hwcdefs.h" +//#include "overlaybuffer.h" +//#include "renderer.h" + +#include +#include +#include "vautils.h" +#include "drmhwcomposer.h" + +#define NATIVE_BUFFER_VECTOR_SIZE 3 + +namespace android { + +struct OverlayLayer; +class NativeSurface; + +class ScopedVABufferID { + public: + ScopedVABufferID(VADisplay display) : display_(display) { + } + ~ScopedVABufferID() { + if (buffer_ != VA_INVALID_ID) + vaDestroyBuffer(display_, buffer_); + } + + bool CreateBuffer(VAContextID context, VABufferType type, uint32_t size, + uint32_t num, void* data) { + VAStatus ret = + vaCreateBuffer(display_, context, type, size, num, data, &buffer_); + return ret == VA_STATUS_SUCCESS ? true : false; + } + + operator VABufferID() const { + return buffer_; + } + + VABufferID buffer() const { + return buffer_; + } + + VABufferID& buffer() { + return buffer_; + } + + private: + VADisplay display_; + VABufferID buffer_ = VA_INVALID_ID; +}; + +struct HwcColorBalanceCap { + VAProcFilterCapColorBalance caps_; + float value_; + bool use_default_ = true; +}; + + +enum class HWCColorControl : int32_t { + kColorHue = 0, + kColorSaturation = 1, + kColorBrightness = 2, + kColorContrast = 3, + kColorSharpness = 4 +}; + +struct HWCColorProp { + float value_ = 0.0; + bool use_default_ = true; +}; + +enum class HWCDeinterlaceFlag : int32_t { + kDeinterlaceFlagNone = 0, + kDeinterlaceFlagForce = 1, + kDeinterlaceFlagAuto = 2 +}; + +enum class HWCDeinterlaceControl : int32_t { + kDeinterlaceNone = 0, + kDeinterlaceBob = 1, + kDeinterlaceWeave = 2, + kDeinterlaceMotionAdaptive = 3, + kDeinterlaceMotionCompensated = 4 +}; + +struct HWCDeinterlaceProp { + HWCDeinterlaceFlag flag_; + HWCDeinterlaceControl mode_; +}; + +enum HWCTransform : uint32_t { + kHwcIdentity = 0, + kHwcReflectX = 1 << 0, + kHwcReflectY = 1 << 1, + kHwcTransform90 = 1 << 2, + kHwcTransform180 = 1 << 3, + kHwcTransform270 = 1 << 4, + kHwcTransform45 = kHwcTransform90 | kHwcReflectY, + kHwcTransform135 = kHwcTransform90 | kHwcReflectX, + kHwcMaxTransform = 8 +}; + +enum HWCRotation { + kHwcRotateNone = 0, + kHwcRotate90, + kHwcRotate180, + kHwcRotate270, + kHwcMaxRotate +}; + + +struct HwcFilterCap { + VAProcFilterCap caps_; + float value_; + bool use_default_ = true; +}; + +typedef struct _HwcDeinterlaceCap { + VAProcFilterCapDeinterlacing caps_[VAProcDeinterlacingCount]; + VAProcDeinterlacingType mode_; +} HwcDeinterlaceCap; + +//static int64_t modifier_bak = 0; + +class VARenderer { + public: + VARenderer() = default; + ~VARenderer(); + + bool Init(uint32_t fd) ; + //bool startRender(const MediaState& state, NativeSurface* surface) ; + bool startRender(DrmHwcLayer* layer,uint32_t format); + void InsertFence(int32_t /*kms_fence*/) { + } + + //VADisplay vaGetDisplay (void *native_dpy ); + + void SetDisableExplicitSync(bool /*disable_explicit_sync*/) { + } + buffer_handle_t getPreBuffer(){ + int temp =0 ; + if(current_handle_position ==0){ + temp = NATIVE_BUFFER_VECTOR_SIZE -1 ; + }else if(current_handle_position ==-1){ + return 0; + }else{ + temp = current_handle_position -1; + } + return native_active_handles.at(temp)->handle_; + } + + // bool DestroyMediaResources(std::vector&) ; + + private: + bool QueryVAProcFilterCaps(VAContextID context, VAProcFilterType type, + void* caps, uint32_t* num); + unsigned int GetVAProcFilterScalingMode(uint32_t mode); + bool SetVAProcFilterColorValue(HWCColorControl type, + const HWCColorProp& prop); + //bool SetVAProcFilterDeinterlaceMode(const HWCDeinterlaceProp& prop, + // OverlayBuffer* buffer); + bool SetVAProcFilterColorDefaultValue(VAProcFilterCapColorBalance* caps); + bool SetVAProcFilterDeinterlaceDefaultMode(); + bool MapVAProcFilterColorModetoHwc(HWCColorControl& vppmode, + VAProcColorBalanceType vamode); +// bool GetVAProcDeinterlaceFlagFromVideo(const HWCDeinterlaceFlag flag, +// OverlayBuffer* buffer); + bool CreateContext(); + void DestroyContext(); + bool LoadCaps(); + bool UpdateCaps(); + +// void getSurfaceIn(buffer_handle_t bufferHandle, VADisplay display, VASurfaceID* surface,uint32_t format); + int getSurfaceIn(buffer_handle_t bufferHandle, VADisplay display, VASurfaceID* surface,uint32_t format,uint32_t width, uint32_t height); +#if VA_MAJOR_VERSION >= 1 + void HWCTransformToVA(uint32_t transform, uint32_t& rotation, + uint32_t& mirror); +#endif + + bool update_caps_ = false; + void* va_display_ = nullptr; + std::vector filters_; + std::vector cb_elements_; + std::vector sharp_; + std::vector deinterlace_; + std::map colorbalance_caps_; + + std::vector pipeline_buffers; + + HwcFilterCap sharp_caps_; + HwcDeinterlaceCap deinterlace_caps_; + int render_target_format_ = VA_RT_FORMAT_YUV420; + VAContextID va_context_ = VA_INVALID_ID; + VAConfigID va_config_ = VA_INVALID_ID; + + VASurfaceID va_surface_in_ = VA_INVALID_ID; + VASurfaceID va_surface_out_ = VA_INVALID_ID; + + mutable pthread_mutex_t lock_; + + int64_t modifier_bak = -1; + std::vector native_handles; + std::vector native_rotation_handles; + std::vector native_active_handles; + int current_handle_position = 0; + + std::unique_ptr buffer_handler_; +}; + +} // namespace hwcomposer +#endif // COMMON_COMPOSITOR_VA_VARENDERER_H_ diff --git a/vautils.cpp b/vautils.cpp new file mode 100755 index 000000000..96ff51670 --- /dev/null +++ b/vautils.cpp @@ -0,0 +1,303 @@ +/* +// Copyright (c) 2017 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 "vautils.h" + +#include + +#include +#include +//#include +#include + + +//#include "platformdefines.h" + +namespace android { + +enum { HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL = 0x100, + HAL_PIXEL_FORMAT_NV12_LINEAR_INTEL = 0x101, + HAL_PIXEL_FORMAT_YCrCb_422_H_INTEL = 0x102, + HAL_PIXEL_FORMAT_NV12_LINEAR_PACKED_INTEL = 0x103, + HAL_PIXEL_FORMAT_YCbCr_422_H_INTEL = 0x104, + HAL_PIXEL_FORMAT_NV12_X_TILED_INTEL = 0x105, + HAL_PIXEL_FORMAT_RGBA_5551_INTEL = 0x106, + HAL_PIXEL_FORMAT_RGBA_4444_INTEL = 0x107, + HAL_PIXEL_FORMAT_GENERIC_8BIT_INTEL = 0x108, + HAL_PIXEL_FORMAT_YCbCr_411_INTEL = 0x109, + HAL_PIXEL_FORMAT_YCbCr_420_H_INTEL = 0x10A, + HAL_PIXEL_FORMAT_YCbCr_422_V_INTEL = 0x10B, + HAL_PIXEL_FORMAT_YCbCr_444_INTEL = 0x10C, + HAL_PIXEL_FORMAT_RGBP_INTEL = 0x10D, + HAL_PIXEL_FORMAT_BGRP_INTEL = 0x10E, + HAL_PIXEL_FORMAT_NV12_LINEAR_CAMERA_INTEL = 0x10F, + HAL_PIXEL_FORMAT_P010_INTEL = 0x110, + HAL_PIXEL_FORMAT_Z16_INTEL = 0x111, + HAL_PIXEL_FORMAT_UVMAP64_INTEL = 0x112, + HAL_PIXEL_FORMAT_A2R10G10B10_INTEL = 0x113, + HAL_PIXEL_FORMAT_A2B10G10R10_INTEL = 0x114, + HAL_PIXEL_FORMAT_YCrCb_NORMAL_INTEL = 0x115, + HAL_PIXEL_FORMAT_YCrCb_SWAPUVY_INTEL = 0x116, + HAL_PIXEL_FORMAT_YCrCb_SWAPUV_INTEL = 0x117, + HAL_PIXEL_FORMAT_YCrCb_SWAPY_INTEL = 0x118, + HAL_PIXEL_FORMAT_X2R10G10B10_INTEL = 0x119, + HAL_PIXEL_FORMAT_X2B10G10R10_INTEL = 0x11A, + HAL_PIXEL_FORMAT_P016_INTEL = 0x11C, + HAL_PIXEL_FORMAT_Y210_INTEL = 0x11D, + HAL_PIXEL_FORMAT_Y216_INTEL = 0x11E, + HAL_PIXEL_FORMAT_Y410_INTEL = 0x11F, + HAL_PIXEL_FORMAT_Y416_INTEL = 0x120, + HAL_PIXEL_FORMAT_Y8I_INTEL = 0x121, + HAL_PIXEL_FORMAT_Y12I_INTEL = 0x122, + HAL_PIXEL_FORMAT_YUYV_INTEL = HAL_PIXEL_FORMAT_YCrCb_NORMAL_INTEL, + HAL_PIXEL_FORMAT_YUY2_INTEL = HAL_PIXEL_FORMAT_YCrCb_NORMAL_INTEL, + HAL_PIXEL_FORMAT_VYUY_INTEL = HAL_PIXEL_FORMAT_YCrCb_SWAPUVY_INTEL, + HAL_PIXEL_FORMAT_YVYU_INTEL = HAL_PIXEL_FORMAT_YCrCb_SWAPUV_INTEL, + HAL_PIXEL_FORMAT_UYVY_INTEL = HAL_PIXEL_FORMAT_YCrCb_SWAPY_INTEL, + HAL_PIXEL_FORMAT_NV12_TILED_INTEL = HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL, + HAL_PIXEL_FORMAT_NV12_INTEL = HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL, + HAL_PIXEL_FORMAT_INTEL_NV12 = HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL, + HAL_PIXEL_FORMAT_NV12 = 0x10F, + HAL_PIXEL_FORMAT_YUV420PackedSemiPlanar_INTEL = 0x7FA00E00, + HAL_PIXEL_FORMAT_YUV420PackedSemiPlanar_Tiled_INTEL = 0x7FA00F00, +}; + + +int DrmFormatToVAFormat(int format) { + ALOGE("############## in vautils.cpp %s,line %d format=0x%x\n",__FUNCTION__,__LINE__,format); + switch (format) { + case DRM_FORMAT_NV12: + return VA_FOURCC_NV12; + case DRM_FORMAT_YVU420: + return VA_FOURCC_YV12; + case DRM_FORMAT_YUV420: + return VA_FOURCC('I', '4', '2', '0'); + case DRM_FORMAT_YUV422: + return VA_FOURCC_YUY2; + case DRM_FORMAT_UYVY: + return VA_FOURCC_UYVY; + case DRM_FORMAT_YUYV: + return VA_FOURCC_YUY2; + case DRM_FORMAT_P010: + return VA_FOURCC_P010; + case DRM_FORMAT_ABGR8888: + return VA_FOURCC_RGBA; + case DRM_FORMAT_XBGR8888: + return VA_FOURCC_RGBX; + case DRM_FORMAT_RGBA8888: + return VA_FOURCC_BGRA; + case DRM_FORMAT_ARGB8888: + return VA_FOURCC_ABGR; + case DRM_FORMAT_YVYU: + case DRM_FORMAT_VYUY: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_AYUV: + default: + ALOGE("Unable to convert to VAFormat from format %x", format); + break; + } + return 0; +} + + bool IsSupportedMediaFormat(uint32_t format) { + ALOGE("#################### in vautils.cpp %s,line %d\n",__FUNCTION__,__LINE__); + switch (format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV16: + case DRM_FORMAT_P010: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_VYUY: + case DRM_FORMAT_AYUV: + case DRM_FORMAT_NV12_Y_TILED_INTEL: + case DRM_FORMAT_NV21: + case DRM_FORMAT_YVU420_ANDROID: + ALOGE("#################### in vautils.cpp %s,line %d\n",__FUNCTION__,__LINE__); + return true; + default: + break; + } + ALOGE("#################### in vautils.cpp %s,line %d\n",__FUNCTION__,__LINE__); + return false; +} + + +int DrmFormatToRTFormat(int format) { + /* ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_NV12); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_YVU420); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_YUV420); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_UYVY); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_YUYV); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_YVYU); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_VYUY); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_YUV422); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_YUV444); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_P010); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_ABGR8888); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_XBGR8888); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_ARGB8888); + ALOGE(" in vautils.cpp %s,line %d,DRM_FORMAT_NV12=%d\n",__FUNCTION__,__LINE__,DRM_FORMAT_RGBA8888);*/ + switch (format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_VYUY: + ALOGE(" in vautils.cpp %s,line %d\n",__FUNCTION__,__LINE__); + return VA_RT_FORMAT_YUV420; + case DRM_FORMAT_YUV422: + return VA_RT_FORMAT_YUV422; + case DRM_FORMAT_YUV444: + return VA_RT_FORMAT_YUV444; + case DRM_FORMAT_P010: + return VA_RT_FORMAT_YUV420_10BPP; + case DRM_FORMAT_ABGR8888: + ALOGE(" in vautils.cpp %s,line %d\n",__FUNCTION__,__LINE__); + return VA_RT_FORMAT_RGB32; + case DRM_FORMAT_XBGR8888: + ALOGE(" in vautils.cpp %s,line %d\n",__FUNCTION__,__LINE__); + return VA_RT_FORMAT_RGB32; + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_RGBA8888: + ALOGE(" in vautils.cpp %s,line %d\n",__FUNCTION__,__LINE__); + return VA_RT_FORMAT_RGB32; + default: + ALOGE("Unable to convert to RTFormat from format %x", format); + break; + } + return 0; +} + int DrmFormatToHALFormat(int format) { + switch (format) { + case DRM_FORMAT_BGRA8888: + return HAL_PIXEL_FORMAT_RGBA_8888; + case DRM_FORMAT_BGRX8888: + return HAL_PIXEL_FORMAT_RGBX_8888; + case DRM_FORMAT_BGR888: + return HAL_PIXEL_FORMAT_RGB_888; + case DRM_FORMAT_BGR565: + return HAL_PIXEL_FORMAT_RGB_565; + case DRM_FORMAT_ARGB8888: + return HAL_PIXEL_FORMAT_BGRA_8888; + case DRM_FORMAT_YVU420: + return HAL_PIXEL_FORMAT_YV12; + case DRM_FORMAT_R8: + return HAL_PIXEL_FORMAT_BLOB; + case DRM_FORMAT_GR88: + case DRM_FORMAT_R16: + return HAL_PIXEL_FORMAT_Y16; + case DRM_FORMAT_ABGR8888: + return HAL_PIXEL_FORMAT_RGBA_8888; + case DRM_FORMAT_RGB332: //('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */ + return 0; + case DRM_FORMAT_BGR233: //('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */ + return 0; + + case DRM_FORMAT_XRGB4444: + case DRM_FORMAT_XBGR4444: + case DRM_FORMAT_RGBX4444: + case DRM_FORMAT_BGRX4444: + case DRM_FORMAT_ARGB4444: + case DRM_FORMAT_ABGR4444: + case DRM_FORMAT_RGBA4444: + case DRM_FORMAT_BGRA4444: + return 0; + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XBGR1555: + case DRM_FORMAT_RGBX5551: + case DRM_FORMAT_BGRX5551: + case DRM_FORMAT_ARGB1555: + case DRM_FORMAT_ABGR1555: + case DRM_FORMAT_RGBA5551: + case DRM_FORMAT_BGRA5551: + return 0; + case DRM_FORMAT_RGB565: + return HAL_PIXEL_FORMAT_RGB_565; + case DRM_FORMAT_RGB888: + return HAL_PIXEL_FORMAT_RGB_888; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_RGBX8888: + case DRM_FORMAT_RGBA8888: + ALOGE("in vatuils.cpp %s,line %d \n",__FUNCTION__,__LINE__); + return 0; + case DRM_FORMAT_ABGR2101010: + return HAL_PIXEL_FORMAT_RGBA_1010102; + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_RGBX1010102: + case DRM_FORMAT_BGRX1010102: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_RGBA1010102: + case DRM_FORMAT_BGRA1010102: + return 0; + case DRM_FORMAT_YUYV: + return HAL_PIXEL_FORMAT_YCbCr_422_I; + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + case DRM_FORMAT_AYUV: + ALOGE("YUV format using RGB buffer \n"); + return 0; + case DRM_FORMAT_NV12: + return HAL_PIXEL_FORMAT_NV12; + case DRM_FORMAT_NV21: + return HAL_PIXEL_FORMAT_YCrCb_420_SP; + case DRM_FORMAT_NV16: + return HAL_PIXEL_FORMAT_YCbCr_422_SP; + case DRM_FORMAT_NV61: + case DRM_FORMAT_YUV410: + case DRM_FORMAT_YVU410: + case DRM_FORMAT_YUV411: + case DRM_FORMAT_YVU411: + ALOGE("YUV format using RGB buffer \n"); + return 0; + case DRM_FORMAT_YUV420: + return HAL_PIXEL_FORMAT_YCbCr_420_888; + case DRM_FORMAT_YVU420_ANDROID: + return HAL_PIXEL_FORMAT_YV12; + case DRM_FORMAT_YUV422: + return HAL_PIXEL_FORMAT_YCbCr_422_888; + case DRM_FORMAT_YVU422: + ALOGE("YUV format using RGB buffer \n"); + return 0; + case DRM_FORMAT_YUV444: + return HAL_PIXEL_FORMAT_YCbCr_444_888; + case DRM_FORMAT_YVU444: + ALOGE("YUV format using RGB buffer \n"); + return 0; + case DRM_FORMAT_NV12_Y_TILED_INTEL: + return HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL; + case DRM_FORMAT_P010: + return HAL_PIXEL_FORMAT_P010_INTEL; + // case DRM_FORMAT_XBGR161616: + // return HAL_PIXEL_FORMAT_RGBA_FP16; + default: + return 0; + break; + } + + return DRM_FORMAT_NONE; +} + +} // namespace hwcomposer diff --git a/vautils.h b/vautils.h new file mode 100755 index 000000000..c693de288 --- /dev/null +++ b/vautils.h @@ -0,0 +1,43 @@ +/* +// Copyright (c) 2016 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. +*/ + +#ifndef COMMON_DRM_COMPOSITOR_VA_VAUTILS_H_ +#define COMMON_DRM_COMPOSITOR_VA_VAUTILS_H_ +#include +#include + +namespace android { +#define DRM_FORMAT_NONE fourcc_code('0', '0', '0', '0') +#define DRM_FORMAT_YVU420_ANDROID fourcc_code('9', '9', '9', '7') +#define DRM_FORMAT_NV12_Y_TILED_INTEL fourcc_code('9', '9', '9', '6') +#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') /* 2x2 subsampled Cr:Cb plane 10 bits per channel */ + +struct gralloc_handle { + buffer_handle_t handle_ = NULL; + uint64_t gralloc1_buffer_descriptor_t_ = 0; +}; + +typedef struct gralloc_handle* DRMHwcNativeHandle; + + +int DrmFormatToVAFormat(int format); +int DrmFormatToRTFormat(int format); +int DrmFormatToHALFormat(int format) ; +bool IsSupportedMediaFormat(uint32_t format); + +} // namespace hwcomposer + +#endif // COMMON_COMPOSITOR_VA_VAUTILS_H_ From c04d7caf921dcb93aec689ce473ade237b26a7a6 Mon Sep 17 00:00:00 2001 From: bozhengx Date: Fri, 27 Dec 2019 14:22:06 +0800 Subject: [PATCH 2/2] add libva support Signed-off-by: bozhengx --- drmdisplaycompositor.cpp | 18 +++++++++--------- drmhwcomposer.h | 17 ++++++++++------- drmhwctwo.cpp | 14 +++++++++----- varenderer.cpp | 10 ++++++---- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp index 0e9bf1710..65150d63c 100755 --- a/drmdisplaycompositor.cpp +++ b/drmdisplaycompositor.cpp @@ -383,15 +383,15 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, rotation |= DRM_MODE_REFLECT_Y; if (layer.IsVideoLayer()) { rotation |= DRM_MODE_ROTATE_0; - source_crop.left = 0; - source_crop.top = 0; - source_crop.bottom = 1080; - source_crop.right = 1920; - - display_frame.left = 0; - display_frame.top = 0; - display_frame.bottom = 1080; - display_frame.right = 1920; + source_crop.left = layer.source_crop.left; + source_crop.top = layer.source_crop.top; + source_crop.bottom = layer.source_crop.bottom; + source_crop.right = layer.source_crop.right; + + display_frame.left = layer.display_frame.left; + display_frame.top = layer.display_frame.top; + display_frame.bottom = layer.display_frame.bottom; + display_frame.right = layer.display_frame.right; }else{ if (layer.transform & DrmHwcTransform::kRotate90) rotation |= DRM_MODE_ROTATE_90; diff --git a/drmhwcomposer.h b/drmhwcomposer.h index db6a2ef6d..b275a9e8d 100755 --- a/drmhwcomposer.h +++ b/drmhwcomposer.h @@ -141,7 +141,6 @@ enum class DrmHwcBlending : int32_t { struct DrmHwcLayer { buffer_handle_t sf_handle = NULL; - std::map> va_z_map; int gralloc_buffer_usage = 0; DrmHwcBuffer buffer; DrmHwcNativeHandle handle; @@ -155,12 +154,6 @@ struct DrmHwcLayer { android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN; UniqueFd acquire_fence; OutputFd release_fence; - void addVaLayerMapData(int zorder, DrmHwcLayer* layer){ - va_z_map.emplace(std::make_pair(zorder, layer)); - } - std::map> getVaLayerMapData(){ - return va_z_map; - } int ImportBuffer(Importer *importer); int InitFromDrmHwcLayer(DrmHwcLayer *layer, Importer *importer); @@ -189,6 +182,16 @@ struct DrmHwcLayer { } }; +struct DrmVaComposeHwcLayer : DrmHwcLayer{ + std::map> va_z_map; + void addVaLayerMapData(int zorder, DrmHwcLayer* layer){ + va_z_map.emplace(std::make_pair(zorder, layer)); + } + std::map> getVaLayerMapData(){ + return va_z_map; + } +}; + struct DrmHwcDisplayContents { OutputFd retire_fence; std::vector layers; diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp index 6292dfc0d..536e81a00 100755 --- a/drmhwctwo.cpp +++ b/drmhwctwo.cpp @@ -548,17 +548,21 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) { if(includeVideoFlag && (!use_client_layer)){ for (std::pair &l : z_map) { if (l.second->IsVideoLayer()) { - DrmHwcLayer layer; + DrmVaComposeHwcLayer va_compose_layer; + DrmHwcLayer clientlayer; DrmHwcLayer layera[z_map.size()]; - l.second->PopulateDrmLayer(&layer); + l.second->PopulateDrmLayer(&va_compose_layer); + client_layer_.PopulateDrmLayer(&clientlayer); + va_compose_layer.SetDisplayFrame(clientlayer.display_frame); + va_compose_layer.SetSourceCrop(clientlayer.source_crop); int index =0; for (std::pair &a : z_map) { a.second->PopulateDrmLayer(&layera[index]); - layer.addVaLayerMapData(a.first, &layera[index]); + va_compose_layer.addVaLayerMapData(a.first, &layera[index]); index++; } - ret = layer.ImportBuffer(importer_.get()); - map.layers.emplace_back(std::move(layer)); + ret = va_compose_layer.ImportBuffer(importer_.get()); + map.layers.emplace_back(std::move(va_compose_layer)); break; } } diff --git a/varenderer.cpp b/varenderer.cpp index bf951f876..427cc87ea 100755 --- a/varenderer.cpp +++ b/varenderer.cpp @@ -276,9 +276,11 @@ bool VARenderer::startRender(DrmHwcLayer* layer,uint32_t format){ bool modifer_succeeded = false; DRMHwcNativeHandle temp_handle = 0; uint32_t input_layer_numer = 1; - std::map> va_layer_map = layer->getVaLayerMapData(); + std::map> va_layer_map = ((DrmVaComposeHwcLayer *)layer)->getVaLayerMapData(); input_layer_numer = va_layer_map.size(); //format = DRM_FORMAT_ABGR8888; + int connector_widht = layer->display_frame.right - layer->display_frame.left; + int connector_height = layer->display_frame.bottom - layer->display_frame.top; int rt_format = DrmFormatToRTFormat(format); if(render_target_format_ != rt_format) render_target_format_ = rt_format; @@ -296,7 +298,7 @@ bool VARenderer::startRender(DrmHwcLayer* layer,uint32_t format){ return false; } for( int32_t i=0; iCreateBuffer(/*gr_handle->width, gr_handle->height,*/1920,1080,format,//2560*1440 + buffer_handler_->CreateBuffer(connector_widht,connector_height,format,//2560*1440 &temp_handle,usage,&modifer_succeeded,modifier); if (modifier == 0) { native_handles.push_back(temp_handle); @@ -313,7 +315,7 @@ bool VARenderer::startRender(DrmHwcLayer* layer,uint32_t format){ if (modifier == I915_FORMAT_MOD_Y_TILED) { if (native_rotation_handles.size() == 0) { for( int32_t i=0; iCreateBuffer(/*gr_handle->width, gr_handle->height,*/1920,1080,format, + buffer_handler_->CreateBuffer(connector_widht,connector_height,format, &temp_handle,usage,&modifer_succeeded,modifier); native_rotation_handles.push_back(temp_handle); } @@ -323,7 +325,7 @@ bool VARenderer::startRender(DrmHwcLayer* layer,uint32_t format){ } else { if (native_handles.size() == 0) { for( int32_t i=0; iCreateBuffer(/*gr_handle->width, gr_handle->height,*/1920,1080,format,//2560*1440 + buffer_handler_->CreateBuffer(connector_widht,connector_height,format,//2560*1440 &temp_handle,usage,&modifer_succeeded,modifier); native_handles.push_back(temp_handle); }