blob: 6af25c1c53041ba59c621d94229ec4de184bfa40 [file] [log] [blame]
dianlujitao7468c412020-06-23 22:16:50 +08001/*
2 * Copyright (C) 2018-2020 The LineageOS Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifdef LIVES_IN_SYSTEM
18#define LOG_TAG "lineage.livedisplay@2.0-impl-sdm"
19#else
20#define LOG_TAG "vendor.lineage.livedisplay@2.0-impl-sdm"
21#endif
22
dianlujitao44e1a1f2020-06-24 22:51:34 +080023#include "livedisplay/sdm/SDMController.h"
dianlujitao7468c412020-06-23 22:16:50 +080024
25#include <android-base/logging.h>
26#include <dlfcn.h>
27
28#include <memory>
29
30#define LOAD_SDM_FUNCTION(name) \
31 fn_##name##_ = LoadFunction<disp_api_##name>(handle_.get(), "disp_api_" #name);
32
33#define CLOSE_SDM_FUNCTION(name) fn_##name##_ = nullptr;
34
35#define FOR_EACH_FUNCTION(MACRO) \
36 MACRO(init) \
37 MACRO(deinit) \
38 MACRO(get_num_display_modes) \
39 MACRO(get_display_modes) \
40 MACRO(get_active_display_mode) \
41 MACRO(set_active_display_mode) \
42 MACRO(set_default_display_mode) \
43 MACRO(get_default_display_mode) \
44 MACRO(get_global_pa_range) \
45 MACRO(get_global_pa_config) \
46 MACRO(set_global_pa_config) \
47 MACRO(get_feature_version)
48
49#define CONTROLLER_CHECK(function, ...) \
50 if (fn_##function##_ == nullptr) { \
51 return ::android::NO_INIT; \
52 } \
53 int err = fn_##function##_(__VA_ARGS__); \
54 if (err != 0) { \
55 return ::android::BAD_VALUE; \
56 } \
57 return android::OK;
58
59namespace {
60constexpr const char* kSdmDispLibs[]{
61#ifdef LIVES_IN_SYSTEM
62 "libsdm-disp-apis.qti.so",
63 "libsdm-disp-apis.so",
64#else
65 "libsdm-disp-vndapis.so",
66#endif
67};
68
69constexpr const int kDisplayId = 0;
70
71void* LoadDispApisLib() {
72 void* handle = nullptr;
73
74 for (auto&& lib : kSdmDispLibs) {
75 handle = dlopen(lib, RTLD_NOW);
76 if (handle != nullptr) {
77 LOG(DEBUG) << "Loaded: " << lib;
78 break;
79 }
80 LOG(INFO) << "Can not load " << lib << " (" << dlerror() << ")";
81 }
82
83 return handle;
84}
85
86template <typename Function>
87Function LoadFunction(void* handle, const char* name) {
88 void* fn = dlsym(handle, name);
89 if (fn == nullptr) {
90 LOG(ERROR) << "LoadFunction -- failed to load function " << name;
91 }
92 return reinterpret_cast<Function>(fn);
93}
94} // anonymous namespace
95
96namespace vendor {
97namespace lineage {
98namespace livedisplay {
99namespace V2_0 {
100namespace sdm {
101
102SDMController::SDMController()
103 : handle_(LoadDispApisLib(), [this](void* p) {
104 FOR_EACH_FUNCTION(CLOSE_SDM_FUNCTION)
105 if (p != nullptr) {
106 int err = dlclose(p);
107 p = nullptr;
108 if (err != 0) {
109 LOG(ERROR) << "Failed to close disp api lib.";
110 }
111 }
112 }) {
113 if (handle_ == nullptr) {
114 // Terminate the program on failure
115 LOG(FATAL) << "Failed to load SDM display lib, exiting. (" << dlerror() << ")";
116 }
117
118 FOR_EACH_FUNCTION(LOAD_SDM_FUNCTION)
119
120 // Initialize SDM backend
121 if (init() != android::OK) {
122 // Terminate the program on failure
123 LOG(FATAL) << "Failed to initialize SDM backend";
124 }
125}
126
127SDMController::~SDMController() {
128 deinit();
129}
130
131status_t SDMController::init() {
132 CONTROLLER_CHECK(init, &hctx_, 0);
133}
134
135status_t SDMController::deinit() {
136 CONTROLLER_CHECK(deinit, hctx_, 0);
137}
138
139status_t SDMController::getNumDisplayModes(int32_t* mode_cnt) {
140 uint32_t flags = 0;
141 CONTROLLER_CHECK(get_num_display_modes, hctx_, kDisplayId, 0, mode_cnt, &flags);
142}
143
dianlujitao143150e2020-06-24 17:41:07 +0800144status_t SDMController::getDisplayModes(SdmDispMode* modes, int32_t mode_cnt) {
dianlujitao7468c412020-06-23 22:16:50 +0800145 uint32_t flags = 0;
146 CONTROLLER_CHECK(get_display_modes, hctx_, kDisplayId, 0, modes, mode_cnt, &flags);
147}
148
149status_t SDMController::getActiveDisplayMode(int32_t* mode_id) {
150 uint32_t mask = 0, flags = 0;
151 CONTROLLER_CHECK(get_active_display_mode, hctx_, kDisplayId, mode_id, &mask, &flags);
152}
153
154status_t SDMController::setActiveDisplayMode(int32_t mode_id) {
155 CONTROLLER_CHECK(set_active_display_mode, hctx_, kDisplayId, mode_id, 0);
156}
157
158status_t SDMController::setDefaultDisplayMode(int32_t mode_id) {
159 CONTROLLER_CHECK(set_default_display_mode, hctx_, kDisplayId, mode_id, 0);
160}
161
162status_t SDMController::getDefaultDisplayMode(int32_t* mode_id) {
163 uint32_t flags = 0;
164 CONTROLLER_CHECK(get_default_display_mode, hctx_, kDisplayId, mode_id, &flags);
165}
166
dianlujitao143150e2020-06-24 17:41:07 +0800167status_t SDMController::getGlobalPaRange(HsicRanges* range) {
dianlujitao7468c412020-06-23 22:16:50 +0800168 CONTROLLER_CHECK(get_global_pa_range, hctx_, kDisplayId, range);
169}
170
dianlujitao143150e2020-06-24 17:41:07 +0800171status_t SDMController::getGlobalPaConfig(HsicConfig* cfg) {
dianlujitao7468c412020-06-23 22:16:50 +0800172 uint32_t enable = 0;
173 CONTROLLER_CHECK(get_global_pa_config, hctx_, kDisplayId, &enable, cfg);
174}
175
dianlujitao143150e2020-06-24 17:41:07 +0800176status_t SDMController::setGlobalPaConfig(HsicConfig* cfg) {
dianlujitao7468c412020-06-23 22:16:50 +0800177 CONTROLLER_CHECK(set_global_pa_config, hctx_, kDisplayId, 1 /* enable */, cfg);
178}
179
dianlujitao143150e2020-06-24 17:41:07 +0800180status_t SDMController::getFeatureVersion(uint32_t feature_id, SdmFeatureVersion* ver) {
dianlujitao7468c412020-06-23 22:16:50 +0800181 uint32_t flags = 0;
182 CONTROLLER_CHECK(get_feature_version, hctx_, feature_id, ver, &flags);
183}
184
185} // namespace sdm
186} // namespace V2_0
187} // namespace livedisplay
188} // namespace lineage
189} // namespace vendor