aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2020-09-30 23:40:23 +0000
committerJohn Stultz <john.stultz@linaro.org>2020-09-30 23:40:23 +0000
commit8e7afb9d2e870bce0498b41ce3630cf9d9b2ea61 (patch)
treecd680faf5b186c330fd86f76bf2179d8e3afb1ad
parent58a4d1f46b7273b5c9e20eeb0dbba4ae2a47c40d (diff)
parent25ddbc44acfbe6d53439deb68e0f92b5809b5738 (diff)
downloaddrm_hwcomposer-8e7afb9d2e870bce0498b41ce3630cf9d9b2ea61.tar.gz
Merge remote-tracking branch 'aosp/upstream-main' into HEAD
Update to the current upstream tree * aosp/upstream-main: drm_hwcomposer: Return error from GetEdidBlob if blob is null drm_hwcomposer: fix build error after fbf5c0ca45b3 drm_hwcomposer: Add check for format support during plane validation drm_hwcomposer: Add supported formats list to DrmPlane drm_hwcomposer: add drm-mediatek to client-backend list drm_hwcomposer: Add MediaTek platform support drm_hwcomposer: remove vendor.hwc.drm.exclude_non_hwfb_imports property drm_hwcomposer: always use PlanStageGreedy drm_hwcomposer: Fix EDID fetch from DRM drm_hwcomposer: use CamelCase in source/header files related to class drm_hwcomposer: move header files into source directory drm_hwcomposer: libdrm gralloc_handle: modifiers and YUV support drm_hwcomposer: fix incorrect layer_count usage drm_hwcomposer: Add rcar-du display backend drm_hwcomposer: Add composition skipping backend drm_hwcomposer: Add backend-dependent validation for HwcDisplay class drm_hwcomposer: Expand access to HwcDisplay class members drm_hwcomposer: Move DrmHwcTwo internal classes outside private section drm_hwcomposer: Add include guard into drmhwctwo.h Signed-off-by: John Stultz <john.stultz@linaro.org> Change-Id: I3b1e1710f14b458bb3501dc7c77f6c52394fff42
-rw-r--r--Android.bp56
-rw-r--r--DrmHwcTwo.cpp (renamed from drmhwctwo.cpp)114
-rw-r--r--DrmHwcTwo.h (renamed from include/drmhwctwo.h)121
-rw-r--r--backend/Backend.cpp136
-rw-r--r--backend/Backend.h38
-rw-r--r--backend/BackendClient.cpp35
-rw-r--r--backend/BackendClient.h32
-rw-r--r--backend/BackendManager.cpp79
-rw-r--r--backend/BackendManager.h57
-rw-r--r--backend/BackendRCarDu.cpp43
-rw-r--r--backend/BackendRCarDu.h31
-rw-r--r--compositor/DrmDisplayComposition.cpp (renamed from compositor/drmdisplaycomposition.cpp)16
-rw-r--r--compositor/DrmDisplayComposition.h (renamed from include/drmdisplaycomposition.h)10
-rw-r--r--compositor/DrmDisplayCompositor.cpp (renamed from compositor/drmdisplaycompositor.cpp)20
-rw-r--r--compositor/DrmDisplayCompositor.h (renamed from include/drmdisplaycompositor.h)16
-rw-r--r--drm/DrmConnector.cpp (renamed from drm/drmconnector.cpp)37
-rw-r--r--drm/DrmConnector.h (renamed from include/drmconnector.h)11
-rw-r--r--drm/DrmCrtc.cpp (renamed from drm/drmcrtc.cpp)6
-rw-r--r--drm/DrmCrtc.h (renamed from include/drmcrtc.h)6
-rw-r--r--drm/DrmDevice.cpp (renamed from drm/drmdevice.cpp)26
-rw-r--r--drm/DrmDevice.h (renamed from include/drmdevice.h)17
-rw-r--r--drm/DrmEncoder.cpp (renamed from drm/drmencoder.cpp)6
-rw-r--r--drm/DrmEncoder.h (renamed from include/drmencoder.h)5
-rw-r--r--drm/DrmEventListener.cpp (renamed from drm/drmeventlistener.cpp)10
-rw-r--r--drm/DrmEventListener.h (renamed from include/drmeventlistener.h)2
-rw-r--r--drm/DrmMode.cpp (renamed from drm/drmmode.cpp)7
-rw-r--r--drm/DrmMode.h (renamed from include/drmmode.h)1
-rw-r--r--drm/DrmPlane.cpp (renamed from drm/drmplane.cpp)18
-rw-r--r--drm/DrmPlane.h (renamed from include/drmplane.h)11
-rw-r--r--drm/DrmProperty.cpp (renamed from drm/drmproperty.cpp)7
-rw-r--r--drm/DrmProperty.h (renamed from include/drmproperty.h)1
-rw-r--r--drm/ResourceManager.cpp (renamed from drm/resourcemanager.cpp)4
-rw-r--r--drm/ResourceManager.h (renamed from include/resourcemanager.h)6
-rw-r--r--drm/VSyncWorker.cpp (renamed from drm/vsyncworker.cpp)9
-rw-r--r--drm/VSyncWorker.h (renamed from include/vsyncworker.h)10
-rw-r--r--include/DrmFramebuffer.h (renamed from include/drmframebuffer.h)2
-rw-r--r--platform/platform.cpp10
-rw-r--r--platform/platform.h (renamed from include/platform.h)6
-rw-r--r--platform/platformdrmgeneric.cpp172
-rw-r--r--platform/platformdrmgeneric.h10
-rw-r--r--platform/platformhisi.cpp42
-rw-r--r--platform/platformhisi.h1
-rw-r--r--platform/platformimagination.cpp6
-rw-r--r--platform/platformimagination.h1
-rw-r--r--platform/platformmediatek.cpp71
-rw-r--r--platform/platformmediatek.h36
-rw-r--r--platform/platformmeson.cpp9
-rw-r--r--platform/platformmeson.h1
-rw-r--r--platform/platformminigbm.cpp9
-rw-r--r--platform/platformminigbm.h1
-rw-r--r--tests/Android.bp5
-rw-r--r--tests/worker_test.cpp4
-rw-r--r--utils/Worker.cpp (renamed from utils/worker.cpp)2
-rw-r--r--utils/Worker.h (renamed from include/worker.h)2
-rw-r--r--utils/autolock.h (renamed from include/autolock.h)0
-rw-r--r--utils/hwcutils.cpp16
56 files changed, 1036 insertions, 374 deletions
diff --git a/Android.bp b/Android.bp
index 8bcd1aa..fef3ed6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -18,9 +18,12 @@
cc_library_static {
name: "libdrmhwc_utils",
- srcs: ["utils/worker.cpp"],
+ srcs: ["utils/Worker.cpp"],
- include_dirs: ["external/drm_hwcomposer/include"],
+ include_dirs: [
+ "external/drm_hwcomposer/include",
+ "external/drm_hwcomposer",
+ ],
cflags: [
"-Wall",
@@ -47,7 +50,10 @@ cc_defaults {
"libutils",
],
- include_dirs: ["external/drm_hwcomposer/include"],
+ include_dirs: [
+ "external/drm_hwcomposer/include",
+ "external/drm_hwcomposer",
+ ],
static_libs: ["libdrmhwc_utils"],
@@ -74,26 +80,31 @@ cc_library_static {
name: "drm_hwcomposer",
defaults: ["hwcomposer.drm_defaults"],
srcs: [
- "drmhwctwo.cpp",
-
- "compositor/drmdisplaycomposition.cpp",
- "compositor/drmdisplaycompositor.cpp",
-
- "drm/drmconnector.cpp",
- "drm/drmcrtc.cpp",
- "drm/drmdevice.cpp",
- "drm/drmencoder.cpp",
- "drm/drmeventlistener.cpp",
- "drm/drmmode.cpp",
- "drm/drmplane.cpp",
- "drm/drmproperty.cpp",
- "drm/resourcemanager.cpp",
- "drm/vsyncworker.cpp",
+ "DrmHwcTwo.cpp",
+
+ "compositor/DrmDisplayComposition.cpp",
+ "compositor/DrmDisplayCompositor.cpp",
+
+ "drm/DrmConnector.cpp",
+ "drm/DrmCrtc.cpp",
+ "drm/DrmDevice.cpp",
+ "drm/DrmEncoder.cpp",
+ "drm/DrmEventListener.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",
+
+ "backend/BackendManager.cpp",
+ "backend/Backend.cpp",
+ "backend/BackendClient.cpp",
+ "backend/BackendRCarDu.cpp",
],
}
@@ -142,3 +153,12 @@ filegroup {
"platform/platformmeson.cpp",
],
}
+
+// Used by hwcomposer.drm_mediatek
+filegroup {
+ name: "drm_hwcomposer_platformmediatek",
+ srcs: [
+ "platform/platformdrmgeneric.cpp",
+ "platform/platformmediatek.cpp",
+ ],
+}
diff --git a/drmhwctwo.cpp b/DrmHwcTwo.cpp
index a847c35..65a317c 100644
--- a/drmhwctwo.cpp
+++ b/DrmHwcTwo.cpp
@@ -17,20 +17,19 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#define LOG_TAG "hwc-drm-two"
-#include "drmhwctwo.h"
-#include "drmdisplaycomposition.h"
-#include "drmhwcomposer.h"
-#include "platform.h"
-#include "vsyncworker.h"
-
-#include <inttypes.h>
-#include <string>
+#include "DrmHwcTwo.h"
#include <cutils/properties.h>
#include <hardware/hardware.h>
#include <hardware/hwcomposer2.h>
+#include <inttypes.h>
#include <log/log.h>
+#include <string>
+
+#include "backend/BackendManager.h"
+#include "compositor/DrmDisplayComposition.h"
+
namespace android {
class DrmVsyncCallback : public VsyncCallback {
@@ -299,6 +298,12 @@ HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
return HWC2::Error::BadDisplay;
}
+ ret = BackendManager::GetInstance().SetBackendForDisplay(this);
+ if (ret) {
+ ALOGE("Failed to set backend for d=%d %d\n", display, ret);
+ return HWC2::Error::BadDisplay;
+ }
+
return ChosePreferredConfig();
}
@@ -900,92 +905,8 @@ void DrmHwcTwo::HwcDisplay::MarkValidated(
HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
uint32_t *num_requests) {
supported(__func__);
- *num_types = 0;
- *num_requests = 0;
- size_t avail_planes = primary_planes_.size() + overlay_planes_.size();
-
- /*
- * If more layers then planes, save one plane
- * for client composited layers
- */
- if (avail_planes < layers_.size())
- avail_planes--;
-
- std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map, z_map_tmp;
- uint32_t z_index = 0;
- // First create a map of layers and z_order values
- for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
- z_map_tmp.emplace(std::make_pair(l.second.z_order(), &l.second));
- // normalise the map so that the lowest z_order layer has key 0
- for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map_tmp)
- z_map.emplace(std::make_pair(z_index++, l.second));
-
- uint32_t total_pixops = CalcPixOps(z_map, 0, z_map.size()), gpu_pixops = 0;
-
- int client_start = -1, client_size = 0;
- if (compositor_.ShouldFlattenOnClient()) {
- client_start = 0;
- client_size = z_map.size();
- MarkValidated(z_map, client_start, client_size);
- } else {
- for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
- if (!HardwareSupportsLayerType(l.second->sf_type()) ||
- !importer_->CanImportBuffer(l.second->buffer()) ||
- color_transform_hint_ != HAL_COLOR_TRANSFORM_IDENTITY ||
- (l.second->RequireScalingOrPhasing() &&
- resource_manager_->ForcedScalingWithGpu())) {
- if (client_start < 0)
- client_start = l.first;
- client_size = (l.first - client_start) + 1;
- }
- }
-
- int extra_client = (z_map.size() - client_size) - avail_planes;
- if (extra_client > 0) {
- int start = 0, steps;
- if (client_size != 0) {
- int prepend = std::min(client_start, extra_client);
- int append = std::min(int(z_map.size() - (client_start + client_size)),
- extra_client);
- start = client_start - prepend;
- client_size += extra_client;
- steps = 1 + std::min(std::min(append, prepend),
- int(z_map.size()) - (start + client_size));
- } else {
- client_size = extra_client;
- steps = 1 + z_map.size() - extra_client;
- }
-
- gpu_pixops = INT_MAX;
- for (int i = 0; i < steps; i++) {
- uint32_t po = CalcPixOps(z_map, start + i, client_size);
- if (po < gpu_pixops) {
- gpu_pixops = po;
- client_start = start + i;
- }
- }
- }
-
- MarkValidated(z_map, client_start, client_size);
-
- bool testing_needed = !(client_start == 0 && client_size == z_map.size());
-
- if (testing_needed && CreateComposition(true) != HWC2::Error::None) {
- ++total_stats_.failed_kms_validate_;
- gpu_pixops = total_pixops;
- client_size = z_map.size();
- MarkValidated(z_map, 0, client_size);
- }
- }
-
- *num_types = client_size;
-
- total_stats_.frames_flattened_ = compositor_.GetFlattenedFramesCount();
- total_stats_.gpu_pixops_ += gpu_pixops;
- total_stats_.total_pixops_ += total_pixops;
-
- return *num_types ? HWC2::Error::HasChanges : HWC2::Error::None;
+ return backend_->ValidateDisplay(this, num_types, num_requests);
}
#if PLATFORM_SDK_VERSION > 28
@@ -994,17 +915,12 @@ HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayIdentificationData(
supported(__func__);
drmModePropertyBlobPtr blob;
- int ret;
- uint64_t blob_id;
- std::tie(ret, blob_id) = connector_->edid_property().value();
- if (ret) {
+ if (connector_->GetEdidBlob(blob)) {
ALOGE("Failed to get edid property value.");
return HWC2::Error::Unsupported;
}
- blob = drmModeGetPropertyBlob(drm_->fd(), blob_id);
-
if (outData) {
*outDataSize = std::min(*outDataSize, blob->length);
memcpy(outData, blob->data, *outDataSize);
diff --git a/include/drmhwctwo.h b/DrmHwcTwo.h
index 1f226bc..ca7a00b 100644
--- a/include/drmhwctwo.h
+++ b/DrmHwcTwo.h
@@ -14,20 +14,25 @@
* limitations under the License.
*/
-#include "drmdisplaycompositor.h"
-#include "drmhwcomposer.h"
-#include "platform.h"
-#include "resourcemanager.h"
-#include "vsyncworker.h"
+#ifndef ANDROID_DRM_HWC_TWO_H_
+#define ANDROID_DRM_HWC_TWO_H_
#include <hardware/hwcomposer2.h>
-
#include <math.h>
+
#include <array>
#include <map>
+#include "compositor/DrmDisplayCompositor.h"
+#include "drm/ResourceManager.h"
+#include "drm/VSyncWorker.h"
+#include "drmhwcomposer.h"
+#include "platform/platform.h"
+
namespace android {
+class Backend;
+
class DrmHwcTwo : public hwc2_device_t {
public:
static int HookDevOpen(const struct hw_module_t *module, const char *name,
@@ -37,7 +42,6 @@ class DrmHwcTwo : public hwc2_device_t {
HWC2::Error Init();
- private:
class HwcLayer {
public:
HWC2::Composition sf_type() const {
@@ -165,6 +169,12 @@ class DrmHwcTwo : public hwc2_device_t {
hwc2_function_pointer_t func);
void RegisterRefreshCallback(hwc2_callback_data_t data,
hwc2_function_pointer_t func);
+ HWC2::Error CreateComposition(bool test);
+ bool HardwareSupportsLayerType(HWC2::Composition comp_type);
+ uint32_t CalcPixOps(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map,
+ size_t first_z, size_t size);
+ void MarkValidated(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map,
+ size_t client_first_z, size_t client_size);
void ClearDisplay();
@@ -229,14 +239,74 @@ class DrmHwcTwo : public hwc2_device_t {
return &it->second;
}
+ /* Statistics */
+ struct Stats {
+ Stats minus(Stats b) {
+ return {total_frames_ - b.total_frames_,
+ total_pixops_ - b.total_pixops_,
+ gpu_pixops_ - b.gpu_pixops_,
+ failed_kms_validate_ - b.failed_kms_validate_,
+ failed_kms_present_ - b.failed_kms_present_,
+ frames_flattened_ - b.frames_flattened_};
+ }
+
+ uint32_t total_frames_ = 0;
+ uint64_t total_pixops_ = 0;
+ uint64_t gpu_pixops_ = 0;
+ uint32_t failed_kms_validate_ = 0;
+ uint32_t failed_kms_present_ = 0;
+ uint32_t frames_flattened_ = 0;
+ };
+
+ const Backend *backend() const {
+ return backend_.get();
+ }
+ void set_backend(std::unique_ptr<Backend> backend) {
+ backend_ = std::move(backend);
+ }
+
+ const std::vector<DrmPlane *> &primary_planes() const {
+ return primary_planes_;
+ }
+
+ const std::vector<DrmPlane *> &overlay_planes() const {
+ return overlay_planes_;
+ }
+
+ std::map<hwc2_layer_t, HwcLayer> &layers() {
+ return layers_;
+ }
+
+ const DrmDisplayCompositor &compositor() const {
+ return compositor_;
+ }
+
+ const DrmDevice *drm() const {
+ return drm_;
+ }
+
+ const DrmConnector *connector() const {
+ return connector_;
+ }
+
+ const std::shared_ptr<Importer> &importer() const {
+ return importer_;
+ }
+
+ ResourceManager *resource_manager() const {
+ return resource_manager_;
+ }
+
+ android_color_transform_t &color_transform_hint() {
+ return color_transform_hint_;
+ }
+
+ Stats &total_stats() {
+ return total_stats_;
+ }
+
private:
- HWC2::Error CreateComposition(bool test);
void AddFenceToPresentFence(int fd);
- bool HardwareSupportsLayerType(HWC2::Composition comp_type);
- uint32_t CalcPixOps(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map,
- size_t first_z, size_t size);
- void MarkValidated(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map,
- size_t client_first_z, size_t client_size);
constexpr static size_t MATRIX_SIZE = 16;
@@ -249,6 +319,8 @@ class DrmHwcTwo : public hwc2_device_t {
std::vector<DrmPlane *> primary_planes_;
std::vector<DrmPlane *> overlay_planes_;
+ std::unique_ptr<Backend> backend_;
+
VSyncWorker vsync_worker_;
DrmConnector *connector_ = NULL;
DrmCrtc *crtc_ = NULL;
@@ -263,24 +335,8 @@ class DrmHwcTwo : public hwc2_device_t {
android_color_transform_t color_transform_hint_;
uint32_t frame_no_ = 0;
- /* Statistics */
- struct Stats {
- Stats minus(Stats b) {
- return {total_frames_ - b.total_frames_,
- total_pixops_ - b.total_pixops_,
- gpu_pixops_ - b.gpu_pixops_,
- failed_kms_validate_ - b.failed_kms_validate_,
- failed_kms_present_ - b.failed_kms_present_,
- frames_flattened_ - b.frames_flattened_};
- }
-
- uint32_t total_frames_ = 0;
- uint64_t total_pixops_ = 0;
- uint64_t gpu_pixops_ = 0;
- uint32_t failed_kms_validate_ = 0;
- uint32_t failed_kms_present_ = 0;
- uint32_t frames_flattened_ = 0;
- } total_stats_, prev_stats_;
+ Stats total_stats_;
+ Stats prev_stats_;
std::string DumpDelta(DrmHwcTwo::HwcDisplay::Stats delta);
};
@@ -296,6 +352,7 @@ class DrmHwcTwo : public hwc2_device_t {
DrmDevice *drm_;
};
+ private:
static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) {
return static_cast<DrmHwcTwo *>(dev);
}
@@ -370,3 +427,5 @@ class DrmHwcTwo : public hwc2_device_t {
std::string mDumpString;
};
} // namespace android
+
+#endif
diff --git a/backend/Backend.cpp b/backend/Backend.cpp
new file mode 100644
index 0000000..50ef900
--- /dev/null
+++ b/backend/Backend.cpp
@@ -0,0 +1,136 @@
+/*
+ * 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 "Backend.h"
+
+#include "BackendManager.h"
+
+namespace android {
+
+HWC2::Error Backend::ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
+ uint32_t *num_types,
+ uint32_t *num_requests) {
+ *num_types = 0;
+ *num_requests = 0;
+ size_t avail_planes = display->primary_planes().size() +
+ display->overlay_planes().size();
+
+ /*
+ * If more layers then planes, save one plane
+ * for client composited layers
+ */
+ if (avail_planes < display->layers().size())
+ avail_planes--;
+
+ std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map, z_map_tmp;
+ uint32_t z_index = 0;
+ // First create a map of layers and z_order values
+ for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l :
+ display->layers())
+ z_map_tmp.emplace(std::make_pair(l.second.z_order(), &l.second));
+ // normalise the map so that the lowest z_order layer has key 0
+ for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map_tmp)
+ z_map.emplace(std::make_pair(z_index++, l.second));
+
+ uint32_t total_pixops = display->CalcPixOps(z_map, 0, z_map.size());
+ uint32_t gpu_pixops = 0;
+
+ int client_start = -1, client_size = 0;
+
+ if (display->compositor().ShouldFlattenOnClient()) {
+ client_start = 0;
+ client_size = z_map.size();
+ display->MarkValidated(z_map, client_start, client_size);
+ } else {
+ std::tie(client_start, client_size) = GetClientLayers(display, z_map);
+
+ int extra_client = (z_map.size() - client_size) - avail_planes;
+ if (extra_client > 0) {
+ int start = 0, steps;
+ if (client_size != 0) {
+ int prepend = std::min(client_start, extra_client);
+ int append = std::min(int(z_map.size() - (client_start + client_size)),
+ extra_client);
+ start = client_start - prepend;
+ client_size += extra_client;
+ steps = 1 + std::min(std::min(append, prepend),
+ int(z_map.size()) - (start + client_size));
+ } else {
+ client_size = extra_client;
+ steps = 1 + z_map.size() - extra_client;
+ }
+
+ gpu_pixops = INT_MAX;
+ for (int i = 0; i < steps; i++) {
+ uint32_t po = display->CalcPixOps(z_map, start + i, client_size);
+ if (po < gpu_pixops) {
+ gpu_pixops = po;
+ client_start = start + i;
+ }
+ }
+ }
+
+ display->MarkValidated(z_map, client_start, client_size);
+
+ bool testing_needed = !(client_start == 0 && client_size == z_map.size());
+
+ if (testing_needed &&
+ display->CreateComposition(true) != HWC2::Error::None) {
+ ++display->total_stats().failed_kms_validate_;
+ gpu_pixops = total_pixops;
+ client_size = z_map.size();
+ display->MarkValidated(z_map, 0, client_size);
+ }
+ }
+
+ *num_types = client_size;
+
+ display->total_stats().frames_flattened_ = display->compositor()
+ .GetFlattenedFramesCount();
+ display->total_stats().gpu_pixops_ += gpu_pixops;
+ display->total_stats().total_pixops_ += total_pixops;
+
+ return *num_types ? HWC2::Error::HasChanges : HWC2::Error::None;
+}
+
+std::tuple<int, int> Backend::GetClientLayers(
+ DrmHwcTwo::HwcDisplay *display,
+ const std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map) {
+ int client_start = -1, client_size = 0;
+
+ for (auto & [ z_order, layer ] : z_map) {
+ if (IsClientLayer(display, layer)) {
+ if (client_start < 0)
+ client_start = z_order;
+ client_size = (z_order - client_start) + 1;
+ }
+ }
+
+ return std::make_tuple(client_start, client_size);
+}
+
+bool Backend::IsClientLayer(DrmHwcTwo::HwcDisplay *display,
+ DrmHwcTwo::HwcLayer *layer) {
+ return !display->HardwareSupportsLayerType(layer->sf_type()) ||
+ !display->importer()->CanImportBuffer(layer->buffer()) ||
+ display->color_transform_hint() != HAL_COLOR_TRANSFORM_IDENTITY ||
+ (layer->RequireScalingOrPhasing() &&
+ display->resource_manager()->ForcedScalingWithGpu());
+}
+
+REGISTER_BACKEND("generic", Backend);
+
+} // namespace android
diff --git a/backend/Backend.h b/backend/Backend.h
new file mode 100644
index 0000000..898fece
--- /dev/null
+++ b/backend/Backend.h
@@ -0,0 +1,38 @@
+/*
+ * 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_BACKEND_H
+#define ANDROID_BACKEND_H
+
+#include "DrmHwcTwo.h"
+
+namespace android {
+
+class Backend {
+ public:
+ virtual ~Backend() = default;
+ virtual HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
+ uint32_t *num_types,
+ uint32_t *num_requests);
+ virtual std::tuple<int, int> GetClientLayers(
+ DrmHwcTwo::HwcDisplay *display,
+ const std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map);
+ virtual bool IsClientLayer(DrmHwcTwo::HwcDisplay *display,
+ DrmHwcTwo::HwcLayer *layer);
+};
+} // namespace android
+
+#endif
diff --git a/backend/BackendClient.cpp b/backend/BackendClient.cpp
new file mode 100644
index 0000000..033a35c
--- /dev/null
+++ b/backend/BackendClient.cpp
@@ -0,0 +1,35 @@
+/*
+ * 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 "BackendClient.h"
+
+#include "BackendManager.h"
+
+namespace android {
+
+HWC2::Error BackendClient::ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
+ uint32_t *num_types,
+ uint32_t * /*num_requests*/) {
+ for (auto & [ layer_handle, layer ] : display->layers()) {
+ layer.set_validated_type(HWC2::Composition::Client);
+ ++*num_types;
+ }
+ return HWC2::Error::HasChanges;
+}
+
+REGISTER_BACKEND("client", BackendClient);
+
+} // namespace android
diff --git a/backend/BackendClient.h b/backend/BackendClient.h
new file mode 100644
index 0000000..13543f1
--- /dev/null
+++ b/backend/BackendClient.h
@@ -0,0 +1,32 @@
+/*
+ * 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_BACKEND_CLIENT_H
+#define ANDROID_BACKEND_CLIENT_H
+
+#include "Backend.h"
+
+namespace android {
+
+class BackendClient : public Backend {
+ public:
+ HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
+ uint32_t *num_types,
+ uint32_t *num_requests) override;
+};
+} // namespace android
+
+#endif
diff --git a/backend/BackendManager.cpp b/backend/BackendManager.cpp
new file mode 100644
index 0000000..0bacdcd
--- /dev/null
+++ b/backend/BackendManager.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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-backend"
+
+#include "BackendManager.h"
+
+#include <cutils/properties.h>
+#include <log/log.h>
+
+namespace android {
+
+const std::vector<std::string> BackendManager::client_devices_ = {
+ "kirin",
+ "mediatek-drm",
+};
+
+BackendManager &BackendManager::GetInstance() {
+ static BackendManager backend_manager;
+
+ return backend_manager;
+}
+
+int BackendManager::RegisterBackend(const std::string &name,
+ backend_constructor_t backend_constructor) {
+ available_backends_[name] = std::move(backend_constructor);
+ return 0;
+}
+
+int BackendManager::SetBackendForDisplay(DrmHwcTwo::HwcDisplay *display) {
+ std::string driver_name(display->drm()->GetName());
+ char backend_override[PROPERTY_VALUE_MAX];
+ property_get("vendor.hwc.backend_override", backend_override,
+ driver_name.c_str());
+ std::string backend_name(std::move(backend_override));
+
+ display->set_backend(GetBackendByName(backend_name));
+ if (!display->backend()) {
+ ALOGE("Failed to set backend '%s' for '%s' and driver '%s'",
+ backend_name.c_str(), display->connector()->name().c_str(),
+ driver_name.c_str());
+ return -EINVAL;
+ }
+
+ ALOGI("Backend '%s' for '%s' and driver '%s' was successfully set",
+ backend_name.c_str(), display->connector()->name().c_str(),
+ driver_name.c_str());
+
+ return 0;
+}
+
+std::unique_ptr<Backend> BackendManager::GetBackendByName(std::string &name) {
+ if (!available_backends_.size()) {
+ ALOGE("No backends are specified");
+ return nullptr;
+ }
+
+ auto it = available_backends_.find(name);
+ if (it == available_backends_.end()) {
+ auto it = std::find(client_devices_.begin(), client_devices_.end(), name);
+ name = it == client_devices_.end() ? "generic" : "client";
+ }
+
+ return available_backends_[name]();
+}
+} // namespace android
diff --git a/backend/BackendManager.h b/backend/BackendManager.h
new file mode 100644
index 0000000..e86c098
--- /dev/null
+++ b/backend/BackendManager.h
@@ -0,0 +1,57 @@
+/*
+ * 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_BACKEND_MANAGER_H
+#define ANDROID_BACKEND_MANAGER_H
+
+#include <functional>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "Backend.h"
+
+#define REGISTER_BACKEND(name_str_, backend_) \
+ static int \
+ backend = BackendManager::GetInstance() \
+ .RegisterBackend(name_str_, \
+ []() -> std::unique_ptr<Backend> { \
+ return std::make_unique<backend_>(); \
+ });
+
+namespace android {
+
+class BackendManager {
+ public:
+ using backend_constructor_t = std::function<std::unique_ptr<Backend>()>;
+ static BackendManager &GetInstance();
+ int RegisterBackend(const std::string &name,
+ backend_constructor_t backend_constructor);
+ int SetBackendForDisplay(DrmHwcTwo::HwcDisplay *display);
+ std::unique_ptr<Backend> GetBackendByName(std::string &name);
+ HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
+ uint32_t *num_types, uint32_t *num_requests);
+
+ private:
+ BackendManager() = default;
+
+ static const std::vector<std::string> client_devices_;
+
+ std::map<std::string, backend_constructor_t> available_backends_;
+};
+} // namespace android
+
+#endif
diff --git a/backend/BackendRCarDu.cpp b/backend/BackendRCarDu.cpp
new file mode 100644
index 0000000..d52f0c3
--- /dev/null
+++ b/backend/BackendRCarDu.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "BackendRCarDu.h"
+
+#include "BackendManager.h"
+#include "drm_fourcc.h"
+
+namespace android {
+
+bool BackendRCarDu::IsClientLayer(DrmHwcTwo::HwcDisplay *display,
+ DrmHwcTwo::HwcLayer *layer) {
+ hwc_drm_bo_t bo;
+
+ int ret = display->importer()->ConvertBoInfo(layer->buffer(), &bo);
+ if (ret)
+ return true;
+
+ if (bo.format == DRM_FORMAT_ABGR8888)
+ return true;
+
+ if (layer->RequireScalingOrPhasing())
+ return true;
+
+ return Backend::IsClientLayer(display, layer);
+}
+
+REGISTER_BACKEND("rcar-du", BackendRCarDu);
+
+} // namespace android \ No newline at end of file
diff --git a/backend/BackendRCarDu.h b/backend/BackendRCarDu.h
new file mode 100644
index 0000000..8a1011a
--- /dev/null
+++ b/backend/BackendRCarDu.h
@@ -0,0 +1,31 @@
+/*
+ * 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 HWC_DISPLAY_BACKEND_RCAR_DU_H
+#define HWC_DISPLAY_BACKEND_RCAR_DU_H
+
+#include "Backend.h"
+
+namespace android {
+
+class BackendRCarDu : public Backend {
+ public:
+ bool IsClientLayer(DrmHwcTwo::HwcDisplay *display,
+ DrmHwcTwo::HwcLayer *layer) override;
+};
+} // namespace android
+
+#endif
diff --git a/compositor/drmdisplaycomposition.cpp b/compositor/DrmDisplayComposition.cpp
index b710fe1..79dd470 100644
--- a/compositor/drmdisplaycomposition.cpp
+++ b/compositor/DrmDisplayComposition.cpp
@@ -16,21 +16,19 @@
#define LOG_TAG "hwc-drm-display-composition"
-#include "drmdisplaycomposition.h"
-#include "drmcrtc.h"
-#include "drmdevice.h"
-#include "drmdisplaycompositor.h"
-#include "drmplane.h"
-#include "platform.h"
+#include "DrmDisplayComposition.h"
+#include <log/log.h>
#include <stdlib.h>
+#include <sync/sync.h>
+#include <xf86drmMode.h>
#include <algorithm>
#include <unordered_set>
-#include <log/log.h>
-#include <sync/sync.h>
-#include <xf86drmMode.h>
+#include "DrmDisplayCompositor.h"
+#include "drm/DrmDevice.h"
+#include "platform/platform.h"
namespace android {
diff --git a/include/drmdisplaycomposition.h b/compositor/DrmDisplayComposition.h
index 2a5b1a4..73a9024 100644
--- a/include/drmdisplaycomposition.h
+++ b/compositor/DrmDisplayComposition.h
@@ -17,15 +17,15 @@
#ifndef ANDROID_DRM_DISPLAY_COMPOSITION_H_
#define ANDROID_DRM_DISPLAY_COMPOSITION_H_
-#include "drmcrtc.h"
-#include "drmhwcomposer.h"
-#include "drmplane.h"
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
#include <sstream>
#include <vector>
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
+#include "drm/DrmCrtc.h"
+#include "drm/DrmPlane.h"
+#include "drmhwcomposer.h"
namespace android {
diff --git a/compositor/drmdisplaycompositor.cpp b/compositor/DrmDisplayCompositor.cpp
index 1519736..467f8ba 100644
--- a/compositor/drmdisplaycompositor.cpp
+++ b/compositor/DrmDisplayCompositor.cpp
@@ -17,25 +17,25 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#define LOG_TAG "hwc-drm-display-compositor"
-#include "drmdisplaycompositor.h"
+#include "DrmDisplayCompositor.h"
+#include <drm/drm_mode.h>
+#include <log/log.h>
#include <pthread.h>
#include <sched.h>
#include <stdlib.h>
+#include <sync/sync.h>
#include <time.h>
+#include <utils/Trace.h>
+
#include <array>
#include <sstream>
#include <vector>
-#include <drm/drm_mode.h>
-#include <log/log.h>
-#include <sync/sync.h>
-#include <utils/Trace.h>
-
-#include "autolock.h"
-#include "drmcrtc.h"
-#include "drmdevice.h"
-#include "drmplane.h"
+#include "drm/DrmCrtc.h"
+#include "drm/DrmDevice.h"
+#include "drm/DrmPlane.h"
+#include "utils/autolock.h"
static const uint32_t kWaitWritebackFence = 100; // ms
diff --git a/include/drmdisplaycompositor.h b/compositor/DrmDisplayCompositor.h
index 26e2572..e500c9e 100644
--- a/include/drmdisplaycompositor.h
+++ b/compositor/DrmDisplayCompositor.h
@@ -17,19 +17,19 @@
#ifndef ANDROID_DRM_DISPLAY_COMPOSITOR_H_
#define ANDROID_DRM_DISPLAY_COMPOSITOR_H_
-#include "drmdisplaycomposition.h"
-#include "drmframebuffer.h"
-#include "drmhwcomposer.h"
-#include "resourcemanager.h"
-#include "vsyncworker.h"
-
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
#include <pthread.h>
+
#include <memory>
#include <sstream>
#include <tuple>
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
+#include "DrmDisplayComposition.h"
+#include "DrmFramebuffer.h"
+#include "drm/ResourceManager.h"
+#include "drm/VSyncWorker.h"
+#include "drmhwcomposer.h"
// One for the front, one for the back, and one for cases where we need to
// squash a frame that the hw can't display with hw overlays.
diff --git a/drm/drmconnector.cpp b/drm/DrmConnector.cpp
index 81c2b98..f1b6c1b 100644
--- a/drm/drmconnector.cpp
+++ b/drm/DrmConnector.cpp
@@ -16,17 +16,17 @@
#define LOG_TAG "hwc-drm-connector"
-#include "drmconnector.h"
-#include "drmdevice.h"
+#include "DrmConnector.h"
#include <errno.h>
+#include <log/log.h>
#include <stdint.h>
+#include <xf86drmMode.h>
#include <array>
#include <sstream>
-#include <log/log.h>
-#include <xf86drmMode.h>
+#include "DrmDevice.h"
namespace android {
@@ -58,10 +58,7 @@ int DrmConnector::Init() {
ALOGE("Could not get CRTC_ID property\n");
return ret;
}
- ret = drm_->GetConnectorProperty(*this, "EDID", &edid_property_);
- if (ret) {
- ALOGW("Could not get EDID property\n");
- }
+ ret = UpdateEdidProperty();
if (writeback()) {
ret = drm_->GetConnectorProperty(*this, "WRITEBACK_PIXEL_FORMATS",
&writeback_pixel_formats_);
@@ -85,6 +82,30 @@ int DrmConnector::Init() {
return 0;
}
+int DrmConnector::UpdateEdidProperty() {
+ int ret = drm_->GetConnectorProperty(*this, "EDID", &edid_property_);
+ if (ret) {
+ ALOGW("Could not get EDID property\n");
+ }
+ return ret;
+}
+
+int DrmConnector::GetEdidBlob(drmModePropertyBlobPtr &blob) {
+ uint64_t blob_id;
+ int ret = UpdateEdidProperty();
+ if (ret) {
+ return ret;
+ }
+
+ std::tie(ret, blob_id) = edid_property().value();
+ if (ret) {
+ return ret;
+ }
+
+ blob = drmModeGetPropertyBlob(drm_->fd(), blob_id);
+ return !blob;
+}
+
uint32_t DrmConnector::id() const {
return id_;
}
diff --git a/include/drmconnector.h b/drm/DrmConnector.h
index dc64b38..8533af8 100644
--- a/include/drmconnector.h
+++ b/drm/DrmConnector.h
@@ -17,15 +17,16 @@
#ifndef ANDROID_DRM_CONNECTOR_H_
#define ANDROID_DRM_CONNECTOR_H_
-#include "drmencoder.h"
-#include "drmmode.h"
-#include "drmproperty.h"
-
#include <stdint.h>
#include <xf86drmMode.h>
+
#include <string>
#include <vector>
+#include "DrmEncoder.h"
+#include "DrmMode.h"
+#include "DrmProperty.h"
+
namespace android {
class DrmDevice;
@@ -39,6 +40,8 @@ class DrmConnector {
DrmConnector &operator=(const DrmProperty &) = delete;
int Init();
+ int UpdateEdidProperty();
+ int GetEdidBlob(drmModePropertyBlobPtr &blob);
uint32_t id() const;
diff --git a/drm/drmcrtc.cpp b/drm/DrmCrtc.cpp
index b627291..4ce8cfc 100644
--- a/drm/drmcrtc.cpp
+++ b/drm/DrmCrtc.cpp
@@ -16,13 +16,13 @@
#define LOG_TAG "hwc-drm-crtc"
-#include "drmcrtc.h"
-#include "drmdevice.h"
+#include "DrmCrtc.h"
+#include <log/log.h>
#include <stdint.h>
#include <xf86drmMode.h>
-#include <log/log.h>
+#include "DrmDevice.h"
namespace android {
diff --git a/include/drmcrtc.h b/drm/DrmCrtc.h
index 3075f9b..7972bef 100644
--- a/include/drmcrtc.h
+++ b/drm/DrmCrtc.h
@@ -17,12 +17,12 @@
#ifndef ANDROID_DRM_CRTC_H_
#define ANDROID_DRM_CRTC_H_
-#include "drmmode.h"
-#include "drmproperty.h"
-
#include <stdint.h>
#include <xf86drmMode.h>
+#include "DrmMode.h"
+#include "DrmProperty.h"
+
namespace android {
class DrmDevice;
diff --git a/drm/drmdevice.cpp b/drm/DrmDevice.cpp
index d7fd2f2..28ecfda 100644
--- a/drm/drmdevice.cpp
+++ b/drm/DrmDevice.cpp
@@ -16,27 +16,21 @@
#define LOG_TAG "hwc-drm-device"
-#include "drmdevice.h"
-#include "drmconnector.h"
-#include "drmcrtc.h"
-#include "drmencoder.h"
-#include "drmeventlistener.h"
-#include "drmplane.h"
+#include "DrmDevice.h"
+#include <cutils/properties.h>
#include <errno.h>
#include <fcntl.h>
+#include <log/log.h>
#include <stdint.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
-#include <cinttypes>
#include <algorithm>
#include <array>
+#include <cinttypes>
#include <string>
-#include <cutils/properties.h>
-#include <log/log.h>
-
static void trim_left(std::string &str) {
str.erase(std::begin(str),
std::find_if(std::begin(str), std::end(str),
@@ -570,4 +564,16 @@ int DrmDevice::GetConnectorProperty(const DrmConnector &connector,
return GetProperty(connector.id(), DRM_MODE_OBJECT_CONNECTOR, prop_name,
property);
}
+
+const std::string DrmDevice::GetName() const {
+ auto ver = drmGetVersion(fd_.get());
+ if (!ver) {
+ ALOGW("Failed to get drm version for fd=%d", fd_.get());
+ return "generic";
+ }
+
+ std::string name(ver->name);
+ drmFreeVersion(ver);
+ return name;
+}
} // namespace android
diff --git a/include/drmdevice.h b/drm/DrmDevice.h
index 91dd38b..d7ea359 100644
--- a/include/drmdevice.h
+++ b/drm/DrmDevice.h
@@ -17,16 +17,17 @@
#ifndef ANDROID_DRM_H_
#define ANDROID_DRM_H_
-#include "drmconnector.h"
-#include "drmcrtc.h"
-#include "drmencoder.h"
-#include "drmeventlistener.h"
-#include "drmplane.h"
-#include "platform.h"
-
#include <stdint.h>
+
#include <tuple>
+#include "DrmConnector.h"
+#include "DrmCrtc.h"
+#include "DrmEncoder.h"
+#include "DrmEventListener.h"
+#include "DrmPlane.h"
+#include "platform/platform.h"
+
namespace android {
class DrmDevice {
@@ -70,6 +71,8 @@ class DrmDevice {
int GetConnectorProperty(const DrmConnector &connector, const char *prop_name,
DrmProperty *property);
+ const std::string GetName() const;
+
const std::vector<std::unique_ptr<DrmCrtc>> &crtcs() const;
uint32_t next_mode_id();
diff --git a/drm/drmencoder.cpp b/drm/DrmEncoder.cpp
index c36fca1..bcf0926 100644
--- a/drm/drmencoder.cpp
+++ b/drm/DrmEncoder.cpp
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-#include "drmencoder.h"
-#include "drmcrtc.h"
-#include "drmdevice.h"
+#include "DrmEncoder.h"
#include <stdint.h>
#include <xf86drmMode.h>
+#include "DrmDevice.h"
+
namespace android {
DrmEncoder::DrmEncoder(drmModeEncoderPtr e, DrmCrtc *current_crtc,
diff --git a/include/drmencoder.h b/drm/DrmEncoder.h
index 8a7f682..f4464d0 100644
--- a/include/drmencoder.h
+++ b/drm/DrmEncoder.h
@@ -17,13 +17,14 @@
#ifndef ANDROID_DRM_ENCODER_H_
#define ANDROID_DRM_ENCODER_H_
-#include "drmcrtc.h"
-
#include <stdint.h>
#include <xf86drmMode.h>
+
#include <set>
#include <vector>
+#include "DrmCrtc.h"
+
namespace android {
class DrmEncoder {
diff --git a/drm/drmeventlistener.cpp b/drm/DrmEventListener.cpp
index ccee0d6..3d95e28 100644
--- a/drm/drmeventlistener.cpp
+++ b/drm/DrmEventListener.cpp
@@ -16,19 +16,19 @@
#define LOG_TAG "hwc-drm-event-listener"
-#include "drmeventlistener.h"
-#include "drmdevice.h"
+#include "DrmEventListener.h"
#include <assert.h>
#include <errno.h>
-#include <linux/netlink.h>
-#include <sys/socket.h>
-
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
+#include <linux/netlink.h>
#include <log/log.h>
+#include <sys/socket.h>
#include <xf86drm.h>
+#include "DrmDevice.h"
+
namespace android {
DrmEventListener::DrmEventListener(DrmDevice *drm)
diff --git a/include/drmeventlistener.h b/drm/DrmEventListener.h
index 95672ee..9f9a4ba 100644
--- a/include/drmeventlistener.h
+++ b/drm/DrmEventListener.h
@@ -18,7 +18,7 @@
#define ANDROID_DRM_EVENT_LISTENER_H_
#include "autofd.h"
-#include "worker.h"
+#include "utils/Worker.h"
namespace android {
diff --git a/drm/drmmode.cpp b/drm/DrmMode.cpp
index c3ab385..6de671a 100644
--- a/drm/drmmode.cpp
+++ b/drm/DrmMode.cpp
@@ -14,12 +14,9 @@
* limitations under the License.
*/
-#include "drmmode.h"
-#include "drmdevice.h"
+#include "DrmMode.h"
-#include <stdint.h>
-#include <xf86drmMode.h>
-#include <string>
+#include "DrmDevice.h"
namespace android {
diff --git a/include/drmmode.h b/drm/DrmMode.h
index 4cc06b1..313a8ea 100644
--- a/include/drmmode.h
+++ b/drm/DrmMode.h
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <xf86drmMode.h>
+
#include <string>
namespace android {
diff --git a/drm/drmplane.cpp b/drm/DrmPlane.cpp
index 6f1bf9b..f994252 100644
--- a/drm/drmplane.cpp
+++ b/drm/DrmPlane.cpp
@@ -16,20 +16,23 @@
#define LOG_TAG "hwc-drm-plane"
-#include "drmplane.h"
-#include "drmdevice.h"
+#include "DrmPlane.h"
#include <errno.h>
+#include <log/log.h>
#include <stdint.h>
+
#include <cinttypes>
-#include <log/log.h>
-#include <xf86drmMode.h>
+#include "DrmDevice.h"
namespace android {
DrmPlane::DrmPlane(DrmDevice *drm, drmModePlanePtr p)
- : drm_(drm), id_(p->plane_id), possible_crtc_mask_(p->possible_crtcs) {
+ : drm_(drm),
+ id_(p->plane_id),
+ possible_crtc_mask_(p->possible_crtcs),
+ formats_(p->formats, p->formats + p->count_formats) {
}
int DrmPlane::Init() {
@@ -153,6 +156,11 @@ uint32_t DrmPlane::type() const {
return type_;
}
+bool DrmPlane::IsFormatSupported(uint32_t format) const {
+ return std::find(std::begin(formats_), std::end(formats_), format) !=
+ std::end(formats_);
+}
+
const DrmProperty &DrmPlane::crtc_property() const {
return crtc_property_;
}
diff --git a/include/drmplane.h b/drm/DrmPlane.h
index 43e0e8a..16731a8 100644
--- a/include/drmplane.h
+++ b/drm/DrmPlane.h
@@ -17,13 +17,14 @@
#ifndef ANDROID_DRM_PLANE_H_
#define ANDROID_DRM_PLANE_H_
-#include "drmcrtc.h"
-#include "drmproperty.h"
-
#include <stdint.h>
#include <xf86drmMode.h>
+
#include <vector>
+#include "DrmCrtc.h"
+#include "DrmProperty.h"
+
namespace android {
class DrmDevice;
@@ -42,6 +43,8 @@ class DrmPlane {
uint32_t type() const;
+ bool IsFormatSupported(uint32_t format) const;
+
const DrmProperty &crtc_property() const;
const DrmProperty &fb_property() const;
const DrmProperty &crtc_x_property() const;
@@ -66,6 +69,8 @@ class DrmPlane {
uint32_t type_;
+ std::vector<uint32_t> formats_;
+
DrmProperty crtc_property_;
DrmProperty fb_property_;
DrmProperty crtc_x_property_;
diff --git a/drm/drmproperty.cpp b/drm/DrmProperty.cpp
index 3aeed13..b60a76e 100644
--- a/drm/drmproperty.cpp
+++ b/drm/DrmProperty.cpp
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-#include "drmproperty.h"
-#include "drmdevice.h"
+#include "DrmProperty.h"
#include <errno.h>
#include <stdint.h>
+#include <xf86drmMode.h>
+
#include <string>
-#include <xf86drmMode.h>
+#include "DrmDevice.h"
namespace android {
diff --git a/include/drmproperty.h b/drm/DrmProperty.h
index 2d92ca1..d293da3 100644
--- a/include/drmproperty.h
+++ b/drm/DrmProperty.h
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <xf86drmMode.h>
+
#include <string>
#include <vector>
diff --git a/drm/resourcemanager.cpp b/drm/ResourceManager.cpp
index 986d4ab..67ef7f8 100644
--- a/drm/resourcemanager.cpp
+++ b/drm/ResourceManager.cpp
@@ -16,13 +16,13 @@
#define LOG_TAG "hwc-resource-manager"
-#include "resourcemanager.h"
+#include "ResourceManager.h"
#include <cutils/properties.h>
#include <log/log.h>
#include <sys/stat.h>
+
#include <sstream>
-#include <string>
namespace android {
diff --git a/include/resourcemanager.h b/drm/ResourceManager.h
index 9fefb46..94ba43e 100644
--- a/include/resourcemanager.h
+++ b/drm/ResourceManager.h
@@ -17,11 +17,11 @@
#ifndef RESOURCEMANAGER_H
#define RESOURCEMANAGER_H
-#include "drmdevice.h"
-#include "platform.h"
-
#include <string.h>
+#include "DrmDevice.h"
+#include "platform/platform.h"
+
namespace android {
class ResourceManager {
diff --git a/drm/vsyncworker.cpp b/drm/VSyncWorker.cpp
index 08ab301..dfbf8ce 100644
--- a/drm/vsyncworker.cpp
+++ b/drm/VSyncWorker.cpp
@@ -16,18 +16,13 @@
#define LOG_TAG "hwc-vsync-worker"
-#include "vsyncworker.h"
-#include "drmdevice.h"
-#include "worker.h"
+#include "VSyncWorker.h"
+#include <log/log.h>
#include <stdlib.h>
#include <time.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
-#include <map>
-
-#include <hardware/hardware.h>
-#include <log/log.h>
namespace android {
diff --git a/include/vsyncworker.h b/drm/VSyncWorker.h
index 96f7432..0121a6c 100644
--- a/include/vsyncworker.h
+++ b/drm/VSyncWorker.h
@@ -17,14 +17,14 @@
#ifndef ANDROID_EVENT_WORKER_H_
#define ANDROID_EVENT_WORKER_H_
-#include "drmdevice.h"
-#include "worker.h"
-
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
#include <stdint.h>
+
#include <map>
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
+#include "DrmDevice.h"
+#include "utils/Worker.h"
namespace android {
diff --git a/include/drmframebuffer.h b/include/DrmFramebuffer.h
index 9032d3a..33ca0db 100644
--- a/include/drmframebuffer.h
+++ b/include/DrmFramebuffer.h
@@ -18,9 +18,7 @@
#define ANDROID_DRM_FRAMEBUFFER_
#include <stdint.h>
-
#include <sync/sync.h>
-
#include <ui/GraphicBuffer.h>
namespace android {
diff --git a/platform/platform.cpp b/platform/platform.cpp
index b7a47c7..a500398 100644
--- a/platform/platform.cpp
+++ b/platform/platform.cpp
@@ -17,10 +17,11 @@
#define LOG_TAG "hwc-platform"
#include "platform.h"
-#include "drmdevice.h"
#include <log/log.h>
+#include "drm/DrmDevice.h"
+
namespace android {
std::vector<DrmPlane *> Planner::GetUsablePlanes(
@@ -77,6 +78,13 @@ int Planner::PlanStage::ValidatePlane(DrmPlane *plane, DrmHwcLayer *layer) {
ALOGE("Expected a valid blend mode on plane %d", plane->id());
}
+ uint32_t format = layer->buffer->format;
+ if (!plane->IsFormatSupported(format)) {
+ ALOGE("Plane %d does not supports %c%c%c%c format", plane->id(), format,
+ format >> 8, format >> 16, format >> 24);
+ return -EINVAL;
+ }
+
return ret;
}
diff --git a/include/platform.h b/platform/platform.h
index 6775e29..13dc360 100644
--- a/include/platform.h
+++ b/platform/platform.h
@@ -17,15 +17,15 @@
#ifndef ANDROID_DRM_PLATFORM_H_
#define ANDROID_DRM_PLATFORM_H_
-#include "drmdisplaycomposition.h"
-#include "drmhwcomposer.h"
-
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
#include <map>
#include <vector>
+#include "compositor/DrmDisplayComposition.h"
+#include "drmhwcomposer.h"
+
namespace android {
class DrmDevice;
diff --git a/platform/platformdrmgeneric.cpp b/platform/platformdrmgeneric.cpp
index bc28dd5..95a1eac 100644
--- a/platform/platformdrmgeneric.cpp
+++ b/platform/platformdrmgeneric.cpp
@@ -17,8 +17,6 @@
#define LOG_TAG "hwc-platform-drm-generic"
#include "platformdrmgeneric.h"
-#include "drmdevice.h"
-#include "platform.h"
#include <xf86drm.h>
#include <xf86drmMode.h>
@@ -47,8 +45,7 @@ Importer *Importer::CreateInstance(DrmDevice *drm) {
}
#endif
-DrmGenericImporter::DrmGenericImporter(DrmDevice *drm)
- : drm_(drm), exclude_non_hwfb_(false) {
+DrmGenericImporter::DrmGenericImporter(DrmDevice *drm) : drm_(drm) {
}
DrmGenericImporter::~DrmGenericImporter() {
@@ -65,14 +62,133 @@ int DrmGenericImporter::Init() {
ALOGI("Using %s gralloc module: %s\n", gralloc_->common.name,
gralloc_->common.author);
- char exclude_non_hwfb_prop[PROPERTY_VALUE_MAX];
- property_get("vendor.hwc.drm.exclude_non_hwfb_imports", exclude_non_hwfb_prop,
- "0");
- exclude_non_hwfb_ = static_cast<bool>(strncmp(exclude_non_hwfb_prop, "0", 1));
-
return 0;
}
+enum chroma_order {
+ YCbCr,
+ YCrCb,
+};
+
+struct droid_yuv_format {
+ /* Lookup keys */
+ int native; /* HAL_PIXEL_FORMAT_ */
+ enum chroma_order chroma_order; /* chroma order is {Cb, Cr} or {Cr, Cb} */
+ int chroma_step; /* Distance in bytes between subsequent chroma pixels. */
+
+ /* Result */
+ int fourcc; /* DRM_FORMAT_ */
+};
+
+/* The following table is used to look up a DRI image FourCC based
+ * on native format and information contained in android_ycbcr struct. */
+static const struct droid_yuv_format droid_yuv_formats[] = {
+ /* Native format, YCrCb, Chroma step, DRI image FourCC */
+ {HAL_PIXEL_FORMAT_YCbCr_420_888, YCbCr, 2, DRM_FORMAT_NV12},
+ {HAL_PIXEL_FORMAT_YCbCr_420_888, YCbCr, 1, DRM_FORMAT_YUV420},
+ {HAL_PIXEL_FORMAT_YCbCr_420_888, YCrCb, 1, DRM_FORMAT_YVU420},
+ {HAL_PIXEL_FORMAT_YV12, YCrCb, 1, DRM_FORMAT_YVU420},
+ /* HACK: See droid_create_image_from_prime_fds() and
+ * https://issuetracker.google.com/32077885. */
+ {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCbCr, 2, DRM_FORMAT_NV12},
+ {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCbCr, 1, DRM_FORMAT_YUV420},
+ {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, DRM_FORMAT_YVU420},
+ {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, DRM_FORMAT_AYUV},
+ {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, DRM_FORMAT_XYUV8888},
+};
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+static int get_fourcc_yuv(int native, enum chroma_order chroma_order,
+ int chroma_step) {
+ for (int i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i)
+ if (droid_yuv_formats[i].native == native &&
+ droid_yuv_formats[i].chroma_order == chroma_order &&
+ droid_yuv_formats[i].chroma_step == chroma_step)
+ return droid_yuv_formats[i].fourcc;
+
+ return -1;
+}
+
+static bool is_yuv(int native) {
+ for (int i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i)
+ if (droid_yuv_formats[i].native == native)
+ return true;
+
+ return false;
+}
+
+bool DrmGenericImporter::GetYuvPlaneInfo(int num_fds, buffer_handle_t handle,
+ hwc_drm_bo_t *bo) {
+ struct android_ycbcr ycbcr;
+ enum chroma_order chroma_order;
+ int ret;
+
+ if (!gralloc_->lock_ycbcr) {
+ static std::once_flag once;
+ std::call_once(once,
+ []() { ALOGW("Gralloc does not support lock_ycbcr()"); });
+ return false;
+ }
+
+ memset(&ycbcr, 0, sizeof(ycbcr));
+ ret = gralloc_->lock_ycbcr(gralloc_, handle, 0, 0, 0, 0, 0, &ycbcr);
+ if (ret) {
+ ALOGW("gralloc->lock_ycbcr failed: %d", ret);
+ return false;
+ }
+ gralloc_->unlock(gralloc_, handle);
+
+ /* When lock_ycbcr's usage argument contains no SW_READ/WRITE flags
+ * it will return the .y/.cb/.cr pointers based on a NULL pointer,
+ * so they can be interpreted as offsets. */
+ bo->offsets[0] = (size_t)ycbcr.y;
+ /* We assume here that all the planes are located in one DMA-buf. */
+ if ((size_t)ycbcr.cr < (size_t)ycbcr.cb) {
+ chroma_order = YCrCb;
+ bo->offsets[1] = (size_t)ycbcr.cr;
+ bo->offsets[2] = (size_t)ycbcr.cb;
+ } else {
+ chroma_order = YCbCr;
+ bo->offsets[1] = (size_t)ycbcr.cb;
+ bo->offsets[2] = (size_t)ycbcr.cr;
+ }
+
+ /* .ystride is the line length (in bytes) of the Y plane,
+ * .cstride is the line length (in bytes) of any of the remaining
+ * Cb/Cr/CbCr planes, assumed to be the same for Cb and Cr for fully
+ * planar formats. */
+ bo->pitches[0] = ycbcr.ystride;
+ bo->pitches[1] = bo->pitches[2] = ycbcr.cstride;
+
+ /* .chroma_step is the byte distance between the same chroma channel
+ * values of subsequent pixels, assumed to be the same for Cb and Cr. */
+ bo->format = get_fourcc_yuv(bo->hal_format, chroma_order, ycbcr.chroma_step);
+ if (bo->format == -1) {
+ ALOGW(
+ "unsupported YUV format, native = %x, chroma_order = %s, chroma_step = "
+ "%d",
+ bo->hal_format, chroma_order == YCbCr ? "YCbCr" : "YCrCb",
+ (int)ycbcr.chroma_step);
+ return false;
+ }
+
+ /*
+ * Since this is EGL_NATIVE_BUFFER_ANDROID don't assume that
+ * the single-fd case cannot happen. So handle eithe single
+ * fd or fd-per-plane case:
+ */
+ if (num_fds == 1) {
+ bo->prime_fds[2] = bo->prime_fds[1] = bo->prime_fds[0];
+ } else {
+ int expected_planes = (ycbcr.chroma_step == 2) ? 2 : 3;
+ if (num_fds != expected_planes)
+ return false;
+ }
+
+ return true;
+}
+
uint32_t DrmGenericImporter::ConvertHalFormatToDrm(uint32_t hal_format) {
switch (hal_format) {
case HAL_PIXEL_FORMAT_RGB_888:
@@ -120,15 +236,36 @@ int DrmGenericImporter::ConvertBoInfo(buffer_handle_t handle,
bo->width = gr_handle->width;
bo->height = gr_handle->height;
bo->hal_format = gr_handle->format;
- bo->format = ConvertHalFormatToDrm(gr_handle->format);
- if (bo->format == DRM_FORMAT_INVALID)
- return -EINVAL;
+
+#if GRALLOC_HANDLE_VERSION < 4
+ static std::once_flag once;
+ std::call_once(once, []() {
+ ALOGE(
+ "libdrm < v2.4.97 has broken gralloc_handle structure. Please update.");
+ });
+#endif
+#if GRALLOC_HANDLE_VERSION == 4
+ bo->modifiers[0] = gr_handle->modifier;
+ bo->with_modifiers = gr_handle->modifier != DRM_FORMAT_MOD_NONE &&
+ gr_handle->modifier != DRM_FORMAT_MOD_INVALID;
+#endif
+
bo->usage = gr_handle->usage;
+ bo->prime_fds[0] = gr_handle->prime_fd;
+
+ if (is_yuv(gr_handle->format)) {
+ if (!GetYuvPlaneInfo(handle->numFds, handle, bo))
+ return -EINVAL;
+ } else {
+ bo->pitches[0] = gr_handle->stride;
+ bo->offsets[0] = 0;
+ bo->format = ConvertHalFormatToDrm(gr_handle->format);
+ if (bo->format == DRM_FORMAT_INVALID)
+ return -EINVAL;
+ }
+
bo->pixel_stride = (gr_handle->stride * 8) /
DrmFormatToBitsPerPixel(bo->format);
- bo->prime_fds[0] = gr_handle->prime_fd;
- bo->pitches[0] = gr_handle->stride;
- bo->offsets[0] = 0;
return 0;
}
@@ -209,19 +346,14 @@ bool DrmGenericImporter::CanImportBuffer(buffer_handle_t handle) {
if (bo.prime_fds[0] == 0)
return false;
- if (exclude_non_hwfb_ && !(bo.usage & GRALLOC_USAGE_HW_FB))
- return false;
-
return true;
}
-#ifdef USE_DRM_GENERIC_IMPORTER
std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
std::unique_ptr<Planner> planner(new Planner);
planner->AddStage<PlanStageGreedy>();
return planner;
}
-#endif
int DrmGenericImporter::ImportHandle(uint32_t gem_handle) {
gem_refcount_[gem_handle]++;
diff --git a/platform/platformdrmgeneric.h b/platform/platformdrmgeneric.h
index f9d923f..1bdaa09 100644
--- a/platform/platformdrmgeneric.h
+++ b/platform/platformdrmgeneric.h
@@ -17,13 +17,13 @@
#ifndef ANDROID_PLATFORM_DRM_GENERIC_H_
#define ANDROID_PLATFORM_DRM_GENERIC_H_
-#include "drmdevice.h"
-#include "platform.h"
-
+#include <drm/drm_fourcc.h>
#include <hardware/gralloc.h>
+
#include <map>
-#include <drm/drm_fourcc.h>
+#include "drm/DrmDevice.h"
+#include "platform.h"
#ifndef DRM_FORMAT_INVALID
#define DRM_FORMAT_INVALID 0
@@ -48,13 +48,13 @@ class DrmGenericImporter : public Importer {
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_;
- bool exclude_non_hwfb_;
int CloseHandle(uint32_t gem_handle);
std::map<uint32_t, int> gem_refcount_;
diff --git a/platform/platformhisi.cpp b/platform/platformhisi.cpp
index 1f1478f..67793db 100644
--- a/platform/platformhisi.cpp
+++ b/platform/platformhisi.cpp
@@ -17,15 +17,11 @@
#define LOG_TAG "hwc-platform-hisi"
#include "platformhisi.h"
-#include "drmdevice.h"
-#include "platform.h"
-#include <stdatomic.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <cinttypes>
-#include <hardware/gralloc.h>
#include <log/log.h>
#include "gralloc_priv.h"
@@ -156,42 +152,4 @@ int HisiImporter::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
return 0;
}
-class PlanStageHiSi : public Planner::PlanStage {
- public:
- int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
- std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
- std::vector<DrmPlane *> *planes) {
- int layers_added = 0;
- // Fill up as many DRM planes as we can with buffers that have HW_FB usage.
- // Buffers without HW_FB should have been filtered out with
- // CanImportBuffer(), if we meet one here, just skip it.
- for (auto i = layers.begin(); i != layers.end(); i = layers.erase(i)) {
- if (!(i->second->gralloc_buffer_usage & GRALLOC_USAGE_HW_FB))
- continue;
-
- int ret = Emplace(composition, planes, DrmCompositionPlane::Type::kLayer,
- crtc, std::make_pair(i->first, i->second));
- layers_added++;
- // We don't have any planes left
- if (ret == -ENOENT)
- break;
- else if (ret) {
- ALOGE("Failed to emplace layer %zu, dropping it", i->first);
- return ret;
- }
- }
- // If we didn't emplace anything, return an error to ensure we force client
- // compositing.
- if (!layers_added)
- return -EINVAL;
-
- return 0;
- }
-};
-
-std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
- std::unique_ptr<Planner> planner(new Planner);
- planner->AddStage<PlanStageHiSi>();
- return planner;
-}
} // namespace android
diff --git a/platform/platformhisi.h b/platform/platformhisi.h
index f127bdb..272e547 100644
--- a/platform/platformhisi.h
+++ b/platform/platformhisi.h
@@ -17,7 +17,6 @@
#ifndef ANDROID_PLATFORM_HISI_H_
#define ANDROID_PLATFORM_HISI_H_
-#include "drmdevice.h"
#include "platform.h"
#include "platformdrmgeneric.h"
diff --git a/platform/platformimagination.cpp b/platform/platformimagination.cpp
index bd4a4c3..7001d64 100644
--- a/platform/platformimagination.cpp
+++ b/platform/platformimagination.cpp
@@ -1,6 +1,7 @@
#define LOG_TAG "hwc-platform-imagination"
#include "platformimagination.h"
+
#include <log/log.h>
#include <xf86drm.h>
@@ -59,9 +60,4 @@ int ImaginationImporter::ConvertBoInfo(buffer_handle_t handle,
return 0;
}
-std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
- std::unique_ptr<Planner> planner(new Planner);
- planner->AddStage<PlanStageGreedy>();
- return planner;
-}
} // namespace android
diff --git a/platform/platformimagination.h b/platform/platformimagination.h
index f2a7cb7..4eec698 100644
--- a/platform/platformimagination.h
+++ b/platform/platformimagination.h
@@ -1,7 +1,6 @@
#ifndef PLATFORMIMAGINATION_H
#define PLATFORMIMAGINATION_H
-#include "drmdevice.h"
#include "platform.h"
#include "platformdrmgeneric.h"
diff --git a/platform/platformmediatek.cpp b/platform/platformmediatek.cpp
new file mode 100644
index 0000000..bbf76ea
--- /dev/null
+++ b/platform/platformmediatek.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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-mediatek"
+
+#include "platformmediatek.h"
+
+#include <hardware/gralloc.h>
+#include <log/log.h>
+#include <stdatomic.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#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;
+
+ 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) {
+ private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(
+ handle);
+ if (!hnd)
+ return -EINVAL;
+
+ uint32_t fmt = ConvertHalFormatToDrm(hnd->req_format);
+ if (fmt == DRM_FORMAT_INVALID)
+ return -EINVAL;
+
+ bo->width = hnd->width;
+ bo->height = hnd->height;
+ 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;
+
+ return 0;
+}
+
+} // namespace android
diff --git a/platform/platformmediatek.h b/platform/platformmediatek.h
new file mode 100644
index 0000000..61fcf47
--- /dev/null
+++ b/platform/platformmediatek.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 ANDROID_PLATFORM_MTK_H_
+#define ANDROID_PLATFORM_MTK_H_
+
+#include <hardware/gralloc.h>
+#include <stdatomic.h>
+
+#include "platform.h"
+#include "platformdrmgeneric.h"
+
+namespace android {
+
+class MediatekImporter : public DrmGenericImporter {
+ public:
+ using DrmGenericImporter::DrmGenericImporter;
+
+ int ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
+};
+} // namespace android
+
+#endif
diff --git a/platform/platformmeson.cpp b/platform/platformmeson.cpp
index ad3aff1..278eac5 100644
--- a/platform/platformmeson.cpp
+++ b/platform/platformmeson.cpp
@@ -17,15 +17,11 @@
#define LOG_TAG "hwc-platform-meson"
#include "platformmeson.h"
-#include "drmdevice.h"
-#include "platform.h"
-#include <stdatomic.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <cinttypes>
-#include <hardware/gralloc.h>
#include <log/log.h>
#include "gralloc_priv.h"
@@ -106,9 +102,4 @@ int MesonImporter::ConvertBoInfo(buffer_handle_t handle, hwc_drm_bo_t *bo) {
return 0;
}
-std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
- std::unique_ptr<Planner> planner(new Planner);
- planner->AddStage<PlanStageGreedy>();
- return planner;
-}
} // namespace android
diff --git a/platform/platformmeson.h b/platform/platformmeson.h
index f29b796..1b428a4 100644
--- a/platform/platformmeson.h
+++ b/platform/platformmeson.h
@@ -17,7 +17,6 @@
#ifndef ANDROID_PLATFORM_HISI_H_
#define ANDROID_PLATFORM_HISI_H_
-#include "drmdevice.h"
#include "platform.h"
#include "platformdrmgeneric.h"
diff --git a/platform/platformminigbm.cpp b/platform/platformminigbm.cpp
index df195d3..4360b0a 100644
--- a/platform/platformminigbm.cpp
+++ b/platform/platformminigbm.cpp
@@ -17,13 +17,10 @@
#define LOG_TAG "hwc-platform-drm-minigbm"
#include "platformminigbm.h"
-#include "drmdevice.h"
-#include "platform.h"
#include <xf86drm.h>
#include <xf86drmMode.h>
-#include <hardware/gralloc.h>
#include <log/log.h>
#include "cros_gralloc_handle.h"
@@ -63,10 +60,4 @@ int DrmMinigbmImporter::ConvertBoInfo(buffer_handle_t handle,
return 0;
}
-std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
- std::unique_ptr<Planner> planner(new Planner);
- planner->AddStage<PlanStageGreedy>();
- return planner;
-}
-
} // namespace android
diff --git a/platform/platformminigbm.h b/platform/platformminigbm.h
index 053b2aa..1eea6ca 100644
--- a/platform/platformminigbm.h
+++ b/platform/platformminigbm.h
@@ -17,7 +17,6 @@
#ifndef ANDROID_PLATFORM_DRM_MINIGBM_H_
#define ANDROID_PLATFORM_DRM_MINIGBM_H_
-#include "drmdevice.h"
#include "platform.h"
#include "platformdrmgeneric.h"
diff --git a/tests/Android.bp b/tests/Android.bp
index 7e550ff..282e71c 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -9,5 +9,8 @@ cc_test {
header_libs: ["libhardware_headers"],
static_libs: ["libdrmhwc_utils"],
shared_libs: ["hwcomposer.drm"],
- include_dirs: ["external/drm_hwcomposer/include"],
+ include_dirs: [
+ "external/drm_hwcomposer/include",
+ "external/drm_hwcomposer",
+ ],
}
diff --git a/tests/worker_test.cpp b/tests/worker_test.cpp
index 82523f0..cb6275e 100644
--- a/tests/worker_test.cpp
+++ b/tests/worker_test.cpp
@@ -1,10 +1,10 @@
+#include "utils/Worker.h"
+
#include <gtest/gtest.h>
#include <hardware/hardware.h>
#include <chrono>
-#include "worker.h"
-
using android::Worker;
struct TestWorker : public Worker {
diff --git a/utils/worker.cpp b/utils/Worker.cpp
index 0dceb16..1f30588 100644
--- a/utils/worker.cpp
+++ b/utils/Worker.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "worker.h"
+#include "Worker.h"
#include <sys/prctl.h>
#include <sys/resource.h>
diff --git a/include/worker.h b/utils/Worker.h
index 7909038..73a80da 100644
--- a/include/worker.h
+++ b/utils/Worker.h
@@ -19,10 +19,10 @@
#include <stdint.h>
#include <stdlib.h>
-#include <string>
#include <condition_variable>
#include <mutex>
+#include <string>
#include <thread>
namespace android {
diff --git a/include/autolock.h b/utils/autolock.h
index 006406a..006406a 100644
--- a/include/autolock.h
+++ b/utils/autolock.h
diff --git a/utils/hwcutils.cpp b/utils/hwcutils.cpp
index 87e3c42..2dc7e7b 100644
--- a/utils/hwcutils.cpp
+++ b/utils/hwcutils.cpp
@@ -17,12 +17,12 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#define LOG_TAG "hwc-drm-utils"
-#include "drmhwcomposer.h"
-#include "platform.h"
-
#include <log/log.h>
#include <ui/GraphicBufferMapper.h>
+#include "drmhwcomposer.h"
+#include "platform/platform.h"
+
#define UNUSED(x) (void)(x)
namespace android {
@@ -114,13 +114,9 @@ int DrmHwcLayer::ImportBuffer(Importer *importer) {
const hwc_drm_bo *bo = buffer.operator->();
- unsigned int layer_count;
- for (layer_count = 0; layer_count < HWC_DRM_BO_MAX_PLANES; ++layer_count)
- if (bo->gem_handles[layer_count] == 0)
- break;
-
- ret = handle.CopyBufferHandle(sf_handle, bo->width, bo->height, layer_count,
- bo->hal_format, bo->usage, bo->pixel_stride);
+ ret = handle.CopyBufferHandle(sf_handle, bo->width, bo->height,
+ 1 /*layer_count*/, bo->hal_format, bo->usage,
+ bo->pixel_stride);
if (ret)
return ret;