blob: de70199ed5778d349aacd7e7ed0081c49a3c9b40 [file] [log] [blame]
Sean Pauled2ec4b2016-03-10 15:35:40 -05001/*
2 * Copyright (C) 2016 The Android Open Source 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
Matvii Zorin0ddc3292020-07-27 18:29:15 +030017#ifndef ANDROID_DRM_HWC_TWO_H_
18#define ANDROID_DRM_HWC_TWO_H_
19
Sean Pauled2ec4b2016-03-10 15:35:40 -050020#include <hardware/hwcomposer2.h>
Roman Stratiienkoaa3cd542020-08-29 11:26:16 +030021
Roman Kovalivskyi12b91a32019-12-11 19:09:51 +020022#include <array>
Roman Stratiienkoe78235c2021-12-23 17:36:12 +020023#include <cmath>
Sean Pauled2ec4b2016-03-10 15:35:40 -050024#include <map>
Roman Stratiienkof81d2c82022-01-11 19:47:24 +020025#include <optional>
Sean Pauled2ec4b2016-03-10 15:35:40 -050026
Roman Stratiienko13cc3662020-08-29 21:35:39 +030027#include "compositor/DrmDisplayCompositor.h"
28#include "drm/ResourceManager.h"
29#include "drm/VSyncWorker.h"
Roman Stratiienkoaa3cd542020-08-29 11:26:16 +030030#include "drmhwcomposer.h"
Roman Stratiienko03fd35c2022-01-04 14:30:37 +020031#include "hwc2_device/HwcLayer.h"
Roman Stratiienkoaa3cd542020-08-29 11:26:16 +030032
Sean Pauled2ec4b2016-03-10 15:35:40 -050033namespace android {
34
Matvii Zorinef3c7972020-08-11 15:15:44 +030035class Backend;
36
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020037class DrmHwcTwo {
Sean Pauled2ec4b2016-03-10 15:35:40 -050038 public:
39 DrmHwcTwo();
40
Sean Paulac874152016-03-10 16:00:26 -050041 HWC2::Error Init();
42
Roman Stratiienko863a3c22021-09-29 13:00:29 +030043 std::pair<HWC2_PFN_HOTPLUG, hwc2_callback_data_t> hotplug_callback_{};
44 std::pair<HWC2_PFN_VSYNC, hwc2_callback_data_t> vsync_callback_{};
Roman Stratiienko11ef8c52021-09-29 13:01:39 +030045#if PLATFORM_SDK_VERSION > 29
46 std::pair<HWC2_PFN_VSYNC_2_4, hwc2_callback_data_t> vsync_2_4_callback_{};
47#endif
Roman Stratiienko863a3c22021-09-29 13:00:29 +030048 std::pair<HWC2_PFN_REFRESH, hwc2_callback_data_t> refresh_callback_{};
Roman Stratiienko23701092020-09-26 02:08:41 +030049
Roman Stratiienko863a3c22021-09-29 13:00:29 +030050 std::mutex callback_lock_;
Roman Stratiienko23701092020-09-26 02:08:41 +030051
Sean Pauled2ec4b2016-03-10 15:35:40 -050052 class HwcDisplay {
53 public:
Alexandru Gheorghe6f0030f2018-05-01 17:25:48 +010054 HwcDisplay(ResourceManager *resource_manager, DrmDevice *drm,
Roman Stratiienko863a3c22021-09-29 13:00:29 +030055 hwc2_display_t handle, HWC2::DisplayType type, DrmHwcTwo *hwc2);
Sean Paulac874152016-03-10 16:00:26 -050056 HwcDisplay(const HwcDisplay &) = delete;
57 HWC2::Error Init(std::vector<DrmPlane *> *planes);
58
Roman Stratiienko2a1f1ae2021-10-23 17:47:35 +030059 HWC2::Error CreateComposition(AtomicCommitArgs &a_args);
Roman Stratiienko03fd35c2022-01-04 14:30:37 +020060 std::vector<HwcLayer *> GetOrderLayersByZPos();
Roman Kovalivskyi8fae1562020-01-30 20:20:47 +020061
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +030062 void ClearDisplay();
Sean Paulac874152016-03-10 16:00:26 -050063
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +020064 std::string Dump();
65
Sean Pauled2ec4b2016-03-10 15:35:40 -050066 // HWC Hooks
67 HWC2::Error AcceptDisplayChanges();
68 HWC2::Error CreateLayer(hwc2_layer_t *layer);
69 HWC2::Error DestroyLayer(hwc2_layer_t layer);
Roman Stratiienkoa148f212021-11-16 18:23:18 +020070 HWC2::Error GetActiveConfig(hwc2_config_t *config) const;
Sean Pauled2ec4b2016-03-10 15:35:40 -050071 HWC2::Error GetChangedCompositionTypes(uint32_t *num_elements,
72 hwc2_layer_t *layers,
73 int32_t *types);
74 HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height,
75 int32_t format, int32_t dataspace);
76 HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes);
77 HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute,
78 int32_t *value);
79 HWC2::Error GetDisplayConfigs(uint32_t *num_configs,
80 hwc2_config_t *configs);
81 HWC2::Error GetDisplayName(uint32_t *size, char *name);
82 HWC2::Error GetDisplayRequests(int32_t *display_requests,
83 uint32_t *num_elements, hwc2_layer_t *layers,
84 int32_t *layer_requests);
85 HWC2::Error GetDisplayType(int32_t *type);
Andrii Chepurnyi50d37452020-04-24 14:20:24 +030086#if PLATFORM_SDK_VERSION > 27
87 HWC2::Error GetRenderIntents(int32_t mode, uint32_t *outNumIntents,
88 int32_t *outIntents);
Andrii Chepurnyi857a53f2020-04-29 23:15:28 +030089 HWC2::Error SetColorModeWithIntent(int32_t mode, int32_t intent);
Andrii Chepurnyi50d37452020-04-24 14:20:24 +030090#endif
John Stultz8c7229d2020-02-07 21:31:08 +000091#if PLATFORM_SDK_VERSION > 28
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +080092 HWC2::Error GetDisplayIdentificationData(uint8_t *outPort,
93 uint32_t *outDataSize,
94 uint8_t *outData);
95 HWC2::Error GetDisplayCapabilities(uint32_t *outNumCapabilities,
96 uint32_t *outCapabilities);
Andrii Chepurnyi2619aab2020-07-03 11:21:33 +030097 HWC2::Error GetDisplayBrightnessSupport(bool *supported);
98 HWC2::Error SetDisplayBrightness(float);
John Stultz8c7229d2020-02-07 21:31:08 +000099#endif
Roman Stratiienko6f5df172020-09-27 22:48:08 +0300100#if PLATFORM_SDK_VERSION > 29
101 HWC2::Error GetDisplayConnectionType(uint32_t *outType);
102 HWC2::Error GetDisplayVsyncPeriod(hwc2_vsync_period_t *outVsyncPeriod);
103
104 HWC2::Error SetActiveConfigWithConstraints(
105 hwc2_config_t config,
106 hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
107 hwc_vsync_period_change_timeline_t *outTimeline);
108 HWC2::Error SetAutoLowLatencyMode(bool on);
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200109 HWC2::Error GetSupportedContentTypes(
110 uint32_t *outNumSupportedContentTypes,
111 const uint32_t *outSupportedContentTypes);
Roman Stratiienko6f5df172020-09-27 22:48:08 +0300112
113 HWC2::Error SetContentType(int32_t contentType);
114#endif
115
Sean Pauled2ec4b2016-03-10 15:35:40 -0500116 HWC2::Error GetDozeSupport(int32_t *support);
Sean Paulac874152016-03-10 16:00:26 -0500117 HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types,
118 float *max_luminance,
119 float *max_average_luminance,
120 float *min_luminance);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500121 HWC2::Error GetReleaseFences(uint32_t *num_elements, hwc2_layer_t *layers,
122 int32_t *fences);
Matteo Franchinc56eede2019-12-03 17:10:38 +0000123 HWC2::Error PresentDisplay(int32_t *present_fence);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500124 HWC2::Error SetActiveConfig(hwc2_config_t config);
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +0300125 HWC2::Error ChosePreferredConfig();
Sean Pauled2ec4b2016-03-10 15:35:40 -0500126 HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
127 int32_t dataspace, hwc_region_t damage);
128 HWC2::Error SetColorMode(int32_t mode);
129 HWC2::Error SetColorTransform(const float *matrix, int32_t hint);
130 HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence);
131 HWC2::Error SetPowerMode(int32_t mode);
132 HWC2::Error SetVsyncEnabled(int32_t enabled);
133 HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests);
Vincent Donnefort9abec032019-10-09 15:43:43 +0100134 HwcLayer *get_layer(hwc2_layer_t layer) {
135 auto it = layers_.find(layer);
136 if (it == layers_.end())
137 return nullptr;
138 return &it->second;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500139 }
140
Matvii Zorin373de712020-08-11 14:05:12 +0300141 /* Statistics */
142 struct Stats {
Roman Stratiienkoe78235c2021-12-23 17:36:12 +0200143 Stats minus(Stats b) const {
Matvii Zorin373de712020-08-11 14:05:12 +0300144 return {total_frames_ - b.total_frames_,
145 total_pixops_ - b.total_pixops_,
146 gpu_pixops_ - b.gpu_pixops_,
147 failed_kms_validate_ - b.failed_kms_validate_,
148 failed_kms_present_ - b.failed_kms_present_,
149 frames_flattened_ - b.frames_flattened_};
150 }
151
152 uint32_t total_frames_ = 0;
153 uint64_t total_pixops_ = 0;
154 uint64_t gpu_pixops_ = 0;
155 uint32_t failed_kms_validate_ = 0;
156 uint32_t failed_kms_present_ = 0;
157 uint32_t frames_flattened_ = 0;
158 };
159
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200160 struct HwcDisplayConfig {
161 int id{};
162 int group_id{};
163 DrmMode mode;
164 bool disabled{};
165
Roman Stratiienkoe78235c2021-12-23 17:36:12 +0200166 bool IsInterlaced() const {
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200167 return (mode.flags() & DRM_MODE_FLAG_INTERLACE) != 0;
168 }
169 };
170
171 std::map<int /*config_id*/, struct HwcDisplayConfig> hwc_configs_;
172
173 int active_config_id_ = 0;
174 int preferred_config_id_ = 0;
175
Roman Stratiienko24a7fc42021-12-23 16:25:20 +0200176 const Backend *backend() const;
177 void set_backend(std::unique_ptr<Backend> backend);
Matvii Zorinef3c7972020-08-11 15:15:44 +0300178
Matvii Zorin373de712020-08-11 14:05:12 +0300179 const std::vector<DrmPlane *> &primary_planes() const {
180 return primary_planes_;
181 }
182
183 const std::vector<DrmPlane *> &overlay_planes() const {
184 return overlay_planes_;
185 }
186
187 std::map<hwc2_layer_t, HwcLayer> &layers() {
188 return layers_;
189 }
190
191 const DrmDisplayCompositor &compositor() const {
192 return compositor_;
193 }
194
195 const DrmDevice *drm() const {
196 return drm_;
197 }
198
199 const DrmConnector *connector() const {
200 return connector_;
201 }
202
Matvii Zorin373de712020-08-11 14:05:12 +0300203 ResourceManager *resource_manager() const {
204 return resource_manager_;
205 }
206
207 android_color_transform_t &color_transform_hint() {
208 return color_transform_hint_;
209 }
210
211 Stats &total_stats() {
212 return total_stats_;
213 }
214
Roman Stratiienkoe8c06792021-09-30 10:09:31 +0300215 /* returns true if composition should be sent to client */
216 bool ProcessClientFlatteningState(bool skip) {
217 int flattenning_state = flattenning_state_;
218 if (flattenning_state == ClientFlattenningState::Disabled) {
219 return false;
220 }
221
222 if (skip) {
223 flattenning_state_ = ClientFlattenningState::NotRequired;
224 return false;
225 }
226
227 if (flattenning_state == ClientFlattenningState::ClientRefreshRequested) {
228 flattenning_state_ = ClientFlattenningState::Flattened;
229 return true;
230 }
231
232 flattening_vsync_worker_.VSyncControl(true);
233 flattenning_state_ = ClientFlattenningState::VsyncCountdownMax;
234 return false;
235 }
236
Sean Pauled2ec4b2016-03-10 15:35:40 -0500237 private:
Roman Stratiienkoe8c06792021-09-30 10:09:31 +0300238 enum ClientFlattenningState : int32_t {
239 Disabled = -3,
240 NotRequired = -2,
241 Flattened = -1,
242 ClientRefreshRequested = 0,
243 VsyncCountdownMax = 60, /* 1 sec @ 60FPS */
244 };
245
246 std::atomic_int flattenning_state_{ClientFlattenningState::NotRequired};
247 VSyncWorker flattening_vsync_worker_;
248
Roman Kovalivskyi12b91a32019-12-11 19:09:51 +0200249 constexpr static size_t MATRIX_SIZE = 16;
250
Roman Stratiienko863a3c22021-09-29 13:00:29 +0300251 DrmHwcTwo *hwc2_;
252
Roman Stratiienkof81d2c82022-01-11 19:47:24 +0200253 std::optional<DrmMode> staged_mode;
254
Alexandru Gheorghe6f0030f2018-05-01 17:25:48 +0100255 ResourceManager *resource_manager_;
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +0100256 DrmDevice *drm_;
Sean Paulac874152016-03-10 16:00:26 -0500257 DrmDisplayCompositor compositor_;
Sean Paulac874152016-03-10 16:00:26 -0500258
259 std::vector<DrmPlane *> primary_planes_;
260 std::vector<DrmPlane *> overlay_planes_;
261
Matvii Zorinef3c7972020-08-11 15:15:44 +0300262 std::unique_ptr<Backend> backend_;
263
Sean Paulac874152016-03-10 16:00:26 -0500264 VSyncWorker vsync_worker_;
Roman Stratiienkoe78235c2021-12-23 17:36:12 +0200265 DrmConnector *connector_ = nullptr;
266 DrmCrtc *crtc_ = nullptr;
Sean Paulac874152016-03-10 16:00:26 -0500267 hwc2_display_t handle_;
268 HWC2::DisplayType type_;
269 uint32_t layer_idx_ = 0;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500270 std::map<hwc2_layer_t, HwcLayer> layers_;
Sean Paulac874152016-03-10 16:00:26 -0500271 HwcLayer client_layer_;
Roman Stratiienkob3b5c1e2021-02-15 13:44:19 +0200272 int32_t color_mode_{};
273 std::array<float, MATRIX_SIZE> color_transform_matrix_{};
Roman Kovalivskyi12b91a32019-12-11 19:09:51 +0200274 android_color_transform_t color_transform_hint_;
Sean Paulac874152016-03-10 16:00:26 -0500275
276 uint32_t frame_no_ = 0;
Matvii Zorin373de712020-08-11 14:05:12 +0300277 Stats total_stats_;
278 Stats prev_stats_;
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200279 std::string DumpDelta(DrmHwcTwo::HwcDisplay::Stats delta);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500280 };
281
Vincent Donnefort315444c2019-10-09 14:23:42 +0100282 static HwcDisplay *GetDisplay(DrmHwcTwo *hwc, hwc2_display_t display_handle) {
283 auto it = hwc->displays_.find(display_handle);
284 if (it == hwc->displays_.end())
285 return nullptr;
286
287 return &it->second;
288 }
289
Sean Pauled2ec4b2016-03-10 15:35:40 -0500290 // Device functions
291 HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height,
Sean Paulf72cccd2018-08-27 13:59:08 -0400292 int32_t *format, hwc2_display_t *display);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500293 HWC2::Error DestroyVirtualDisplay(hwc2_display_t display);
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200294 void Dump(uint32_t *outSize, char *outBuffer);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500295 uint32_t GetMaxVirtualDisplayCount();
296 HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
297 hwc2_function_pointer_t function);
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +0300298 HWC2::Error CreateDisplay(hwc2_display_t displ, HWC2::DisplayType type);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200299
300 private:
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +0300301 void HandleDisplayHotplug(hwc2_display_t displayid, int state);
302 void HandleInitialHotplugState(DrmDevice *drmDevice);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500303
Roman Stratiienko1e053b42021-10-25 22:54:20 +0300304 void HandleHotplugUEvent();
305
Alexandru Gheorghec5463582018-03-27 15:52:02 +0100306 ResourceManager resource_manager_;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500307 std::map<hwc2_display_t, HwcDisplay> displays_;
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200308
309 std::string mDumpString;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500310};
Sean Paulf72cccd2018-08-27 13:59:08 -0400311} // namespace android
Matvii Zorin0ddc3292020-07-27 18:29:15 +0300312
313#endif