aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2020-11-05 17:20:49 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-11-05 17:20:49 +0000
commitb13b51996b42f126d5c6415380d4718b1455c3de (patch)
tree514de253f25c3f7893ca7bcecfbc5b11bf147c3a
parent709de7f5f7f0c7724588798f5ca24882b22c2f6b (diff)
parent713247a2723f1a624e47b791141034281b313298 (diff)
downloaddrm_hwcomposer-b13b51996b42f126d5c6415380d4718b1455c3de.tar.gz
Merge remote-tracking branch 'aosp/upstream-main' into HEAD am: c707da598c am: 713247a272
Original change: https://android-review.googlesource.com/c/platform/external/drm_hwcomposer/+/1485140 Change-Id: I5a29c530aecb3eaa908e7d43e1ef6b2a6e0f5aba
-rw-r--r--Android.bp36
-rw-r--r--DrmHwcTwo.cpp87
-rw-r--r--DrmHwcTwo.h27
-rw-r--r--backend/Backend.cpp3
-rw-r--r--backend/BackendRCarDu.cpp4
-rw-r--r--bufferinfo/BufferInfoGetter.cpp118
-rw-r--r--bufferinfo/BufferInfoGetter.h76
-rw-r--r--bufferinfo/BufferInfoMapperMetadata.cpp146
-rw-r--r--bufferinfo/BufferInfoMapperMetadata.h36
-rw-r--r--bufferinfo/legacy/BufferInfoImagination.cpp (renamed from platform/platformimagination.cpp)39
-rw-r--r--bufferinfo/legacy/BufferInfoImagination.h34
-rw-r--r--bufferinfo/legacy/BufferInfoLibdrm.cpp (renamed from platform/platformdrmgeneric.cpp)210
-rw-r--r--bufferinfo/legacy/BufferInfoLibdrm.h37
-rw-r--r--bufferinfo/legacy/BufferInfoMaliHisi.cpp (renamed from platform/platformhisi.cpp)57
-rw-r--r--bufferinfo/legacy/BufferInfoMaliHisi.h (renamed from platform/platformhisi.h)19
-rw-r--r--bufferinfo/legacy/BufferInfoMaliMediatek.cpp (renamed from platform/platformmediatek.cpp)23
-rw-r--r--bufferinfo/legacy/BufferInfoMaliMediatek.h (renamed from platform/platformmediatek.h)12
-rw-r--r--bufferinfo/legacy/BufferInfoMaliMeson.cpp (renamed from platform/platformmeson.cpp)32
-rw-r--r--bufferinfo/legacy/BufferInfoMaliMeson.h (renamed from platform/platformmeson.h)16
-rw-r--r--bufferinfo/legacy/BufferInfoMinigbm.cpp (renamed from platform/platformminigbm.cpp)25
-rw-r--r--bufferinfo/legacy/BufferInfoMinigbm.h (renamed from platform/platformminigbm.h)13
-rw-r--r--compositor/DrmDisplayComposition.cpp2
-rw-r--r--compositor/DrmDisplayCompositor.cpp6
-rw-r--r--compositor/DrmDisplayCompositor.h13
-rw-r--r--compositor/Planner.cpp (renamed from platform/platform.cpp)8
-rw-r--r--compositor/Planner.h (renamed from platform/platform.h)27
-rw-r--r--drm/DrmDevice.cpp1
-rw-r--r--drm/DrmDevice.h2
-rw-r--r--drm/DrmGenericImporter.cpp137
-rw-r--r--drm/DrmGenericImporter.h (renamed from platform/platformdrmgeneric.h)37
-rw-r--r--drm/ResourceManager.cpp9
-rw-r--r--drm/ResourceManager.h2
-rw-r--r--drm/VSyncWorker.cpp42
-rw-r--r--drm/VSyncWorker.h6
-rw-r--r--include/drmhwcgralloc.h1
-rw-r--r--include/drmhwcomposer.h3
-rw-r--r--platform/platformimagination.h21
-rw-r--r--utils/hwcutils.cpp42
38 files changed, 844 insertions, 565 deletions
diff --git a/Android.bp b/Android.bp
index fef3ed6..20b22ce 100644
--- a/Android.bp
+++ b/Android.bp
@@ -44,6 +44,7 @@ cc_defaults {
"libcutils",
"libdrm",
"libhardware",
+ "libhidlbase",
"liblog",
"libsync",
"libui",
@@ -82,22 +83,25 @@ cc_library_static {
srcs: [
"DrmHwcTwo.cpp",
+ "bufferinfo/BufferInfoGetter.cpp",
+ "bufferinfo/BufferInfoMapperMetadata.cpp",
+
"compositor/DrmDisplayComposition.cpp",
"compositor/DrmDisplayCompositor.cpp",
+ "compositor/Planner.cpp",
"drm/DrmConnector.cpp",
"drm/DrmCrtc.cpp",
"drm/DrmDevice.cpp",
"drm/DrmEncoder.cpp",
"drm/DrmEventListener.cpp",
+ "drm/DrmGenericImporter.cpp",
"drm/DrmMode.cpp",
"drm/DrmPlane.cpp",
"drm/DrmProperty.cpp",
"drm/ResourceManager.cpp",
"drm/VSyncWorker.cpp",
- "platform/platform.cpp",
-
"utils/autolock.cpp",
"utils/hwcutils.cpp",
@@ -112,53 +116,37 @@ cc_library_shared {
name: "hwcomposer.drm",
defaults: ["hwcomposer.drm_defaults"],
whole_static_libs: ["drm_hwcomposer"],
- srcs: ["platform/platformdrmgeneric.cpp"],
- cppflags: ["-DUSE_DRM_GENERIC_IMPORTER"],
+ srcs: ["bufferinfo/legacy/BufferInfoLibdrm.cpp"],
}
cc_library_shared {
name: "hwcomposer.drm_minigbm",
defaults: ["hwcomposer.drm_defaults"],
whole_static_libs: ["drm_hwcomposer"],
- srcs: [
- "platform/platformdrmgeneric.cpp",
- "platform/platformminigbm.cpp",
- ],
+ srcs: ["bufferinfo/legacy/BufferInfoMinigbm.cpp"],
include_dirs: ["external/minigbm/cros_gralloc"],
}
// Used by hwcomposer.drm_imagination
filegroup {
name: "drm_hwcomposer_platformimagination",
- srcs: [
- "platform/platformdrmgeneric.cpp",
- "platform/platformimagination.cpp",
- ],
+ srcs: ["bufferinfo/legacy/BufferInfoImagination.cpp"],
}
// Used by hwcomposer.drm_hikey and hwcomposer.drm_hikey960
filegroup {
name: "drm_hwcomposer_platformhisi",
- srcs: [
- "platform/platformdrmgeneric.cpp",
- "platform/platformhisi.cpp",
- ],
+ srcs: ["bufferinfo/legacy/BufferInfoMaliHisi.cpp"],
}
// Used by hwcomposer.drm_meson
filegroup {
name: "drm_hwcomposer_platformmeson",
- srcs: [
- "platform/platformdrmgeneric.cpp",
- "platform/platformmeson.cpp",
- ],
+ srcs: ["bufferinfo/legacy/BufferInfoMaliMeson.cpp"],
}
// Used by hwcomposer.drm_mediatek
filegroup {
name: "drm_hwcomposer_platformmediatek",
- srcs: [
- "platform/platformdrmgeneric.cpp",
- "platform/platformmediatek.cpp",
- ],
+ srcs: ["bufferinfo/legacy/BufferInfoMaliMediatek.cpp"],
}
diff --git a/DrmHwcTwo.cpp b/DrmHwcTwo.cpp
index 65a317c..93b6fa7 100644
--- a/DrmHwcTwo.cpp
+++ b/DrmHwcTwo.cpp
@@ -28,26 +28,11 @@
#include <string>
#include "backend/BackendManager.h"
+#include "bufferinfo/BufferInfoGetter.h"
#include "compositor/DrmDisplayComposition.h"
namespace android {
-class DrmVsyncCallback : public VsyncCallback {
- public:
- DrmVsyncCallback(hwc2_callback_data_t data, hwc2_function_pointer_t hook)
- : data_(data), hook_(hook) {
- }
-
- void Callback(int display, int64_t timestamp) {
- auto hook = reinterpret_cast<HWC2_PFN_VSYNC>(hook_);
- hook(data_, display, timestamp);
- }
-
- private:
- hwc2_callback_data_t data_;
- hwc2_function_pointer_t hook_;
-};
-
DrmHwcTwo::DrmHwcTwo() {
common.tag = HARDWARE_DEVICE_TAG;
common.version = HWC_DEVICE_API_VERSION_2_0;
@@ -194,17 +179,10 @@ HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
hwc2_callback_data_t data,
hwc2_function_pointer_t function) {
supported(__func__);
- auto callback = static_cast<HWC2::Callback>(descriptor);
-
- if (!function) {
- callbacks_.erase(callback);
- return HWC2::Error::None;
- }
- callbacks_.emplace(callback, HwcCallback(data, function));
-
- switch (callback) {
+ switch (static_cast<HWC2::Callback>(descriptor)) {
case HWC2::Callback::Hotplug: {
+ SetHotplugCallback(data, function);
auto &drmDevices = resource_manager_.getDrmDevices();
for (auto &device : drmDevices)
HandleInitialHotplugState(device.get());
@@ -317,21 +295,16 @@ HWC2::Error DrmHwcTwo::HwcDisplay::ChosePreferredConfig() {
return SetActiveConfig(connector_->get_preferred_mode_id());
}
-HWC2::Error DrmHwcTwo::HwcDisplay::RegisterVsyncCallback(
+void DrmHwcTwo::HwcDisplay::RegisterVsyncCallback(
hwc2_callback_data_t data, hwc2_function_pointer_t func) {
supported(__func__);
- auto callback = std::make_shared<DrmVsyncCallback>(data, func);
- vsync_worker_.RegisterCallback(std::move(callback));
- return HWC2::Error::None;
+ vsync_worker_.RegisterClientCallback(data, func);
}
void DrmHwcTwo::HwcDisplay::RegisterRefreshCallback(
hwc2_callback_data_t data, hwc2_function_pointer_t func) {
supported(__func__);
- auto hook = reinterpret_cast<HWC2_PFN_REFRESH>(func);
- compositor_.SetRefreshCallback([data, hook](int display) {
- hook(data, static_cast<hwc2_display_t>(display));
- });
+ compositor_.SetRefreshCallback(data, func);
}
HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() {
@@ -785,11 +758,6 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
.right = static_cast<int>(mode->h_display()),
.bottom = static_cast<int>(mode->v_display())};
client_layer_.SetLayerDisplayFrame(display_frame);
- hwc_frect_t source_crop = {.left = 0.0f,
- .top = 0.0f,
- .right = mode->h_display() + 0.0f,
- .bottom = mode->v_display() + 0.0f};
- client_layer_.SetLayerSourceCrop(source_crop);
return HWC2::Error::None;
}
@@ -804,15 +772,30 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target,
client_layer_.set_buffer(target);
client_layer_.set_acquire_fence(uf.get());
client_layer_.SetLayerDataspace(dataspace);
+
+ /* TODO: Do not update source_crop every call.
+ * It makes sense to do it once after every hotplug event. */
+ hwc_drm_bo bo{};
+ BufferInfoGetter::GetInstance()->ConvertBoInfo(target, &bo);
+
+ hwc_frect_t source_crop = {.left = 0.0f,
+ .top = 0.0f,
+ .right = bo.width + 0.0f,
+ .bottom = bo.height + 0.0f};
+ client_layer_.SetLayerSourceCrop(source_crop);
+
return HWC2::Error::None;
}
HWC2::Error DrmHwcTwo::HwcDisplay::SetColorMode(int32_t mode) {
supported(__func__);
- if (mode != HAL_COLOR_MODE_NATIVE)
+ if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
return HWC2::Error::BadParameter;
+ if (mode != HAL_COLOR_MODE_NATIVE)
+ return HWC2::Error::Unsupported;
+
color_mode_ = mode;
return HWC2::Error::None;
}
@@ -978,10 +961,19 @@ HWC2::Error DrmHwcTwo::HwcDisplay::GetRenderIntents(
HWC2::Error DrmHwcTwo::HwcDisplay::SetColorModeWithIntent(int32_t mode,
int32_t intent) {
- if (mode != HAL_COLOR_MODE_NATIVE)
+ if (intent < HAL_RENDER_INTENT_COLORIMETRIC ||
+ intent > HAL_RENDER_INTENT_TONE_MAP_ENHANCE)
return HWC2::Error::BadParameter;
- if (intent != HAL_RENDER_INTENT_COLORIMETRIC)
+
+ if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
return HWC2::Error::BadParameter;
+
+ if (mode != HAL_COLOR_MODE_NATIVE)
+ return HWC2::Error::Unsupported;
+
+ if (intent != HAL_RENDER_INTENT_COLORIMETRIC)
+ return HWC2::Error::Unsupported;
+
color_mode_ = mode;
return HWC2::Error::None;
}
@@ -1110,14 +1102,13 @@ void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
}
void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) {
- auto cb = callbacks_.find(HWC2::Callback::Hotplug);
- if (cb == callbacks_.end())
- return;
+ const std::lock_guard<std::mutex> lock(hotplug_callback_lock);
- auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(cb->second.func);
- hotplug(cb->second.data, displayid,
- (state == DRM_MODE_CONNECTED ? HWC2_CONNECTION_CONNECTED
- : HWC2_CONNECTION_DISCONNECTED));
+ if (hotplug_callback_hook_ && hotplug_callback_data_)
+ hotplug_callback_hook_(hotplug_callback_data_, displayid,
+ state == DRM_MODE_CONNECTED
+ ? HWC2_CONNECTION_CONNECTED
+ : HWC2_CONNECTION_DISCONNECTED);
}
void DrmHwcTwo::HandleInitialHotplugState(DrmDevice *drmDevice) {
diff --git a/DrmHwcTwo.h b/DrmHwcTwo.h
index ca7a00b..d489113 100644
--- a/DrmHwcTwo.h
+++ b/DrmHwcTwo.h
@@ -24,10 +24,11 @@
#include <map>
#include "compositor/DrmDisplayCompositor.h"
+#include "compositor/Planner.h"
+#include "drm/DrmGenericImporter.h"
#include "drm/ResourceManager.h"
#include "drm/VSyncWorker.h"
#include "drmhwcomposer.h"
-#include "platform/platform.h"
namespace android {
@@ -42,6 +43,17 @@ class DrmHwcTwo : public hwc2_device_t {
HWC2::Error Init();
+ hwc2_callback_data_t hotplug_callback_data_ = NULL;
+ HWC2_PFN_HOTPLUG hotplug_callback_hook_ = NULL;
+ std::mutex hotplug_callback_lock;
+
+ void SetHotplugCallback(hwc2_callback_data_t data,
+ hwc2_function_pointer_t hook) {
+ const std::lock_guard<std::mutex> lock(hotplug_callback_lock);
+ hotplug_callback_data_ = data;
+ hotplug_callback_hook_ = reinterpret_cast<HWC2_PFN_HOTPLUG>(hook);
+ }
+
class HwcLayer {
public:
HWC2::Composition sf_type() const {
@@ -149,14 +161,6 @@ class DrmHwcTwo : public hwc2_device_t {
android_dataspace_t dataspace_ = HAL_DATASPACE_UNKNOWN;
};
- struct HwcCallback {
- HwcCallback(hwc2_callback_data_t d, hwc2_function_pointer_t f)
- : data(d), func(f) {
- }
- hwc2_callback_data_t data;
- hwc2_function_pointer_t func;
- };
-
class HwcDisplay {
public:
HwcDisplay(ResourceManager *resource_manager, DrmDevice *drm,
@@ -165,8 +169,8 @@ class DrmHwcTwo : public hwc2_device_t {
HwcDisplay(const HwcDisplay &) = delete;
HWC2::Error Init(std::vector<DrmPlane *> *planes);
- HWC2::Error RegisterVsyncCallback(hwc2_callback_data_t data,
- hwc2_function_pointer_t func);
+ void RegisterVsyncCallback(hwc2_callback_data_t data,
+ hwc2_function_pointer_t func);
void RegisterRefreshCallback(hwc2_callback_data_t data,
hwc2_function_pointer_t func);
HWC2::Error CreateComposition(bool test);
@@ -422,7 +426,6 @@ class DrmHwcTwo : public hwc2_device_t {
ResourceManager resource_manager_;
std::map<hwc2_display_t, HwcDisplay> displays_;
- std::map<HWC2::Callback, HwcCallback> callbacks_;
std::string mDumpString;
};
diff --git a/backend/Backend.cpp b/backend/Backend.cpp
index 50ef900..887eb0e 100644
--- a/backend/Backend.cpp
+++ b/backend/Backend.cpp
@@ -17,6 +17,7 @@
#include "Backend.h"
#include "BackendManager.h"
+#include "bufferinfo/BufferInfoGetter.h"
namespace android {
@@ -125,7 +126,7 @@ std::tuple<int, int> Backend::GetClientLayers(
bool Backend::IsClientLayer(DrmHwcTwo::HwcDisplay *display,
DrmHwcTwo::HwcLayer *layer) {
return !display->HardwareSupportsLayerType(layer->sf_type()) ||
- !display->importer()->CanImportBuffer(layer->buffer()) ||
+ !BufferInfoGetter::GetInstance()->IsHandleUsable(layer->buffer()) ||
display->color_transform_hint() != HAL_COLOR_TRANSFORM_IDENTITY ||
(layer->RequireScalingOrPhasing() &&
display->resource_manager()->ForcedScalingWithGpu());
diff --git a/backend/BackendRCarDu.cpp b/backend/BackendRCarDu.cpp
index d52f0c3..e85fa71 100644
--- a/backend/BackendRCarDu.cpp
+++ b/backend/BackendRCarDu.cpp
@@ -17,6 +17,7 @@
#include "BackendRCarDu.h"
#include "BackendManager.h"
+#include "bufferinfo/BufferInfoGetter.h"
#include "drm_fourcc.h"
namespace android {
@@ -25,7 +26,8 @@ bool BackendRCarDu::IsClientLayer(DrmHwcTwo::HwcDisplay *display,
DrmHwcTwo::HwcLayer *layer) {
hwc_drm_bo_t bo;
- int ret = display->importer()->ConvertBoInfo(layer->buffer(), &bo);
+ int ret = BufferInfoGetter::GetInstance()->ConvertBoInfo(layer->buffer(),
+ &bo);
if (ret)
return true;
diff --git a/bufferinfo/BufferInfoGetter.cpp b/bufferinfo/BufferInfoGetter.cpp
new file mode 100644
index 0000000..afdc50e
--- /dev/null
+++ b/bufferinfo/BufferInfoGetter.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "hwc-buffer-info-getter"
+
+#include "BufferInfoGetter.h"
+
+#if PLATFORM_SDK_VERSION >= 30
+#include "BufferInfoMapperMetadata.h"
+#endif
+
+#include <cutils/properties.h>
+#include <gralloc_handle.h>
+#include <hardware/gralloc.h>
+#include <log/log.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+namespace android {
+
+BufferInfoGetter *BufferInfoGetter::GetInstance() {
+ static std::unique_ptr<BufferInfoGetter> inst;
+ if (inst == nullptr) {
+#if PLATFORM_SDK_VERSION >= 30
+ inst.reset(BufferInfoMapperMetadata::CreateInstance());
+ if (inst == nullptr) {
+ ALOGW(
+ "Generic buffer getter is not available. Falling back to legacy...");
+#endif
+ inst.reset(LegacyBufferInfoGetter::CreateInstance());
+#if PLATFORM_SDK_VERSION >= 30
+ }
+#endif
+ }
+
+ return inst.get();
+}
+
+bool BufferInfoGetter::IsHandleUsable(buffer_handle_t handle) {
+ hwc_drm_bo_t bo;
+ memset(&bo, 0, sizeof(hwc_drm_bo_t));
+
+ if (ConvertBoInfo(handle, &bo) != 0)
+ return false;
+
+ if (bo.prime_fds[0] == 0)
+ return false;
+
+ return true;
+}
+
+int LegacyBufferInfoGetter::Init() {
+ int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
+ (const hw_module_t **)&gralloc_);
+ if (ret) {
+ ALOGE("Failed to open gralloc module");
+ return ret;
+ }
+
+ ALOGI("Using %s gralloc module: %s\n", gralloc_->common.name,
+ gralloc_->common.author);
+
+ return 0;
+}
+
+uint32_t LegacyBufferInfoGetter::ConvertHalFormatToDrm(uint32_t hal_format) {
+ switch (hal_format) {
+ case HAL_PIXEL_FORMAT_RGB_888:
+ return DRM_FORMAT_BGR888;
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ return DRM_FORMAT_ARGB8888;
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ return DRM_FORMAT_XBGR8888;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return DRM_FORMAT_ABGR8888;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return DRM_FORMAT_BGR565;
+ case HAL_PIXEL_FORMAT_YV12:
+ return DRM_FORMAT_YVU420;
+ default:
+ ALOGE("Cannot convert hal format to drm format %u", hal_format);
+ return DRM_FORMAT_INVALID;
+ }
+}
+
+bool BufferInfoGetter::IsDrmFormatRgb(uint32_t drm_format) {
+ switch (drm_format) {
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_BGR888:
+ case DRM_FORMAT_BGR565:
+ return true;
+ default:
+ return false;
+ }
+}
+
+__attribute__((weak)) LegacyBufferInfoGetter *
+LegacyBufferInfoGetter::CreateInstance() {
+ ALOGE("No legacy buffer info getters available");
+ return nullptr;
+}
+
+} // namespace android
diff --git a/bufferinfo/BufferInfoGetter.h b/bufferinfo/BufferInfoGetter.h
new file mode 100644
index 0000000..fad3d16
--- /dev/null
+++ b/bufferinfo/BufferInfoGetter.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2020 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 ANDROID_BUFFERINFOGETTER_H_
+#define ANDROID_BUFFERINFOGETTER_H_
+
+#include <drm/drm_fourcc.h>
+#include <hardware/gralloc.h>
+
+#include "drm/DrmDevice.h"
+#include "drmhwcgralloc.h"
+
+#ifndef DRM_FORMAT_INVALID
+#define DRM_FORMAT_INVALID 0
+#endif
+
+namespace android {
+
+class BufferInfoGetter {
+ public:
+ virtual ~BufferInfoGetter() {
+ }
+
+ virtual int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) = 0;
+
+ bool IsHandleUsable(buffer_handle_t handle);
+
+ static BufferInfoGetter *GetInstance();
+
+ static bool IsDrmFormatRgb(uint32_t drm_format);
+};
+
+class LegacyBufferInfoGetter : public BufferInfoGetter {
+ public:
+ using BufferInfoGetter::BufferInfoGetter;
+
+ int Init();
+
+ int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override = 0;
+
+ static LegacyBufferInfoGetter *CreateInstance();
+
+ static uint32_t ConvertHalFormatToDrm(uint32_t hal_format);
+ const gralloc_module_t *gralloc_;
+};
+
+#define LEGACY_BUFFER_INFO_GETTER(getter_) \
+ LegacyBufferInfoGetter *LegacyBufferInfoGetter::CreateInstance() { \
+ auto *instance = new getter_(); \
+ if (!instance) \
+ return NULL; \
+ \
+ int ret = instance->Init(); \
+ if (ret) { \
+ ALOGE("Failed to initialize the " #getter_ " getter %d", ret); \
+ delete instance; \
+ return NULL; \
+ } \
+ return instance; \
+ }
+
+} // namespace android
+#endif
diff --git a/bufferinfo/BufferInfoMapperMetadata.cpp b/bufferinfo/BufferInfoMapperMetadata.cpp
new file mode 100644
index 0000000..3aabeb5
--- /dev/null
+++ b/bufferinfo/BufferInfoMapperMetadata.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#if PLATFORM_SDK_VERSION >= 30
+
+#define LOG_TAG "hwc-bufferinfo-mappermetadata"
+
+#include "BufferInfoMapperMetadata.h"
+
+#include <drm/drm_fourcc.h>
+#include <inttypes.h>
+#include <log/log.h>
+#include <ui/GraphicBufferMapper.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+using android::hardware::graphics::common::V1_1::BufferUsage;
+
+namespace android {
+
+BufferInfoGetter *BufferInfoMapperMetadata::CreateInstance() {
+ if (GraphicBufferMapper::getInstance().getMapperVersion() <
+ GraphicBufferMapper::GRALLOC_4)
+ return nullptr;
+
+ return new BufferInfoMapperMetadata();
+}
+
+/* The implementation below makes assumptions on the order and number of file
+ * descriptors that Gralloc places in the native_handle_t and as such it very
+ * likely needs to be adapted to match the particular Gralloc implementation
+ * used in the system. For this reason it is been declared as a weak symbol,
+ * so that it can be overridden.
+ */
+int __attribute__((weak))
+BufferInfoMapperMetadata::GetFds(buffer_handle_t handle, hwc_drm_bo_t *bo) {
+ int num_fds = handle->numFds;
+
+ if (num_fds >= 1 && num_fds <= 2) {
+ if (IsDrmFormatRgb(bo->format)) {
+ bo->prime_fds[0] = handle->data[0];
+ } else {
+ bo->prime_fds[0] = bo->prime_fds[1] = bo->prime_fds[2] = handle->data[0];
+ }
+ if (bo->prime_fds[0] <= 0) {
+ ALOGE("Encountered invalid fd %d", bo->prime_fds[0]);
+ return android::BAD_VALUE;
+ }
+
+ } else if (num_fds >= 3) {
+ bo->prime_fds[0] = handle->data[0];
+ bo->prime_fds[1] = handle->data[1];
+ bo->prime_fds[2] = handle->data[2];
+ for (int i = 0; i < 3; i++) {
+ if (bo->prime_fds[i] <= 0) {
+ ALOGE("Encountered invalid fd %d", bo->prime_fds[i]);
+ return android::BAD_VALUE;
+ }
+ }
+ }
+ return 0;
+}
+
+int BufferInfoMapperMetadata::ConvertBoInfo(buffer_handle_t handle,
+ hwc_drm_bo_t *bo) {
+ GraphicBufferMapper &mapper = GraphicBufferMapper::getInstance();
+ if (!handle)
+ return -EINVAL;
+
+ uint64_t usage = 0;
+ int err = mapper.getUsage(handle, &usage);
+ if (err) {
+ ALOGE("Failed to get usage err=%d", err);
+ return err;
+ }
+ bo->usage = static_cast<uint32_t>(usage);
+
+ ui::PixelFormat hal_format;
+ err = mapper.getPixelFormatRequested(handle, &hal_format);
+ if (err) {
+ ALOGE("Failed to get HAL Pixel Format err=%d", err);
+ return err;
+ }
+ bo->hal_format = static_cast<uint32_t>(hal_format);
+
+ err = mapper.getPixelFormatFourCC(handle, &bo->format);
+ if (err) {
+ ALOGE("Failed to get FourCC format err=%d", err);
+ return err;
+ }
+
+ err = mapper.getPixelFormatModifier(handle, &bo->modifiers[0]);
+ if (err) {
+ ALOGE("Failed to get DRM Modifier err=%d", err);
+ return err;
+ }
+ bo->with_modifiers = true;
+
+ uint64_t width = 0;
+ err = mapper.getWidth(handle, &width);
+ if (err) {
+ ALOGE("Failed to get Width err=%d", err);
+ return err;
+ }
+ bo->width = static_cast<uint32_t>(width);
+
+ uint64_t height = 0;
+ err = mapper.getHeight(handle, &height);
+ if (err) {
+ ALOGE("Failed to get Height err=%d", err);
+ return err;
+ }
+ bo->height = static_cast<uint32_t>(height);
+
+ std::vector<ui::PlaneLayout> layouts;
+ err = mapper.getPlaneLayouts(handle, &layouts);
+ if (err) {
+ ALOGE("Failed to get Plane Layouts err=%d", err);
+ return err;
+ }
+
+ for (uint32_t i = 0; i < layouts.size(); i++) {
+ bo->modifiers[i] = bo->modifiers[0];
+ bo->pitches[i] = layouts[i].strideInBytes;
+ bo->offsets[i] = layouts[i].offsetInBytes;
+ }
+
+ return GetFds(handle, bo);
+}
+
+} // namespace android
+
+#endif
diff --git a/bufferinfo/BufferInfoMapperMetadata.h b/bufferinfo/BufferInfoMapperMetadata.h
new file mode 100644
index 0000000..d335705
--- /dev/null
+++ b/bufferinfo/BufferInfoMapperMetadata.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 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 PLATFORMIMAGINATION_H
+#define PLATFORMIMAGINATION_H
+
+#include "bufferinfo/BufferInfoGetter.h"
+
+namespace android {
+
+class BufferInfoMapperMetadata : public BufferInfoGetter {
+ public:
+ using BufferInfoGetter::BufferInfoGetter;
+
+ int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
+
+ int GetFds(buffer_handle_t handle, hwc_drm_bo_t *bo);
+
+ static BufferInfoGetter *CreateInstance();
+};
+} // namespace android
+
+#endif // PLATFORMIMAGINATION_H
diff --git a/platform/platformimagination.cpp b/bufferinfo/legacy/BufferInfoImagination.cpp
index 7001d64..84c177e 100644
--- a/platform/platformimagination.cpp
+++ b/bufferinfo/legacy/BufferInfoImagination.cpp
@@ -1,6 +1,22 @@
-#define LOG_TAG "hwc-platform-imagination"
+/*
+ * Copyright (C) 2020 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 "platformimagination.h"
+#define LOG_TAG "hwc-bufferinfo-imagination"
+
+#include "BufferInfoImagination.h"
#include <log/log.h>
#include <xf86drm.h>
@@ -9,22 +25,10 @@
namespace android {
-Importer *Importer::CreateInstance(DrmDevice *drm) {
- ImaginationImporter *importer = new ImaginationImporter(drm);
- if (!importer)
- return NULL;
-
- int ret = importer->Init();
- if (ret) {
- ALOGE("Failed to initialize the Imagination importer %d", ret);
- delete importer;
- return NULL;
- }
- return importer;
-}
+LEGACY_BUFFER_INFO_GETTER(BufferInfoImagination);
-int ImaginationImporter::ConvertBoInfo(buffer_handle_t handle,
- hwc_drm_bo_t *bo) {
+int BufferInfoImagination::ConvertBoInfo(buffer_handle_t handle,
+ hwc_drm_bo_t *bo) {
IMG_native_handle_t *hnd = (IMG_native_handle_t *)handle;
if (!hnd)
return -EINVAL;
@@ -41,7 +45,6 @@ int ImaginationImporter::ConvertBoInfo(buffer_handle_t handle,
bo->prime_fds[0] = hnd->fd[0];
bo->pitches[0] = ALIGN(hnd->iWidth, HW_ALIGN) * hnd->uiBpp >> 3;
bo->hal_format = hnd->iFormat;
- bo->pixel_stride = hnd->aiStride[0];
switch (hnd->iFormat) {
#ifdef HAL_PIXEL_FORMAT_BGRX_8888
diff --git a/bufferinfo/legacy/BufferInfoImagination.h b/bufferinfo/legacy/BufferInfoImagination.h
new file mode 100644
index 0000000..765b279
--- /dev/null
+++ b/bufferinfo/legacy/BufferInfoImagination.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 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 BUFFERINFOIMAGINATION_H
+#define BUFFERINFOIMAGINATION_H
+
+#include <hardware/gralloc.h>
+
+#include "bufferinfo/BufferInfoGetter.h"
+
+namespace android {
+
+class BufferInfoImagination : public LegacyBufferInfoGetter {
+ public:
+ using LegacyBufferInfoGetter::LegacyBufferInfoGetter;
+
+ int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
+};
+} // namespace android
+
+#endif // PLATFORMIMAGINATION_H
diff --git a/platform/platformdrmgeneric.cpp b/bufferinfo/legacy/BufferInfoLibdrm.cpp
index 95a1eac..3f6a6fd 100644
--- a/platform/platformdrmgeneric.cpp
+++ b/bufferinfo/legacy/BufferInfoLibdrm.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,56 +14,20 @@
* limitations under the License.
*/
-#define LOG_TAG "hwc-platform-drm-generic"
+#define LOG_TAG "hwc-bufferinfo-libdrm"
-#include "platformdrmgeneric.h"
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
+#include "BufferInfoLibdrm.h"
#include <cutils/properties.h>
#include <gralloc_handle.h>
#include <hardware/gralloc.h>
#include <log/log.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
namespace android {
-#ifdef USE_DRM_GENERIC_IMPORTER
-// static
-Importer *Importer::CreateInstance(DrmDevice *drm) {
- DrmGenericImporter *importer = new DrmGenericImporter(drm);
- if (!importer)
- return NULL;
-
- int ret = importer->Init();
- if (ret) {
- ALOGE("Failed to initialize the nv importer %d", ret);
- delete importer;
- return NULL;
- }
- return importer;
-}
-#endif
-
-DrmGenericImporter::DrmGenericImporter(DrmDevice *drm) : drm_(drm) {
-}
-
-DrmGenericImporter::~DrmGenericImporter() {
-}
-
-int DrmGenericImporter::Init() {
- int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
- (const hw_module_t **)&gralloc_);
- if (ret) {
- ALOGE("Failed to open gralloc module");
- return ret;
- }
-
- ALOGI("Using %s gralloc module: %s\n", gralloc_->common.name,
- gralloc_->common.author);
-
- return 0;
-}
+LEGACY_BUFFER_INFO_GETTER(BufferInfoLibdrm);
enum chroma_order {
YCbCr,
@@ -118,8 +82,8 @@ static bool is_yuv(int native) {
return false;
}
-bool DrmGenericImporter::GetYuvPlaneInfo(int num_fds, buffer_handle_t handle,
- hwc_drm_bo_t *bo) {
+bool BufferInfoLibdrm::GetYuvPlaneInfo(int num_fds, buffer_handle_t handle,
+ hwc_drm_bo_t *bo) {
struct android_ycbcr ycbcr;
enum chroma_order chroma_order;
int ret;
@@ -189,46 +153,7 @@ bool DrmGenericImporter::GetYuvPlaneInfo(int num_fds, buffer_handle_t handle,
return true;
}
-uint32_t DrmGenericImporter::ConvertHalFormatToDrm(uint32_t hal_format) {
- switch (hal_format) {
- case HAL_PIXEL_FORMAT_RGB_888:
- return DRM_FORMAT_BGR888;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return DRM_FORMAT_ARGB8888;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- return DRM_FORMAT_XBGR8888;
- case HAL_PIXEL_FORMAT_RGBA_8888:
- return DRM_FORMAT_ABGR8888;
- case HAL_PIXEL_FORMAT_RGB_565:
- return DRM_FORMAT_BGR565;
- case HAL_PIXEL_FORMAT_YV12:
- return DRM_FORMAT_YVU420;
- default:
- ALOGE("Cannot convert hal format to drm format %u", hal_format);
- return DRM_FORMAT_INVALID;
- }
-}
-
-uint32_t DrmGenericImporter::DrmFormatToBitsPerPixel(uint32_t drm_format) {
- switch (drm_format) {
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_XBGR8888:
- case DRM_FORMAT_ABGR8888:
- return 32;
- case DRM_FORMAT_BGR888:
- return 24;
- case DRM_FORMAT_BGR565:
- return 16;
- case DRM_FORMAT_YVU420:
- return 12;
- default:
- ALOGE("Cannot convert hal format %u to bpp (returning 32)", drm_format);
- return 32;
- }
-}
-
-int DrmGenericImporter::ConvertBoInfo(buffer_handle_t handle,
- hwc_drm_bo_t *bo) {
+int BufferInfoLibdrm::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
gralloc_handle_t *gr_handle = gralloc_handle(handle);
if (!gr_handle)
return -EINVAL;
@@ -264,122 +189,7 @@ int DrmGenericImporter::ConvertBoInfo(buffer_handle_t handle,
return -EINVAL;
}
- bo->pixel_stride = (gr_handle->stride * 8) /
- DrmFormatToBitsPerPixel(bo->format);
-
return 0;
}
-int DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
- memset(bo, 0, sizeof(hwc_drm_bo_t));
-
- int ret = ConvertBoInfo(handle, bo);
- if (ret)
- return ret;
-
- ret = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[0], &bo->gem_handles[0]);
- if (ret) {
- ALOGE("failed to import prime fd %d ret=%d", bo->prime_fds[0], ret);
- return ret;
- }
-
- for (int i = 1; i < HWC_DRM_BO_MAX_PLANES; i++) {
- int fd = bo->prime_fds[i];
- if (fd != 0) {
- if (fd != bo->prime_fds[0]) {
- ALOGE("Multiplanar FBs are not supported by this version of composer");
- return -ENOTSUP;
- }
- bo->gem_handles[i] = bo->gem_handles[0];
- }
- }
-
- if (!bo->with_modifiers)
- ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
- bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id,
- 0);
- else
- ret = drmModeAddFB2WithModifiers(drm_->fd(), bo->width, bo->height,
- bo->format, bo->gem_handles, bo->pitches,
- bo->offsets, bo->modifiers, &bo->fb_id,
- bo->modifiers[0] ? DRM_MODE_FB_MODIFIERS
- : 0);
-
- if (ret) {
- ALOGE("could not create drm fb %d", ret);
- return ret;
- }
-
- ImportHandle(bo->gem_handles[0]);
-
- return ret;
-}
-
-int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
- if (bo->fb_id)
- if (drmModeRmFB(drm_->fd(), bo->fb_id))
- ALOGE("Failed to rm fb");
-
- for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
- if (!bo->gem_handles[i])
- continue;
-
- if (ReleaseHandle(bo->gem_handles[i])) {
- ALOGE("Failed to release gem handle %d", bo->gem_handles[i]);
- } else {
- for (int j = i + 1; j < HWC_DRM_BO_MAX_PLANES; j++)
- if (bo->gem_handles[j] == bo->gem_handles[i])
- bo->gem_handles[j] = 0;
- bo->gem_handles[i] = 0;
- }
- }
- return 0;
-}
-
-bool DrmGenericImporter::CanImportBuffer(buffer_handle_t handle) {
- hwc_drm_bo_t bo;
-
- int ret = ConvertBoInfo(handle, &bo);
- if (ret)
- return false;
-
- if (bo.prime_fds[0] == 0)
- return false;
-
- return true;
-}
-
-std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
- std::unique_ptr<Planner> planner(new Planner);
- planner->AddStage<PlanStageGreedy>();
- return planner;
-}
-
-int DrmGenericImporter::ImportHandle(uint32_t gem_handle) {
- gem_refcount_[gem_handle]++;
-
- return 0;
-}
-
-int DrmGenericImporter::ReleaseHandle(uint32_t gem_handle) {
- if (--gem_refcount_[gem_handle])
- return 0;
-
- gem_refcount_.erase(gem_handle);
-
- return CloseHandle(gem_handle);
-}
-
-int DrmGenericImporter::CloseHandle(uint32_t gem_handle) {
- struct drm_gem_close gem_close;
-
- memset(&gem_close, 0, sizeof(gem_close));
-
- gem_close.handle = gem_handle;
- int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
- if (ret)
- ALOGE("Failed to close gem handle %d %d", gem_handle, ret);
-
- return ret;
-}
-}
+} // namespace android
diff --git a/bufferinfo/legacy/BufferInfoLibdrm.h b/bufferinfo/legacy/BufferInfoLibdrm.h
new file mode 100644
index 0000000..4d37d00
--- /dev/null
+++ b/bufferinfo/legacy/BufferInfoLibdrm.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 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 BUFFERINFOLIBDRM_H_
+#define BUFFERINFOLIBDRM_H_
+
+#include <hardware/gralloc.h>
+
+#include "bufferinfo/BufferInfoGetter.h"
+
+namespace android {
+
+class BufferInfoLibdrm : public LegacyBufferInfoGetter {
+ public:
+ using LegacyBufferInfoGetter::LegacyBufferInfoGetter;
+ int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
+
+ private:
+ bool GetYuvPlaneInfo(int num_fds, buffer_handle_t handle, hwc_drm_bo_t *bo);
+};
+
+} // namespace android
+
+#endif
diff --git a/platform/platformhisi.cpp b/bufferinfo/legacy/BufferInfoMaliHisi.cpp
index 67793db..ab5579c 100644
--- a/platform/platformhisi.cpp
+++ b/bufferinfo/legacy/BufferInfoMaliHisi.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,39 +14,28 @@
* limitations under the License.
*/
-#define LOG_TAG "hwc-platform-hisi"
+#define LOG_TAG "hwc-bufferinfo-mali-hisi"
-#include "platformhisi.h"
+#include "BufferInfoMaliHisi.h"
+#include <log/log.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
+
#include <cinttypes>
-#include <log/log.h>
#include "gralloc_priv.h"
#define MALI_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1))
namespace android {
-Importer *Importer::CreateInstance(DrmDevice *drm) {
- HisiImporter *importer = new HisiImporter(drm);
- if (!importer)
- return NULL;
-
- int ret = importer->Init();
- if (ret) {
- ALOGE("Failed to initialize the hisi importer %d", ret);
- delete importer;
- return NULL;
- }
- return importer;
-}
+LEGACY_BUFFER_INFO_GETTER(BufferInfoMaliHisi);
#if defined(MALI_GRALLOC_INTFMT_AFBC_BASIC) && \
defined(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16)
-uint64_t HisiImporter::ConvertGrallocFormatToDrmModifiers(uint64_t flags,
- bool is_rgb) {
+uint64_t BufferInfoMaliHisi::ConvertGrallocFormatToDrmModifiers(uint64_t flags,
+ bool is_rgb) {
uint64_t features = 0UL;
if (flags & MALI_GRALLOC_INTFMT_AFBC_BASIC)
@@ -71,29 +60,14 @@ uint64_t HisiImporter::ConvertGrallocFormatToDrmModifiers(uint64_t flags,
return 0;
}
#else
-uint64_t HisiImporter::ConvertGrallocFormatToDrmModifiers(uint64_t /* flags */,
- bool /* is_rgb */) {
+uint64_t BufferInfoMaliHisi::ConvertGrallocFormatToDrmModifiers(
+ uint64_t /* flags */, bool /* is_rgb */) {
return 0;
}
#endif
-bool HisiImporter::IsDrmFormatRgb(uint32_t drm_format) {
- switch (drm_format) {
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_XBGR8888:
- case DRM_FORMAT_ABGR8888:
- case DRM_FORMAT_BGR888:
- case DRM_FORMAT_BGR565:
- return true;
- case DRM_FORMAT_YVU420:
- return false;
- default:
- ALOGV("Unsupported format %u assuming rgb?", drm_format);
- return true;
- }
-}
-
-int HisiImporter::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
+int BufferInfoMaliHisi::ConvertBoInfo(buffer_handle_t handle,
+ hwc_drm_bo_t *bo) {
bool is_rgb;
private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(
@@ -108,16 +82,15 @@ int HisiImporter::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
if (fmt == DRM_FORMAT_INVALID)
return -EINVAL;
- is_rgb = HisiImporter::IsDrmFormatRgb(fmt);
- bo->modifiers[0] = HisiImporter::
- ConvertGrallocFormatToDrmModifiers(hnd->internal_format, is_rgb);
+ is_rgb = IsDrmFormatRgb(fmt);
+ bo->modifiers[0] = ConvertGrallocFormatToDrmModifiers(hnd->internal_format,
+ is_rgb);
bo->width = hnd->width;
bo->height = hnd->height;
bo->hal_format = hnd->req_format;
bo->format = fmt;
bo->usage = hnd->usage;
- bo->pixel_stride = hnd->stride;
bo->pitches[0] = hnd->byte_stride;
bo->prime_fds[0] = hnd->share_fd;
bo->offsets[0] = 0;
diff --git a/platform/platformhisi.h b/bufferinfo/legacy/BufferInfoMaliHisi.h
index 272e547..698a0d3 100644
--- a/platform/platformhisi.h
+++ b/bufferinfo/legacy/BufferInfoMaliHisi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,28 +14,23 @@
* limitations under the License.
*/
-#ifndef ANDROID_PLATFORM_HISI_H_
-#define ANDROID_PLATFORM_HISI_H_
-
-#include "platform.h"
-#include "platformdrmgeneric.h"
-
-#include <stdatomic.h>
+#ifndef BUFFERINFOMALIHISI_H_
+#define BUFFERINFOMALIHISI_H_
#include <hardware/gralloc.h>
+#include "bufferinfo/BufferInfoGetter.h"
+
namespace android {
-class HisiImporter : public DrmGenericImporter {
+class BufferInfoMaliHisi : public LegacyBufferInfoGetter {
public:
- using DrmGenericImporter::DrmGenericImporter;
+ using LegacyBufferInfoGetter::LegacyBufferInfoGetter;
int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
private:
uint64_t ConvertGrallocFormatToDrmModifiers(uint64_t flags, bool is_rgb);
-
- bool IsDrmFormatRgb(uint32_t drm_format);
};
} // namespace android
diff --git a/platform/platformmediatek.cpp b/bufferinfo/legacy/BufferInfoMaliMediatek.cpp
index bbf76ea..ce47343 100644
--- a/platform/platformmediatek.cpp
+++ b/bufferinfo/legacy/BufferInfoMaliMediatek.cpp
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#define LOG_TAG "hwc-platform-mediatek"
+#define LOG_TAG "hwc-bufferinfo-mali-mediatek"
-#include "platformmediatek.h"
+#include "BufferInfoMaliMediatek.h"
#include <hardware/gralloc.h>
#include <log/log.h>
@@ -27,25 +27,13 @@
#include <cinttypes>
#include "gralloc_priv.h"
-#include "platform.h"
namespace android {
-Importer *Importer::CreateInstance(DrmDevice *drm) {
- MediatekImporter *importer = new MediatekImporter(drm);
- if (!importer)
- return NULL;
+LEGACY_BUFFER_INFO_GETTER(BufferInfoMaliMediatek);
- int ret = importer->Init();
- if (ret) {
- ALOGE("Failed to initialize the mediatek importer %d", ret);
- delete importer;
- return NULL;
- }
- return importer;
-}
-
-int MediatekImporter::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
+int BufferInfoMaliMediatek::ConvertBoInfo(buffer_handle_t handle,
+ hwc_drm_bo_t *bo) {
private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(
handle);
if (!hnd)
@@ -60,7 +48,6 @@ int MediatekImporter::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
bo->hal_format = hnd->req_format;
bo->format = fmt;
bo->usage = hnd->consumer_usage | hnd->producer_usage;
- bo->pixel_stride = hnd->stride;
bo->prime_fds[0] = hnd->share_fd;
bo->pitches[0] = hnd->byte_stride;
bo->offsets[0] = 0;
diff --git a/platform/platformmediatek.h b/bufferinfo/legacy/BufferInfoMaliMediatek.h
index 61fcf47..1204818 100644
--- a/platform/platformmediatek.h
+++ b/bufferinfo/legacy/BufferInfoMaliMediatek.h
@@ -14,20 +14,18 @@
* limitations under the License.
*/
-#ifndef ANDROID_PLATFORM_MTK_H_
-#define ANDROID_PLATFORM_MTK_H_
+#ifndef BUFFERINFOMALIMTK_H_
+#define BUFFERINFOMALIMTK_H_
#include <hardware/gralloc.h>
-#include <stdatomic.h>
-#include "platform.h"
-#include "platformdrmgeneric.h"
+#include "bufferinfo/BufferInfoGetter.h"
namespace android {
-class MediatekImporter : public DrmGenericImporter {
+class BufferInfoMaliMediatek : public LegacyBufferInfoGetter {
public:
- using DrmGenericImporter::DrmGenericImporter;
+ using LegacyBufferInfoGetter::LegacyBufferInfoGetter;
int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
};
diff --git a/platform/platformmeson.cpp b/bufferinfo/legacy/BufferInfoMaliMeson.cpp
index 278eac5..b6896e1 100644
--- a/platform/platformmeson.cpp
+++ b/bufferinfo/legacy/BufferInfoMaliMeson.cpp
@@ -14,36 +14,26 @@
* limitations under the License.
*/
-#define LOG_TAG "hwc-platform-meson"
+#define LOG_TAG "hwc-bufferinfo-mali-meson"
-#include "platformmeson.h"
+#include "BufferInfoMaliMeson.h"
+#include <log/log.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
+
#include <cinttypes>
-#include <log/log.h>
#include "gralloc_priv.h"
namespace android {
-Importer *Importer::CreateInstance(DrmDevice *drm) {
- MesonImporter *importer = new MesonImporter(drm);
- if (!importer)
- return NULL;
-
- int ret = importer->Init();
- if (ret) {
- ALOGE("Failed to initialize the meson importer %d", ret);
- delete importer;
- return NULL;
- }
- return importer;
-}
+LEGACY_BUFFER_INFO_GETTER(BufferInfoMaliMeson);
#if defined(MALI_GRALLOC_INTFMT_AFBC_BASIC) && \
defined(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16)
-uint64_t MesonImporter::ConvertGrallocFormatToDrmModifiers(uint64_t flags) {
+uint64_t BufferInfoMaliMeson::ConvertGrallocFormatToDrmModifiers(
+ uint64_t flags) {
uint64_t features = 0UL;
if (flags & MALI_GRALLOC_INTFMT_AFBC_BASIC) {
@@ -65,13 +55,14 @@ uint64_t MesonImporter::ConvertGrallocFormatToDrmModifiers(uint64_t flags) {
return 0;
}
#else
-uint64_t MesonImporter::ConvertGrallocFormatToDrmModifiers(
+uint64_t BufferInfoMaliMeson::ConvertGrallocFormatToDrmModifiers(
uint64_t /* flags */) {
return 0;
}
#endif
-int MesonImporter::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
+int BufferInfoMaliMeson::ConvertBoInfo(buffer_handle_t handle,
+ hwc_drm_bo_t *bo) {
private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(
handle);
if (!hnd)
@@ -84,7 +75,7 @@ int MesonImporter::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
if (fmt == DRM_FORMAT_INVALID)
return -EINVAL;
- bo->modifiers[0] = MesonImporter::ConvertGrallocFormatToDrmModifiers(
+ bo->modifiers[0] = BufferInfoMaliMeson::ConvertGrallocFormatToDrmModifiers(
hnd->internal_format);
bo->width = hnd->width;
@@ -92,7 +83,6 @@ int MesonImporter::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
bo->hal_format = hnd->req_format;
bo->format = fmt;
bo->usage = hnd->usage;
- bo->pixel_stride = hnd->stride;
bo->prime_fds[0] = hnd->share_fd;
bo->pitches[0] = hnd->byte_stride;
bo->offsets[0] = 0;
diff --git a/platform/platformmeson.h b/bufferinfo/legacy/BufferInfoMaliMeson.h
index 1b428a4..ce5d3f9 100644
--- a/platform/platformmeson.h
+++ b/bufferinfo/legacy/BufferInfoMaliMeson.h
@@ -14,22 +14,18 @@
* limitations under the License.
*/
-#ifndef ANDROID_PLATFORM_HISI_H_
-#define ANDROID_PLATFORM_HISI_H_
-
-#include "platform.h"
-#include "platformdrmgeneric.h"
-
-#include <stdatomic.h>
+#ifndef BUFFERINFOMALIHISI_H_
+#define BUFFERINFOMALIHISI_H_
#include <hardware/gralloc.h>
+#include "bufferinfo/BufferInfoGetter.h"
+
namespace android {
-class MesonImporter : public DrmGenericImporter {
+class BufferInfoMaliMeson : public LegacyBufferInfoGetter {
public:
- using DrmGenericImporter::DrmGenericImporter;
-
+ using LegacyBufferInfoGetter::LegacyBufferInfoGetter;
int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
private:
diff --git a/platform/platformminigbm.cpp b/bufferinfo/legacy/BufferInfoMinigbm.cpp
index 4360b0a..860de08 100644
--- a/platform/platformminigbm.cpp
+++ b/bufferinfo/legacy/BufferInfoMinigbm.cpp
@@ -14,35 +14,21 @@
* limitations under the License.
*/
-#define LOG_TAG "hwc-platform-drm-minigbm"
+#define LOG_TAG "hwc-bufferinfo-minigbm"
-#include "platformminigbm.h"
+#include "BufferInfoMinigbm.h"
+#include <log/log.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
-#include <log/log.h>
-
#include "cros_gralloc_handle.h"
namespace android {
-Importer *Importer::CreateInstance(DrmDevice *drm) {
- DrmMinigbmImporter *importer = new DrmMinigbmImporter(drm);
- if (!importer)
- return NULL;
-
- int ret = importer->Init();
- if (ret) {
- ALOGE("Failed to initialize the minigbm importer %d", ret);
- delete importer;
- return NULL;
- }
- return importer;
-}
+LEGACY_BUFFER_INFO_GETTER(BufferInfoMinigbm);
-int DrmMinigbmImporter::ConvertBoInfo(buffer_handle_t handle,
- hwc_drm_bo_t *bo) {
+int BufferInfoMinigbm::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)handle;
if (!gr_handle)
return -EINVAL;
@@ -52,7 +38,6 @@ int DrmMinigbmImporter::ConvertBoInfo(buffer_handle_t handle,
bo->hal_format = gr_handle->droid_format;
bo->format = gr_handle->format;
bo->usage = gr_handle->usage;
- bo->pixel_stride = gr_handle->pixel_stride;
bo->prime_fds[0] = gr_handle->fds[0];
bo->pitches[0] = gr_handle->strides[0];
bo->offsets[0] = gr_handle->offsets[0];
diff --git a/platform/platformminigbm.h b/bufferinfo/legacy/BufferInfoMinigbm.h
index 1eea6ca..bff9d74 100644
--- a/platform/platformminigbm.h
+++ b/bufferinfo/legacy/BufferInfoMinigbm.h
@@ -14,19 +14,18 @@
* limitations under the License.
*/
-#ifndef ANDROID_PLATFORM_DRM_MINIGBM_H_
-#define ANDROID_PLATFORM_DRM_MINIGBM_H_
-
-#include "platform.h"
-#include "platformdrmgeneric.h"
+#ifndef BUFFERINFOMINIGBM_H_
+#define BUFFERINFOMINIGBM_H_
#include <hardware/gralloc.h>
+#include "bufferinfo/BufferInfoGetter.h"
+
namespace android {
-class DrmMinigbmImporter : public DrmGenericImporter {
+class BufferInfoMinigbm : public LegacyBufferInfoGetter {
public:
- using DrmGenericImporter::DrmGenericImporter;
+ using LegacyBufferInfoGetter::LegacyBufferInfoGetter;
int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
};
diff --git a/compositor/DrmDisplayComposition.cpp b/compositor/DrmDisplayComposition.cpp
index 79dd470..4d2e19a 100644
--- a/compositor/DrmDisplayComposition.cpp
+++ b/compositor/DrmDisplayComposition.cpp
@@ -27,8 +27,8 @@
#include <unordered_set>
#include "DrmDisplayCompositor.h"
+#include "Planner.h"
#include "drm/DrmDevice.h"
-#include "platform/platform.h"
namespace android {
diff --git a/compositor/DrmDisplayCompositor.cpp b/compositor/DrmDisplayCompositor.cpp
index 467f8ba..ba0d56b 100644
--- a/compositor/DrmDisplayCompositor.cpp
+++ b/compositor/DrmDisplayCompositor.cpp
@@ -813,7 +813,9 @@ bool DrmDisplayCompositor::IsFlatteningNeeded() const {
}
int DrmDisplayCompositor::FlattenOnClient() {
- if (refresh_display_cb_) {
+ const std::lock_guard<std::mutex> lock(refresh_callback_lock);
+
+ if (refresh_callback_hook_ && refresh_callback_data_) {
{
AutoLock lock(&lock_, __func__);
if (!IsFlatteningNeeded()) {
@@ -829,7 +831,7 @@ int DrmDisplayCompositor::FlattenOnClient() {
"No writeback connector available, "
"falling back to client composition");
SetFlattening(FlatteningState::kClientRequested);
- refresh_display_cb_(display_);
+ refresh_callback_hook_(refresh_callback_data_, display_);
return 0;
} else {
ALOGV("No writeback connector available");
diff --git a/compositor/DrmDisplayCompositor.h b/compositor/DrmDisplayCompositor.h
index e500c9e..ab3f867 100644
--- a/compositor/DrmDisplayCompositor.h
+++ b/compositor/DrmDisplayCompositor.h
@@ -27,6 +27,7 @@
#include "DrmDisplayComposition.h"
#include "DrmFramebuffer.h"
+#include "Planner.h"
#include "drm/ResourceManager.h"
#include "drm/VSyncWorker.h"
#include "drmhwcomposer.h"
@@ -59,9 +60,15 @@ class DrmDisplayCompositor {
int Init(ResourceManager *resource_manager, int display);
- template <typename Fn>
- void SetRefreshCallback(Fn &&refresh_cb) {
- refresh_display_cb_ = std::forward<Fn>(refresh_cb);
+ hwc2_callback_data_t refresh_callback_data_ = NULL;
+ HWC2_PFN_REFRESH refresh_callback_hook_ = NULL;
+ std::mutex refresh_callback_lock;
+
+ void SetRefreshCallback(hwc2_callback_data_t data,
+ hwc2_function_pointer_t hook) {
+ const std::lock_guard<std::mutex> lock(refresh_callback_lock);
+ refresh_callback_data_ = data;
+ refresh_callback_hook_ = reinterpret_cast<HWC2_PFN_REFRESH>(hook);
}
std::unique_ptr<DrmDisplayComposition> CreateComposition() const;
diff --git a/platform/platform.cpp b/compositor/Planner.cpp
index a500398..f4b5c51 100644
--- a/platform/platform.cpp
+++ b/compositor/Planner.cpp
@@ -16,7 +16,7 @@
#define LOG_TAG "hwc-platform"
-#include "platform.h"
+#include "Planner.h"
#include <log/log.h>
@@ -24,6 +24,12 @@
namespace android {
+std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
+ std::unique_ptr<Planner> planner(new Planner);
+ planner->AddStage<PlanStageGreedy>();
+ return planner;
+}
+
std::vector<DrmPlane *> Planner::GetUsablePlanes(
DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
std::vector<DrmPlane *> *overlay_planes) {
diff --git a/platform/platform.h b/compositor/Planner.h
index 13dc360..09034ff 100644
--- a/platform/platform.h
+++ b/compositor/Planner.h
@@ -30,33 +30,6 @@ namespace android {
class DrmDevice;
-class Importer {
- public:
- virtual ~Importer() {
- }
-
- // Creates a platform-specific importer instance
- static Importer *CreateInstance(DrmDevice *drm);
-
- // Imports the buffer referred to by handle into bo.
- //
- // 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;
-
- // Releases the buffer object (ie: does the inverse of ImportBuffer)
- //
- // Note: This can be called from a different thread than ImportBuffer. The
- // implementation is responsible for ensuring thread safety.
- virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0;
-
- // Checks if importer can import the buffer.
- virtual bool CanImportBuffer(buffer_handle_t handle) = 0;
-
- // Convert platform-dependent buffer format to drm_hwc internal format.
- virtual int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) = 0;
-};
-
class Planner {
public:
class PlanStage {
diff --git a/drm/DrmDevice.cpp b/drm/DrmDevice.cpp
index 28ecfda..bf1a5e2 100644
--- a/drm/DrmDevice.cpp
+++ b/drm/DrmDevice.cpp
@@ -29,6 +29,7 @@
#include <algorithm>
#include <array>
#include <cinttypes>
+#include <sstream>
#include <string>
static void trim_left(std::string &str) {
diff --git a/drm/DrmDevice.h b/drm/DrmDevice.h
index d7ea359..be68aa6 100644
--- a/drm/DrmDevice.h
+++ b/drm/DrmDevice.h
@@ -19,6 +19,7 @@
#include <stdint.h>
+#include <map>
#include <tuple>
#include "DrmConnector.h"
@@ -26,7 +27,6 @@
#include "DrmEncoder.h"
#include "DrmEventListener.h"
#include "DrmPlane.h"
-#include "platform/platform.h"
namespace android {
diff --git a/drm/DrmGenericImporter.cpp b/drm/DrmGenericImporter.cpp
new file mode 100644
index 0000000..8ab4fe5
--- /dev/null
+++ b/drm/DrmGenericImporter.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "hwc-platform-drm-generic"
+
+#include "DrmGenericImporter.h"
+
+#include <cutils/properties.h>
+#include <gralloc_handle.h>
+#include <hardware/gralloc.h>
+#include <inttypes.h>
+#include <log/log.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+namespace android {
+
+DrmGenericImporter::DrmGenericImporter(DrmDevice *drm) : drm_(drm) {
+ uint64_t cap_value = 0;
+ if (drmGetCap(drm_->fd(), DRM_CAP_ADDFB2_MODIFIERS, &cap_value)) {
+ ALOGE("drmGetCap failed. Fallback to no modifier support.");
+ cap_value = 0;
+ }
+ has_modifier_support_ = cap_value;
+}
+
+DrmGenericImporter::~DrmGenericImporter() {
+}
+
+int DrmGenericImporter::ImportBuffer(hwc_drm_bo_t *bo) {
+ int ret = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[0],
+ &bo->gem_handles[0]);
+ if (ret) {
+ ALOGE("failed to import prime fd %d ret=%d", bo->prime_fds[0], ret);
+ return ret;
+ }
+
+ for (int i = 1; i < HWC_DRM_BO_MAX_PLANES; i++) {
+ int fd = bo->prime_fds[i];
+ if (fd != 0) {
+ if (fd != bo->prime_fds[0]) {
+ ALOGE("Multiplanar FBs are not supported by this version of composer");
+ return -ENOTSUP;
+ }
+ bo->gem_handles[i] = bo->gem_handles[0];
+ }
+ }
+
+ if (!has_modifier_support_ && bo->modifiers[0]) {
+ ALOGE("No ADDFB2 with modifier support. Can't import modifier %" PRIu64,
+ bo->modifiers[0]);
+ return -EINVAL;
+ }
+
+ if (!bo->with_modifiers)
+ ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
+ bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id,
+ 0);
+ else
+ ret = drmModeAddFB2WithModifiers(drm_->fd(), bo->width, bo->height,
+ bo->format, bo->gem_handles, bo->pitches,
+ bo->offsets, bo->modifiers, &bo->fb_id,
+ bo->modifiers[0] ? DRM_MODE_FB_MODIFIERS
+ : 0);
+
+ if (ret) {
+ ALOGE("could not create drm fb %d", ret);
+ return ret;
+ }
+
+ ImportHandle(bo->gem_handles[0]);
+
+ return ret;
+}
+
+int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
+ if (bo->fb_id)
+ if (drmModeRmFB(drm_->fd(), bo->fb_id))
+ ALOGE("Failed to rm fb");
+
+ for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
+ if (!bo->gem_handles[i])
+ continue;
+
+ if (ReleaseHandle(bo->gem_handles[i])) {
+ ALOGE("Failed to release gem handle %d", bo->gem_handles[i]);
+ } else {
+ for (int j = i + 1; j < HWC_DRM_BO_MAX_PLANES; j++)
+ if (bo->gem_handles[j] == bo->gem_handles[i])
+ bo->gem_handles[j] = 0;
+ bo->gem_handles[i] = 0;
+ }
+ }
+ return 0;
+}
+
+int DrmGenericImporter::ImportHandle(uint32_t gem_handle) {
+ gem_refcount_[gem_handle]++;
+
+ return 0;
+}
+
+int DrmGenericImporter::ReleaseHandle(uint32_t gem_handle) {
+ if (--gem_refcount_[gem_handle])
+ return 0;
+
+ gem_refcount_.erase(gem_handle);
+
+ return CloseHandle(gem_handle);
+}
+
+int DrmGenericImporter::CloseHandle(uint32_t gem_handle) {
+ struct drm_gem_close gem_close;
+
+ memset(&gem_close, 0, sizeof(gem_close));
+
+ gem_close.handle = gem_handle;
+ int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
+ if (ret)
+ ALOGE("Failed to close gem handle %d %d", gem_handle, ret);
+
+ return ret;
+}
+} // namespace android
diff --git a/platform/platformdrmgeneric.h b/drm/DrmGenericImporter.h
index 1bdaa09..ca53762 100644
--- a/platform/platformdrmgeneric.h
+++ b/drm/DrmGenericImporter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -23,7 +23,7 @@
#include <map>
#include "drm/DrmDevice.h"
-#include "platform.h"
+#include "drmhwcgralloc.h"
#ifndef DRM_FORMAT_INVALID
#define DRM_FORMAT_INVALID 0
@@ -31,34 +31,43 @@
namespace android {
+class Importer {
+ public:
+ virtual ~Importer() {
+ }
+
+ // Imports the buffer referred to by handle into bo.
+ //
+ // Note: This can be called from a different thread than ReleaseBuffer. The
+ // implementation is responsible for ensuring thread safety.
+ virtual int ImportBuffer(hwc_drm_bo_t *bo) = 0;
+
+ // Releases the buffer object (ie: does the inverse of ImportBuffer)
+ //
+ // Note: This can be called from a different thread than ImportBuffer. The
+ // implementation is responsible for ensuring thread safety.
+ virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0;
+};
+
class DrmGenericImporter : public Importer {
public:
DrmGenericImporter(DrmDevice *drm);
~DrmGenericImporter() override;
- int Init();
-
- int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
+ int ImportBuffer(hwc_drm_bo_t *bo) override;
int ReleaseBuffer(hwc_drm_bo_t *bo) override;
- bool CanImportBuffer(buffer_handle_t handle) override;
int ImportHandle(uint32_t gem_handle);
int ReleaseHandle(uint32_t gem_handle);
- int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
-
- uint32_t ConvertHalFormatToDrm(uint32_t hal_format);
- uint32_t DrmFormatToBitsPerPixel(uint32_t drm_format);
- bool GetYuvPlaneInfo(int num_fds, buffer_handle_t handle, hwc_drm_bo_t *bo);
-
protected:
DrmDevice *drm_;
private:
- const gralloc_module_t *gralloc_;
-
int CloseHandle(uint32_t gem_handle);
std::map<uint32_t, int> gem_refcount_;
+ bool has_modifier_support_;
};
+
} // namespace android
#endif
diff --git a/drm/ResourceManager.cpp b/drm/ResourceManager.cpp
index 67ef7f8..fc24aea 100644
--- a/drm/ResourceManager.cpp
+++ b/drm/ResourceManager.cpp
@@ -24,6 +24,8 @@
#include <sstream>
+#include "bufferinfo/BufferInfoGetter.h"
+
namespace android {
ResourceManager::ResourceManager() : num_displays_(0), gralloc_(NULL) {
@@ -62,6 +64,11 @@ int ResourceManager::Init() {
property_get("vendor.hwc.drm.scale_with_gpu", scale_with_gpu, "0");
scale_with_gpu_ = bool(strncmp(scale_with_gpu, "0", 1));
+ if (!BufferInfoGetter::GetInstance()) {
+ ALOGE("Failed to initialize BufferInfoGetter");
+ return -EINVAL;
+ }
+
return hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
(const hw_module_t **)&gralloc_);
}
@@ -73,7 +80,7 @@ int ResourceManager::AddDrmDevice(std::string path) {
if (ret)
return ret;
std::shared_ptr<Importer> importer;
- importer.reset(Importer::CreateInstance(drm.get()));
+ importer.reset(new DrmGenericImporter(drm.get()));
if (!importer) {
ALOGE("Failed to create importer instance");
return -ENODEV;
diff --git a/drm/ResourceManager.h b/drm/ResourceManager.h
index 94ba43e..7102cea 100644
--- a/drm/ResourceManager.h
+++ b/drm/ResourceManager.h
@@ -20,7 +20,7 @@
#include <string.h>
#include "DrmDevice.h"
-#include "platform/platform.h"
+#include "DrmGenericImporter.h"
namespace android {
diff --git a/drm/VSyncWorker.cpp b/drm/VSyncWorker.cpp
index dfbf8ce..b2f7e5f 100644
--- a/drm/VSyncWorker.cpp
+++ b/drm/VSyncWorker.cpp
@@ -50,6 +50,14 @@ void VSyncWorker::RegisterCallback(std::shared_ptr<VsyncCallback> callback) {
Unlock();
}
+void VSyncWorker::RegisterClientCallback(hwc2_callback_data_t data,
+ hwc2_function_pointer_t hook) {
+ Lock();
+ vsync_callback_data_ = data;
+ vsync_callback_hook_ = reinterpret_cast<HWC2_PFN_VSYNC>(hook);
+ Unlock();
+}
+
void VSyncWorker::VSyncControl(bool enabled) {
Lock();
enabled_ = enabled;
@@ -151,37 +159,17 @@ void VSyncWorker::Routine() {
(int64_t)vblank.reply.tval_usec * 1000;
}
- /*
- * VSync could be disabled during routine execution so it could potentially
- * lead to crash since callback's inner hook could be invalid anymore. We have
- * no control over lifetime of this hook, therefore we can't rely that it'll
- * be valid after vsync disabling.
- *
- * Blocking VSyncControl to wait until routine
- * will finish execution is logically correct way to fix this issue, but it
- * creates visible lags and stutters, so we have to resort to other ways of
- * mitigating this issue.
- *
- * Doing check before attempt to invoke callback drastically shortens the
- * window when such situation could happen and that allows us to practically
- * avoid this issue.
- *
- * Please note that issue described below is different one and it is related
- * to RegisterCallback, not to disabling vsync via VSyncControl.
- */
if (!enabled_)
return;
- /*
- * There's a race here where a change in callback_ will not take effect until
- * the next subsequent requested vsync. This is unavoidable since we can't
- * call the vsync hook while holding the thread lock.
- *
- * We could shorten the race window by caching callback_ right before calling
- * the hook. However, in practice, callback_ is only updated once, so it's not
- * worth the overhead.
- */
+
if (callback)
callback->Callback(display, timestamp);
+
+ Lock();
+ if (enabled_ && vsync_callback_hook_ && vsync_callback_data_)
+ vsync_callback_hook_(vsync_callback_data_, display, timestamp);
+ Unlock();
+
last_timestamp_ = timestamp;
}
} // namespace android
diff --git a/drm/VSyncWorker.h b/drm/VSyncWorker.h
index 0121a6c..7454b51 100644
--- a/drm/VSyncWorker.h
+++ b/drm/VSyncWorker.h
@@ -19,6 +19,7 @@
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer2.h>
#include <stdint.h>
#include <map>
@@ -42,6 +43,8 @@ class VSyncWorker : public Worker {
int Init(DrmDevice *drm, int display);
void RegisterCallback(std::shared_ptr<VsyncCallback> callback);
+ void RegisterClientCallback(hwc2_callback_data_t data,
+ hwc2_function_pointer_t hook);
void VSyncControl(bool enabled);
@@ -62,6 +65,9 @@ class VSyncWorker : public Worker {
int display_;
std::atomic_bool enabled_;
int64_t last_timestamp_;
+
+ hwc2_callback_data_t vsync_callback_data_ = NULL;
+ HWC2_PFN_VSYNC vsync_callback_hook_ = NULL;
};
} // namespace android
diff --git a/include/drmhwcgralloc.h b/include/drmhwcgralloc.h
index b959714..fc0af64 100644
--- a/include/drmhwcgralloc.h
+++ b/include/drmhwcgralloc.h
@@ -26,7 +26,6 @@ typedef struct hwc_drm_bo {
uint32_t format; /* DRM_FORMAT_* from drm_fourcc.h */
uint32_t hal_format; /* HAL_PIXEL_FORMAT_* */
uint32_t usage;
- uint32_t pixel_stride;
uint32_t pitches[HWC_DRM_BO_MAX_PLANES];
uint32_t offsets[HWC_DRM_BO_MAX_PLANES];
uint32_t prime_fds[HWC_DRM_BO_MAX_PLANES];
diff --git a/include/drmhwcomposer.h b/include/drmhwcomposer.h
index 69313d9..0706ae5 100644
--- a/include/drmhwcomposer.h
+++ b/include/drmhwcomposer.h
@@ -99,8 +99,7 @@ class DrmHwcNativeHandle {
return *this;
}
- int CopyBufferHandle(buffer_handle_t handle, int width, int height,
- int layerCount, int format, int usage, int stride);
+ int CopyBufferHandle(buffer_handle_t handle);
void Clear();
diff --git a/platform/platformimagination.h b/platform/platformimagination.h
deleted file mode 100644
index 4eec698..0000000
--- a/platform/platformimagination.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef PLATFORMIMAGINATION_H
-#define PLATFORMIMAGINATION_H
-
-#include "platform.h"
-#include "platformdrmgeneric.h"
-
-#include <stdatomic.h>
-
-#include <hardware/gralloc.h>
-
-namespace android {
-
-class ImaginationImporter : public DrmGenericImporter {
- public:
- using DrmGenericImporter::DrmGenericImporter;
-
- int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
-};
-} // namespace android
-
-#endif // PLATFORMIMAGINATION_H
diff --git a/utils/hwcutils.cpp b/utils/hwcutils.cpp
index 2dc7e7b..322efce 100644
--- a/utils/hwcutils.cpp
+++ b/utils/hwcutils.cpp
@@ -18,10 +18,12 @@
#define LOG_TAG "hwc-drm-utils"
#include <log/log.h>
+#include <ui/Gralloc.h>
#include <ui/GraphicBufferMapper.h>
+#include "bufferinfo/BufferInfoGetter.h"
+#include "drm/DrmGenericImporter.h"
#include "drmhwcomposer.h"
-#include "platform/platform.h"
#define UNUSED(x) (void)(x)
@@ -44,11 +46,19 @@ void DrmHwcBuffer::Clear() {
}
int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) {
- hwc_drm_bo tmp_bo;
+ hwc_drm_bo tmp_bo{};
- int ret = importer->ImportBuffer(handle, &tmp_bo);
- if (ret)
+ int ret = BufferInfoGetter::GetInstance()->ConvertBoInfo(handle, &tmp_bo);
+ if (ret) {
+ ALOGE("Failed to convert buffer info %d", ret);
+ return ret;
+ }
+
+ ret = importer->ImportBuffer(&tmp_bo);
+ if (ret) {
+ ALOGE("Failed to import buffer %d", ret);
return ret;
+ }
if (importer_ != NULL) {
importer_->ReleaseBuffer(&bo_);
@@ -61,25 +71,15 @@ int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) {
return 0;
}
-int DrmHwcNativeHandle::CopyBufferHandle(buffer_handle_t handle, int width,
- int height, int layerCount, int format,
- int usage, int stride) {
+int DrmHwcNativeHandle::CopyBufferHandle(buffer_handle_t handle) {
native_handle_t *handle_copy;
GraphicBufferMapper &gm(GraphicBufferMapper::get());
int ret;
-#ifdef HWC2_USE_OLD_GB_IMPORT
- UNUSED(width);
- UNUSED(height);
- UNUSED(layerCount);
- UNUSED(format);
- UNUSED(usage);
- UNUSED(stride);
- ret = gm.importBuffer(handle, const_cast<buffer_handle_t *>(&handle_copy));
-#else
- ret = gm.importBuffer(handle, width, height, layerCount, format, usage,
- stride, const_cast<buffer_handle_t *>(&handle_copy));
-#endif
+ ret = gm.getGrallocMapper().importBuffer(handle,
+ const_cast<buffer_handle_t *>(
+ &handle_copy));
+
if (ret) {
ALOGE("Failed to import buffer handle %d", ret);
return ret;
@@ -114,9 +114,7 @@ int DrmHwcLayer::ImportBuffer(Importer *importer) {
const hwc_drm_bo *bo = buffer.operator->();
- ret = handle.CopyBufferHandle(sf_handle, bo->width, bo->height,
- 1 /*layer_count*/, bo->hal_format, bo->usage,
- bo->pixel_stride);
+ ret = handle.CopyBufferHandle(sf_handle);
if (ret)
return ret;